summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/intel/intel_blit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_blit.c')
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index e1ab7f1..5aac1f6 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -146,6 +146,17 @@ intelEmitCopyBlit(struct intel_context *intel,
src_pitch *= cpp;
dst_pitch *= cpp;
+ /* For big formats (such as floating point), do the copy using 32bpp and
+ * multiply the coordinates.
+ */
+ if (cpp > 4) {
+ assert(cpp % 4 == 0);
+ dst_x *= cpp / 4;
+ dst_x2 *= cpp / 4;
+ src_x *= cpp / 4;
+ cpp = 4;
+ }
+
BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
switch (cpp) {
@@ -211,7 +222,7 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
{
struct intel_context *intel = intel_context(ctx);
struct gl_framebuffer *fb = ctx->DrawBuffer;
- GLuint clear_depth;
+ GLuint clear_depth_value, clear_depth_mask;
GLboolean all;
GLint cx, cy, cw, ch;
GLbitfield fail_mask = 0;
@@ -220,12 +231,15 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
/*
* Compute values for clearing the buffers.
*/
- clear_depth = 0;
+ clear_depth_value = 0;
+ clear_depth_mask = 0;
if (mask & BUFFER_BIT_DEPTH) {
- clear_depth = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
+ clear_depth_value = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
+ clear_depth_mask = XY_BLT_WRITE_RGB;
}
if (mask & BUFFER_BIT_STENCIL) {
- clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
+ clear_depth_value |= (ctx->Stencil.Clear & 0xff) << 24;
+ clear_depth_mask |= XY_BLT_WRITE_ALPHA;
}
cx = fb->_Xmin;
@@ -239,12 +253,13 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
if (cw == 0 || ch == 0)
return 0;
- GLuint buf;
all = (cw == fb->Width && ch == fb->Height);
/* Loop over all renderbuffers */
- for (buf = 0; buf < BUFFER_COUNT && mask; buf++) {
- const GLbitfield bufBit = 1 << buf;
+ mask &= (1 << BUFFER_COUNT) - 1;
+ while (mask) {
+ GLuint buf = _mesa_ffs(mask) - 1;
+ GLboolean is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
struct intel_renderbuffer *irb;
drm_intel_bo *write_buffer;
int x1, y1, x2, y2;
@@ -253,11 +268,15 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
int pitch, cpp;
drm_intel_bo *aper_array[2];
- if (!(mask & bufBit))
- continue;
+ mask &= ~(1 << buf);
- /* OK, clear this renderbuffer */
irb = intel_get_renderbuffer(fb, buf);
+ if (irb == NULL || irb->region == NULL || irb->region->buffer == NULL) {
+ fail_mask |= 1 << buf;
+ continue;
+ }
+
+ /* OK, clear this renderbuffer */
write_buffer = intel_region_buffer(intel, irb->region,
all ? INTEL_WRITE_FULL :
INTEL_WRITE_PART);
@@ -274,16 +293,13 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
irb->region->buffer, (pitch * cpp),
x1, y1, x2 - x1, y2 - y1);
- BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
+ BR13 = 0xf0 << 16;
CMD = XY_COLOR_BLT_CMD;
/* Setup the blit command */
if (cpp == 4) {
- if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) {
- if (mask & BUFFER_BIT_DEPTH)
- CMD |= XY_BLT_WRITE_RGB;
- if (mask & BUFFER_BIT_STENCIL)
- CMD |= XY_BLT_WRITE_ALPHA;
+ if (is_depth_stencil) {
+ CMD |= clear_depth_mask;
} else {
/* clearing RGBA */
CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
@@ -300,8 +316,8 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
#endif
BR13 |= (pitch * cpp);
- if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) {
- clear_val = clear_depth;
+ if (is_depth_stencil) {
+ clear_val = clear_depth_value;
} else {
uint8_t clear[4];
GLclampf *color = ctx->Color.ClearColor;
@@ -333,12 +349,13 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
clear[3], clear[3]);
break;
default:
- fail_mask |= bufBit;
- mask &= ~bufBit;
+ fail_mask |= 1 << buf;
continue;
}
}
+ BR13 |= br13_for_cpp(cpp);
+
assert(x1 < x2);
assert(y1 < y2);
@@ -367,8 +384,6 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
- else
- mask &= ~bufBit; /* turn off bit, for faster loop exit */
}
return fail_mask;