/** * 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); } }
/** * 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); } }
/** * 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 {
/** * Upload SAMPLER_BORDER_COLOR_STATE. */ void upload_default_color(struct brw_context *brw, struct gl_sampler_object *sampler, int unit, uint32_t *sdc_offset) { struct gl_context *ctx = &brw->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]; switch (firstImage->_BaseFormat) { case 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]; break; case GL_ALPHA: color[0] = 0.0; color[1] = 0.0; color[2] = 0.0; color[3] = sampler->BorderColor.f[3]; break; case GL_INTENSITY: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = sampler->BorderColor.f[0]; break; case GL_LUMINANCE: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = 1.0; break; case GL_LUMINANCE_ALPHA: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = sampler->BorderColor.f[3]; break; default: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[1]; color[2] = sampler->BorderColor.f[2]; color[3] = sampler->BorderColor.f[3]; break; } /* 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 (brw->gen >= 8) { /* On Broadwell, the border color is represented as four 32-bit floats, * integers, or unsigned values, interpreted according to the surface * format. This matches the sampler->BorderColor union exactly. Since * we use floats both here and in the above reswizzling code, we preserve * the original bit pattern. So we actually handle all three formats. */ float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR, 4 * 4, 64, sdc_offset); COPY_4FV(sdc, color); } else if (brw->gen == 5 || brw->gen == 6) { struct gen5_sampler_default_color *sdc; sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR, sizeof(*sdc), 32, sdc_offset); 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 {