/** * Clear the color buffer when glColorMask is in effect. */ static void clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb) { const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; SWspan span; GLint i; ASSERT(ctx->Visual.rgbMode); ASSERT(rb->PutRow); /* Initialize color span with clear color */ /* XXX optimize for clearcolor == black/zero (bzero) */ INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_RGBA); span.array->ChanType = rb->DataType; if (span.array->ChanType == GL_UNSIGNED_BYTE) { GLubyte clearColor[4]; UNCLAMPED_FLOAT_TO_UBYTE(clearColor[RCOMP], ctx->Color.ClearColor[0]); UNCLAMPED_FLOAT_TO_UBYTE(clearColor[GCOMP], ctx->Color.ClearColor[1]); UNCLAMPED_FLOAT_TO_UBYTE(clearColor[BCOMP], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_UBYTE(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < width; i++) { COPY_4UBV(span.array->rgba[i], clearColor); } } else if (span.array->ChanType == GL_UNSIGNED_SHORT) { GLushort clearColor[4]; UNCLAMPED_FLOAT_TO_USHORT(clearColor[RCOMP], ctx->Color.ClearColor[0]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[GCOMP], ctx->Color.ClearColor[1]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < width; i++) { COPY_4V(span.array->rgba[i], clearColor); } } else { ASSERT(span.array->ChanType == GL_FLOAT); for (i = 0; i < width; i++) { CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][0], ctx->Color.ClearColor[0]); CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][1], ctx->Color.ClearColor[1]); CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][2], ctx->Color.ClearColor[2]); CLAMPED_FLOAT_TO_CHAN(span.array->rgba[i][3], ctx->Color.ClearColor[3]); } } /* Note that masking will change the color values, but only the * channels for which the write mask is GL_FALSE. The channels * which which are write-enabled won't get modified. */ for (i = 0; i < height; i++) { span.x = x; span.y = y + i; _swrast_mask_rgba_span(ctx, rb, &span); /* write masked row */ rb->PutRow(ctx, rb, width, x, y + i, span.array->rgba, NULL); } }
static void radeon_Color4fv_ub( const GLfloat *v ) { radeon_color_t *dest = vb.colorptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); }
static void radeon_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) { radeon_color_t *dest = vb.specptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); dest->alpha = 255; }
static void radeon_SecondaryColor3fvEXT_ub( const GLfloat *v ) { radeon_color_t *dest = vb.specptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); dest->alpha = 255; }
static void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { (void) a; UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); v[0] = 0; }
static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) { radeon_color_t *dest = vb.colorptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); }
static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { DEBUG_INSERT; (void) a; UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); }
static void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { (void) a; UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); v[1] = 0x00; v[0] = 0xff; }
static void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { (void) a; UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); }
static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); r200_color_t *dest = rmesa->vb.specptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); dest->alpha = 255; }
static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeon_color_t *dest = rmesa->vb.colorptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); dest->alpha = 255; }
static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); r200_color_t *dest = rmesa->vb.colorptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); }
static void radeon_Color3fv_ub( const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeon_color_t *dest = rmesa->vb.colorptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); dest->alpha = 255; }
static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); r200_color_t *dest = rmesa->vb.specptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); dest->alpha = 255; }
static void r200_Color4fv_ub( const GLfloat *v ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); r200_color_t *dest = rmesa->vb.colorptr; UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); }
static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) { DEBUG_INSERT; (void) a; UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); v[3] = 0x00; v[0] = 0xff; }
static void gammaDDClearColor( GLcontext *ctx, const GLfloat color[4]) { gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); GLubyte c[4]; UNCLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); UNCLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); UNCLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); UNCLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); gmesa->ClearColor = gammaPackColor( gmesa->gammaScreen->cpp, c[0], c[1], c[2], c[3] ); if (gmesa->gammaScreen->cpp == 2) gmesa->ClearColor |= gmesa->ClearColor<<16; }
/** * Clear an rgba color buffer without channel masking. */ static void clear_rgba_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { const GLint x = ctx->DrawBuffer->_Xmin; const GLint y = ctx->DrawBuffer->_Ymin; const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; GLubyte clear8[4]; GLushort clear16[4]; GLvoid *clearVal; GLint i; ASSERT(ctx->Visual.rgbMode); ASSERT(ctx->Color.ColorMask[0] && ctx->Color.ColorMask[1] && ctx->Color.ColorMask[2] && ctx->Color.ColorMask[3]); ASSERT(rb->PutMonoRow); switch (rb->DataType) { case GL_UNSIGNED_BYTE: UNCLAMPED_FLOAT_TO_UBYTE(clear8[0], ctx->Color.ClearColor[0]); UNCLAMPED_FLOAT_TO_UBYTE(clear8[1], ctx->Color.ClearColor[1]); UNCLAMPED_FLOAT_TO_UBYTE(clear8[2], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_UBYTE(clear8[3], ctx->Color.ClearColor[3]); clearVal = clear8; break; case GL_UNSIGNED_SHORT: UNCLAMPED_FLOAT_TO_USHORT(clear16[0], ctx->Color.ClearColor[0]); UNCLAMPED_FLOAT_TO_USHORT(clear16[1], ctx->Color.ClearColor[1]); UNCLAMPED_FLOAT_TO_USHORT(clear16[2], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_USHORT(clear16[3], ctx->Color.ClearColor[3]); clearVal = clear16; break; case GL_FLOAT: clearVal = ctx->Color.ClearColor; break; default: _mesa_problem(ctx, "Bad rb DataType in clear_color_buffer"); return; } for (i = 0; i < height; i++) { rb->PutMonoRow(ctx, rb, width, x, y + i, clearVal, NULL); } }
static void gen6_prepare_color_calc_state(struct brw_context *brw) { struct gl_context *ctx = &brw->intel.ctx; struct gen6_color_calc_state *cc; cc = brw_state_batch(brw, AUB_TRACE_CC_STATE, sizeof(*cc), 64, &brw->cc.state_offset); memset(cc, 0, sizeof(*cc)); /* _NEW_COLOR */ cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef); /* _NEW_STENCIL */ cc->cc0.stencil_ref = ctx->Stencil.Ref[0]; cc->cc0.bf_stencil_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; /* _NEW_COLOR */ cc->constant_r = ctx->Color.BlendColorUnclamped[0]; cc->constant_g = ctx->Color.BlendColorUnclamped[1]; cc->constant_b = ctx->Color.BlendColorUnclamped[2]; cc->constant_a = ctx->Color.BlendColorUnclamped[3]; brw->state.dirty.cache |= CACHE_NEW_COLOR_CALC_STATE; }
void xmesa_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p) { struct xmesa_surface *xms = xmesa_surface(ps); struct xmesa_renderbuffer *xrb = xms->xrb; if (xrb) { /* this is a front/back color buffer */ GLubyte tmp[MAX_WIDTH * 4]; GLuint i, j; uint w0 = w; GET_CURRENT_CONTEXT(ctx); CLIP_TILE; FLIP(y); for (i = 0; i < h; i++) { for (j = 0; j < w * 4; j++) { UNCLAMPED_FLOAT_TO_UBYTE(tmp[j], p[j]); } xrb->St.Base.PutRow(ctx, &xrb->St.Base, w, x, y - i, tmp, NULL); p += w0 * 4; } #if 0 /* debug: flush */ { XMesaContext xm = XMESA_CONTEXT(ctx); XSync(xm->display, 0); } #endif } else { /* other softpipe surface */ softpipe_put_tile_rgba(ps, x, y, w, h, p); } }
static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) { i830ContextPtr i830 = I830_CONTEXT(ctx); GLubyte r, g, b, a; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b; }
static void i915BlendColor(GLcontext * ctx, const GLfloat color[4]) { struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; DBG("%s\n", __FUNCTION__); UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = (a << 24) | (r << 16) | (g << 8) | b; }
static void i830BlendColor(struct gl_context * ctx, const GLfloat color[4]) { struct i830_context *i830 = i830_context(ctx); GLubyte r, g, b, a; DBG("%s\n", __FUNCTION__); UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = (a << 24) | (r << 16) | (g << 8) | b; }
static void i915BlendColor(struct gl_context * ctx, const GLfloat color[4]) { struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; GLuint dw; DBG("%s\n", __FUNCTION__); UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); dw = (a << 24) | (r << 16) | (g << 8) | b; if (dw != i915->state.Blend[I915_BLENDREG_BLENDCOLOR1]) { i915->state.Blend[I915_BLENDREG_BLENDCOLOR1] = dw; I915_STATECHANGE(i915, I915_UPLOAD_BLEND); } }
static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count, const GLfloat *factor ) { GLubyte r, g, b, a; GLuint col; if (0) fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", blendUnit, factor[0], factor[1], factor[2], factor[3]); UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); col = ((a << 24) | (r << 16) | (g << 8) | b); state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); state[count++] = col; return count; }
static void i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK); i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | (((GLuint) refByte) << S6_ALPHA_REF_SHIFT)); }
static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { i830ContextPtr i830 = I830_CONTEXT(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; GLuint refInt; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); refInt = (GLuint)refByte; I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | ENABLE_ALPHA_REF_VALUE | ALPHA_TEST_FUNC(test) | ALPHA_REF_VALUE(refInt)); }
static void gen6_upload_color_calc_state(struct brw_context *brw) { struct gl_context *ctx = &brw->ctx; struct gen6_color_calc_state *cc; cc = brw_state_batch(brw, AUB_TRACE_CC_STATE, sizeof(*cc), 64, &brw->cc.state_offset); memset(cc, 0, sizeof(*cc)); /* _NEW_COLOR */ cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef); if (brw->gen < 9) { /* _NEW_STENCIL */ cc->cc0.stencil_ref = _mesa_get_stencil_ref(ctx, 0); cc->cc0.bf_stencil_ref = _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace); } /* _NEW_COLOR */ cc->constant_r = ctx->Color.BlendColorUnclamped[0]; cc->constant_g = ctx->Color.BlendColorUnclamped[1]; cc->constant_b = ctx->Color.BlendColorUnclamped[2]; cc->constant_a = ctx->Color.BlendColorUnclamped[3]; /* Point the GPU at the new indirect state. */ if (brw->gen == 6) { BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2)); OUT_BATCH(0); OUT_BATCH(0); OUT_BATCH(brw->cc.state_offset | 1); ADVANCE_BATCH(); } else { BEGIN_BATCH(2); OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2)); OUT_BATCH(brw->cc.state_offset | 1); ADVANCE_BATCH(); } }
/** * Upload SAMPLER_BORDER_COLOR_STATE. */ void upload_default_color(struct brw_context *brw, struct gl_sampler_object *sampler, int unit, int ss_index) { struct intel_context *intel = &brw->intel; struct gl_context *ctx = &intel->ctx; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *texObj = texUnit->_Current; struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel]; float color[4]; if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) { /* GL specs that border color for depth textures is taken from the * R channel, while the hardware uses A. Spam R into all the * channels for safety. */ color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = sampler->BorderColor.f[0]; } else { color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[1]; color[2] = sampler->BorderColor.f[2]; color[3] = sampler->BorderColor.f[3]; } /* In some cases we use an RGBA surface format for GL RGB textures, * where we've initialized the A channel to 1.0. We also have to set * the border color alpha to 1.0 in that case. */ if (firstImage->_BaseFormat == GL_RGB) color[3] = 1.0; if (intel->gen == 5 || intel->gen == 6) { struct gen5_sampler_default_color *sdc; sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR, sizeof(*sdc), 32, &brw->wm.sdc_offset[ss_index]); memset(sdc, 0, sizeof(*sdc)); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color[0]); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color[1]); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color[2]); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color[3]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color[0]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color[1]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color[2]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color[3]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color[0]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color[1]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color[2]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color[3]); sdc->hf[0] = _mesa_float_to_half(color[0]); sdc->hf[1] = _mesa_float_to_half(color[1]); sdc->hf[2] = _mesa_float_to_half(color[2]); sdc->hf[3] = _mesa_float_to_half(color[3]); sdc->b[0] = sdc->s[0] >> 8; sdc->b[1] = sdc->s[1] >> 8; sdc->b[2] = sdc->s[2] >> 8; sdc->b[3] = sdc->s[3] >> 8; sdc->f[0] = color[0]; sdc->f[1] = color[1]; sdc->f[2] = color[2]; sdc->f[3] = color[3]; } else {
/* * Render a bitmap. */ static bool do_blit_bitmap( struct gl_context *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 gl_framebuffer *fb = ctx->DrawBuffer; struct intel_renderbuffer *irb; GLfloat tmpColor[4]; GLubyte ubcolor[4]; GLuint color; GLsizei bitmap_width = width; GLsizei bitmap_height = height; GLint px, py; GLuint stipple[32]; GLint orig_dstx = dstx; GLint orig_dsty = dsty; /* Update draw buffer bounds */ _mesa_update_state(ctx); if (ctx->Depth.Test) { /* The blit path produces incorrect results when depth testing is on. * It seems the blit Z coord is always 1.0 (the far plane) so fragments * will likely be obscured by other, closer geometry. */ return false; } intel_prepare_render(intel); if (fb->_NumColorDrawBuffers != 1) { perf_debug("accelerated glBitmap() only supports rendering to a " "single color buffer\n"); return false; } irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]); if (_mesa_is_bufferobj(unpack->BufferObj)) { bitmap = map_pbo(ctx, width, height, unpack, bitmap); if (bitmap == NULL) return true; /* even though this is an error, we're done */ } COPY_4V(tmpColor, ctx->Current.RasterColor); if (_mesa_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]); switch (irb->mt->format) { case MESA_FORMAT_B8G8R8A8_UNORM: case MESA_FORMAT_B8G8R8X8_UNORM: color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]); break; case MESA_FORMAT_B5G6R5_UNORM: color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]); break; default: perf_debug("Unsupported format %s in accelerated glBitmap()\n", _mesa_get_format_name(irb->mt->format)); return false; } if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F)) return false; /* Clip to buffer bounds and scissor. */ if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, &dstx, &dsty, &width, &height)) goto out; dsty = y_flip(fb, dsty, height); #define DY 32 #define DX 32 /* Chop it all into chunks that can be digested by hardware: */ for (py = 0; py < height; py += DY) { for (px = 0; px < width; px += DX) { int h = MIN2(DY, height - py); int w = MIN2(DX, width - 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: * * Have to translate destination coordinates back into source * coordinates. */ int count = get_bitmap_rect(bitmap_width, bitmap_height, unpack, bitmap, -orig_dstx + (dstx + px), -orig_dsty + y_flip(fb, dsty + py, h), w, h, (GLubyte *)stipple, 8, _mesa_is_winsys_fbo(fb)); if (count == 0) continue; if (!intelEmitImmediateColorExpandBlit(intel, irb->mt->cpp, (GLubyte *)stipple, sz, color, irb->mt->region->pitch, irb->mt->region->bo, 0, irb->mt->region->tiling, dstx + px, dsty + py, w, h, logic_op)) { return false; } if (ctx->Query.CurrentOcclusionObject) ctx->Query.CurrentOcclusionObject->Result += count; } } out: if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) intel_batchbuffer_flush(intel); if (_mesa_is_bufferobj(unpack->BufferObj)) { /* done with PBO so unmap it now */ ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); } intel_check_front_buffer_rendering(intel); return true; }