summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/cell/common.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c11
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_derived.c13
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c21
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.c112
-rw-r--r--src/gallium/drivers/cell/spu/Makefile1
-rw-r--r--src/gallium/drivers/cell/spu/spu_blend.c62
-rw-r--r--src/gallium/drivers/cell/spu/spu_blend.h37
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c50
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h17
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c59
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_setup.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_stipple.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c19
16 files changed, 235 insertions, 187 deletions
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index fe93fd8e1a..d59e4f7036 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -115,6 +115,16 @@ struct cell_command_depth_stencil_alpha_test {
/**
+ * Upload code to perform framebuffer blend operation
+ */
+struct cell_command_blend {
+ uint64_t base; /**< Effective address of code start. */
+ unsigned size; /**< Size in bytes of test code. */
+ unsigned read_fb; /**< Flag: should framebuffer be read? */
+};
+
+
+/**
* Tell SPUs about the framebuffer size, location
*/
struct cell_command_framebuffer
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index c880760e4b..86fcdcff1f 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -54,14 +54,19 @@ cell_create_blend_state(struct pipe_context *pipe,
static void
-cell_bind_blend_state(struct pipe_context *pipe, void *blend)
+cell_bind_blend_state(struct pipe_context *pipe, void *state)
{
struct cell_context *cell = cell_context(pipe);
+ struct cell_blend_state *blend = (struct cell_blend_state *) state;
+
draw_flush(cell->draw);
- cell->blend = (const struct cell_blend_state *)blend;
+ if ((blend != NULL) && (blend->code.store == NULL)) {
+ cell_generate_alpha_blend(blend, &cell->blend_color);
+ }
+ cell->blend = blend;
cell->dirty |= CELL_NEW_BLEND;
}
@@ -70,7 +75,7 @@ static void
cell_delete_blend_state(struct pipe_context *pipe, void *blend)
{
struct cell_blend_state *cb = (struct cell_blend_state *) blend;
-
+
spe_release_func(& cb->code);
FREE(cb);
}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c
index 5c240a55c0..5480534ad9 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_derived.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c
@@ -141,17 +141,8 @@ calculate_vertex_layout( struct cell_context *cell )
static void
compute_cliprect(struct cell_context *sp)
{
- unsigned surfWidth, surfHeight;
-
- if (sp->framebuffer.num_cbufs > 0) {
- surfWidth = sp->framebuffer.cbufs[0]->width;
- surfHeight = sp->framebuffer.cbufs[0]->height;
- }
- else {
- /* no surface? */
- surfWidth = sp->scissor.maxx;
- surfHeight = sp->scissor.maxy;
- }
+ uint surfWidth = sp->framebuffer.width;
+ uint surfHeight = sp->framebuffer.height;
if (sp->rasterizer->scissor) {
/* clip to scissor rect */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 4d589bcdbf..5709b48f12 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -60,14 +60,25 @@ cell_emit_state(struct cell_context *cell)
fb->color_format = cbuf->format;
fb->depth_start = cell->zsbuf_map;
fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE;
- fb->width = cell->framebuffer.cbufs[0]->width;
- fb->height = cell->framebuffer.cbufs[0]->height;
+ fb->width = cell->framebuffer.width;
+ fb->height = cell->framebuffer.height;
}
if (cell->dirty & CELL_NEW_BLEND) {
- emit_state_cmd(cell, CELL_CMD_STATE_BLEND,
- cell->blend,
- sizeof(struct pipe_blend_state));
+ struct cell_command_blend blend;
+
+ if (cell->blend != NULL) {
+ blend.base = (intptr_t) cell->blend->code.store;
+ blend.size = (char *) cell->blend->code.csr
+ - (char *) cell->blend->code.store;
+ blend.read_fb = TRUE;
+ } else {
+ blend.base = 0;
+ blend.size = 0;
+ blend.read_fb = FALSE;
+ }
+
+ emit_state_cmd(cell, CELL_CMD_STATE_BLEND, &blend, sizeof(blend));
}
if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
index 9c47968459..988c251e20 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
@@ -669,7 +669,7 @@ emit_alpha_factor_calculation(struct spe_function *f,
/**
- * \note Emits a maximum of 5 instructions
+ * \note Emits a maximum of 6 instructions
*/
static void
emit_color_factor_calculation(struct spe_function *f,
@@ -864,7 +864,11 @@ emit_blend_calculation(struct spe_function *f,
spe_il(f, src, 0);
} else if (dF == PIPE_BLENDFACTOR_ONE) {
spe_or(f, src, dst, dst);
+ } else {
+ spe_fm(f, src, dst, dst_factor);
}
+ } else if (dF == PIPE_BLENDFACTOR_ZERO) {
+ spe_fm(f, src, src, src_factor);
} else {
spe_fm(f, tmp, dst, dst_factor);
spe_fma(f, src, src, src_factor, tmp);
@@ -884,7 +888,11 @@ emit_blend_calculation(struct spe_function *f,
} else if (dF == PIPE_BLENDFACTOR_ONE) {
spe_il(f, tmp, 0);
spe_fs(f, src, tmp, dst);
+ } else {
+ spe_fm(f, src, dst, dst_factor);
}
+ } else if (dF == PIPE_BLENDFACTOR_ZERO) {
+ spe_fm(f, src, src, src_factor);
} else {
spe_fm(f, tmp, dst, dst_factor);
spe_fms(f, src, src, src_factor, tmp);
@@ -904,7 +912,11 @@ emit_blend_calculation(struct spe_function *f,
spe_il(f, src, 0);
} else if (dF == PIPE_BLENDFACTOR_ONE) {
spe_or(f, src, dst, dst);
+ } else {
+ spe_fm(f, src, dst, dst_factor);
}
+ } else if (dF == PIPE_BLENDFACTOR_ZERO) {
+ spe_fm(f, src, src, src_factor);
} else {
spe_fm(f, tmp, src, src_factor);
spe_fms(f, src, src, dst_factor, tmp);
@@ -913,12 +925,12 @@ emit_blend_calculation(struct spe_function *f,
case PIPE_BLEND_MIN:
spe_cgt(f, tmp, src, dst);
- spe_selb(f, src, dst, src, tmp);
+ spe_selb(f, src, src, dst, tmp);
break;
case PIPE_BLEND_MAX:
spe_cgt(f, tmp, src, dst);
- spe_selb(f, src, src, dst, tmp);
+ spe_selb(f, src, dst, src, tmp);
break;
default:
@@ -940,9 +952,9 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
struct spe_function *const f = &cb->code;
/* This code generates a maximum of 3 (source alpha factor)
- * + 3 (destination alpha factor) + (3 * 5) (source color factor)
- * + (3 * 5) (destination color factor) + (4 * 2) (blend equation)
- * + 4 (fragment mask) + 1 (return) = 49 instlructions. Round up to 64 to
+ * + 3 (destination alpha factor) + (3 * 6) (source color factor)
+ * + (3 * 6) (destination color factor) + (4 * 2) (blend equation)
+ * + 4 (fragment mask) + 1 (return) = 55 instlructions. Round up to 64 to
* make it a happy power-of-two.
*/
spe_init_func(f, 4 * 64);
@@ -984,16 +996,57 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
&& (b->alpha_func != PIPE_BLEND_MAX);
- sF[0] = b->rgb_src_factor;
- sF[1] = sF[0];
- sF[2] = sF[0];
- sF[3] = (b->alpha_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
- ? PIPE_BLENDFACTOR_ONE : b->alpha_src_factor;
+ if (b->blend_enable) {
+ sF[0] = b->rgb_src_factor;
+ sF[1] = sF[0];
+ sF[2] = sF[0];
+ switch (b->alpha_src_factor & 0x0f) {
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ sF[3] = PIPE_BLENDFACTOR_ONE;
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ sF[3] = b->alpha_src_factor + 1;
+ break;
+ default:
+ sF[3] = b->alpha_src_factor;
+ }
- dF[0] = b->rgb_dst_factor;
- dF[1] = dF[0];
- dF[2] = dF[0];
- dF[3] = b->rgb_dst_factor;
+ dF[0] = b->rgb_dst_factor;
+ dF[1] = dF[0];
+ dF[2] = dF[0];
+ switch (b->alpha_dst_factor & 0x0f) {
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ dF[3] = b->alpha_dst_factor + 1;
+ break;
+ default:
+ dF[3] = b->alpha_dst_factor;
+ }
+
+ func[0] = b->rgb_func;
+ func[1] = func[0];
+ func[2] = func[0];
+ func[3] = b->alpha_func;
+ } else {
+ sF[0] = PIPE_BLENDFACTOR_ONE;
+ sF[1] = PIPE_BLENDFACTOR_ONE;
+ sF[2] = PIPE_BLENDFACTOR_ONE;
+ sF[3] = PIPE_BLENDFACTOR_ONE;
+ dF[0] = PIPE_BLENDFACTOR_ZERO;
+ dF[1] = PIPE_BLENDFACTOR_ZERO;
+ dF[2] = PIPE_BLENDFACTOR_ZERO;
+ dF[3] = PIPE_BLENDFACTOR_ZERO;
+
+ func[0] = PIPE_BLEND_ADD;
+ func[1] = PIPE_BLEND_ADD;
+ func[2] = PIPE_BLEND_ADD;
+ func[3] = PIPE_BLEND_ADD;
+ }
/* If alpha writing is enabled and the alpha blend mode requires use of
@@ -1054,11 +1107,6 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
- func[0] = b->rgb_func;
- func[1] = func[0];
- func[2] = func[0];
- func[3] = b->alpha_func;
-
for (i = 0; i < 4; ++i) {
if ((b->colormask & (1U << i)) != 0) {
emit_blend_calculation(f,
@@ -1072,4 +1120,28 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
}
spe_bi(f, 0, 0, 0);
+
+#if 0
+ {
+ const uint32_t *p = f->store;
+
+ printf("# %u instructions\n", f->csr - f->store);
+ printf("# blend (%sabled)\n",
+ (cb->base.blend_enable) ? "en" : "dis");
+ printf("# RGB func / sf / df: %u %u %u\n",
+ cb->base.rgb_func,
+ cb->base.rgb_src_factor,
+ cb->base.rgb_dst_factor);
+ printf("# ALP func / sf / df: %u %u %u\n",
+ cb->base.alpha_func,
+ cb->base.alpha_src_factor,
+ cb->base.alpha_dst_factor);
+
+ printf("\t.text\n");
+ for (/* empty */; p < f->csr; p++) {
+ printf("\t.long\t0x%04x\n", *p);
+ }
+ fflush(stdout);
+ }
+#endif
}
diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile
index 115ca8cd90..8e83610790 100644
--- a/src/gallium/drivers/cell/spu/Makefile
+++ b/src/gallium/drivers/cell/spu/Makefile
@@ -17,7 +17,6 @@ PROG_SPU_EMBED_O = $(PROG)_spu-embed.o
SOURCES = \
spu_main.c \
- spu_blend.c \
spu_dcache.c \
spu_per_fragment_op.c \
spu_render.c \
diff --git a/src/gallium/drivers/cell/spu/spu_blend.c b/src/gallium/drivers/cell/spu/spu_blend.c
deleted file mode 100644
index 23ec0eeb45..0000000000
--- a/src/gallium/drivers/cell/spu/spu_blend.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#include "spu_main.h"
-#include "spu_blend.h"
-#include "spu_colorpack.h"
-
-
-void
-blend_quad(uint itx, uint ity, vector float colors[4])
-{
- /* simple SRC_ALPHA, ONE_MINUS_SRC_ALPHA blending */
- vector float fbc00 = spu_unpack_color(spu.ctile.ui[ity][itx]);
- vector float fbc01 = spu_unpack_color(spu.ctile.ui[ity][itx+1]);
- vector float fbc10 = spu_unpack_color(spu.ctile.ui[ity+1][itx]);
- vector float fbc11 = spu_unpack_color(spu.ctile.ui[ity+1][itx+1]);
-
- vector float alpha00 = spu_splats(spu_extract(colors[0], 3));
- vector float alpha01 = spu_splats(spu_extract(colors[1], 3));
- vector float alpha10 = spu_splats(spu_extract(colors[2], 3));
- vector float alpha11 = spu_splats(spu_extract(colors[3], 3));
-
- vector float one_minus_alpha00 = spu_sub(spu_splats(1.0f), alpha00);
- vector float one_minus_alpha01 = spu_sub(spu_splats(1.0f), alpha01);
- vector float one_minus_alpha10 = spu_sub(spu_splats(1.0f), alpha10);
- vector float one_minus_alpha11 = spu_sub(spu_splats(1.0f), alpha11);
-
- colors[0] = spu_add(spu_mul(colors[0], alpha00),
- spu_mul(fbc00, one_minus_alpha00));
- colors[1] = spu_add(spu_mul(colors[1], alpha01),
- spu_mul(fbc01, one_minus_alpha01));
- colors[2] = spu_add(spu_mul(colors[2], alpha10),
- spu_mul(fbc10, one_minus_alpha10));
- colors[3] = spu_add(spu_mul(colors[3], alpha11),
- spu_mul(fbc11, one_minus_alpha11));
-}
-
diff --git a/src/gallium/drivers/cell/spu/spu_blend.h b/src/gallium/drivers/cell/spu/spu_blend.h
deleted file mode 100644
index 2b594b578b..0000000000
--- a/src/gallium/drivers/cell/spu/spu_blend.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef SPU_BLEND_H
-#define SPU_BLEND_H
-
-
-extern void
-blend_quad(uint itx, uint ity, vector float colors[4]);
-
-
-#endif /* SPU_BLEND_H */
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index 937962285d..41bebf5362 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -61,6 +61,25 @@ static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX]
static unsigned char depth_stencil_code_buffer[4 * 64]
ALIGN16_ATTRIB;
+static unsigned char fb_blend_code_buffer[4 * 64]
+ ALIGN16_ATTRIB;
+
+static struct spu_blend_results
+default_blend(qword frag_r, qword frag_g, qword frag_b, qword frag_a,
+ qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
+ qword frag_mask)
+{
+ struct spu_blend_results result;
+
+ result.r = si_selb(pixel_r, frag_r, frag_mask);
+ result.g = si_selb(pixel_g, frag_g, frag_mask);
+ result.b = si_selb(pixel_b, frag_b, frag_mask);
+ result.a = si_selb(pixel_a, frag_a, frag_mask);
+
+ return result;
+}
+
+
/**
* Tell the PPU that this SPU has finished copying a buffer to
* local store and that it may be reused by the PPU.
@@ -246,14 +265,31 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
static void
-cmd_state_blend(const struct pipe_blend_state *state)
+cmd_state_blend(const struct cell_command_blend *state)
{
if (Debug)
printf("SPU %u: BLEND: enabled %d\n",
spu.init.id,
- state->blend_enable);
+ (state->size != 0));
+
+ ASSERT_ALIGN16(state->base);
- memcpy(&spu.blend, state, sizeof(*state));
+ if (state->size != 0) {
+ mfc_get(fb_blend_code_buffer,
+ (unsigned int) state->base, /* src */
+ ROUNDUP16(state->size),
+ TAG_BATCH_BUFFER,
+ 0, /* tid */
+ 0 /* rid */);
+ wait_on_mask(1 << TAG_BATCH_BUFFER);
+ spu.blend = (blend_func) fb_blend_code_buffer;
+ spu.read_fb = state->read_fb;
+ } else {
+ /* If there is no code, use the default;
+ */
+ spu.blend = default_blend;
+ spu.read_fb = FALSE;
+ }
}
@@ -441,9 +477,8 @@ cmd_batch(uint opcode)
pos += 1;
break;
case CELL_CMD_STATE_BLEND:
- cmd_state_blend((struct pipe_blend_state *)
- &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct pipe_blend_state)) / 8);
+ cmd_state_blend((struct cell_command_blend *) &buffer[pos+1]);
+ pos += (1 + ROUNDUP8(sizeof(struct cell_command_blend)) / 8);
break;
case CELL_CMD_STATE_DEPTH_STENCIL:
cmd_state_depth_stencil((struct cell_command_depth_stencil_alpha_test *)
@@ -587,6 +622,9 @@ one_time_init(void)
memset(spu.ctile_status, TILE_STATUS_DEFINED, sizeof(spu.ctile_status));
memset(spu.ztile_status, TILE_STATUS_DEFINED, sizeof(spu.ztile_status));
invalidate_tex_cache();
+
+ spu.blend = default_blend;
+ spu.read_fb = FALSE;
}
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index 444e218645..56d0968676 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -67,6 +67,18 @@ typedef struct spu_frag_test_results (*frag_test_func)(qword frag_mask,
qword frag_alpha, qword facing);
+struct spu_blend_results {
+ qword r;
+ qword g;
+ qword b;
+ qword a;
+};
+
+typedef struct spu_blend_results (*blend_func)(
+ qword frag_r, qword frag_g, qword frag_b, qword frag_a,
+ qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
+ qword frag_mask);
+
struct spu_framebuffer {
void *color_start; /**< addr of color surface in main memory */
void *depth_start; /**< addr of depth surface in main memory */
@@ -93,7 +105,10 @@ struct spu_global
boolean read_depth;
boolean read_stencil;
frag_test_func frag_test;
- struct pipe_blend_state blend;
+
+ boolean read_fb;
+ blend_func blend;
+
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct cell_command_texture texture;
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index 81823f2463..c4272d6e93 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -29,10 +29,10 @@
* Triangle rendering within a tile.
*/
+#include <transpose_matrix4x4.h>
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "pipe/p_util.h"
-#include "spu_blend.h"
#include "spu_colorpack.h"
#include "spu_main.h"
#include "spu_texture.h"
@@ -261,6 +261,9 @@ do_depth_test(int x, int y, mask_t quadmask)
float4 zvals;
mask_t mask;
+ if (spu.fb.depth_format == PIPE_FORMAT_NONE)
+ return quadmask;
+
zvals.v = eval_z((float) x, (float) y);
mask = (mask_t) spu_do_depth_stencil(x - setup.cliprect_minx,
@@ -326,27 +329,45 @@ emit_quad( int x, int y, mask_t mask )
eval_coeff(1, (float) x, (float) y, colors);
}
-#if 1
- if (spu.blend.blend_enable)
- blend_quad(ix % TILE_SIZE, iy % TILE_SIZE, colors);
-#endif
- if (spu_extract(mask, 0))
- spu.ctile.ui[iy][ix] = spu_pack_color_shuffle(colors[0], shuffle);
- if (spu_extract(mask, 1))
- spu.ctile.ui[iy][ix+1] = spu_pack_color_shuffle(colors[1], shuffle);
- if (spu_extract(mask, 2))
- spu.ctile.ui[iy+1][ix] = spu_pack_color_shuffle(colors[2], shuffle);
- if (spu_extract(mask, 3))
- spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(colors[3], shuffle);
+ /* Read the current framebuffer values.
+ *
+ * Ignore read_fb for now. In the future we can use this to avoid
+ * reading the framebuffer if read_fb is false and the fragment mask is
+ * all 0xffffffff. This is the common case, so it is probably worth
+ * the effort. We'll have to profile to determine whether or not the
+ * extra conditional branches hurt overall performance.
+ */
+ vec_float4 aos_pix[4] = {
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]),
+ };
-#if 0
- /* SIMD_Z with swizzled color buffer (someday) */
- vector unsigned int uicolors = *((vector unsigned int *) &colors);
- spu.ctile.ui4[iy/2][ix/2] = spu_sel(spu.ctile.ui4[iy/2][ix/2], uicolors, mask);
-#endif
- }
+ qword soa_pix[4];
+ qword soa_frag[4];
+ /* Convert pixel and fragment data from AoS to SoA format.
+ */
+ _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix);
+ _transpose_matrix4x4((vec_float4 *) soa_frag, colors);
+
+ const struct spu_blend_results result =
+ (*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3],
+ soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3],
+ (qword) mask);
+
+
+ /* Convert final pixel data from SoA to AoS format.
+ */
+ _transpose_matrix4x4(aos_pix, (const vec_float4 *) &result);
+
+ spu.ctile.ui[iy+0][ix+0] = spu_pack_color_shuffle(aos_pix[0], shuffle);
+ spu.ctile.ui[iy+0][ix+1] = spu_pack_color_shuffle(aos_pix[1], shuffle);
+ spu.ctile.ui[iy+1][ix+0] = spu_pack_color_shuffle(aos_pix[2], shuffle);
+ spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(aos_pix[3], shuffle);
+ }
#endif
}
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 31d7062dcc..19e6cfaf02 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -84,8 +84,6 @@ struct softpipe_context {
unsigned num_samplers;
unsigned num_textures;
- uint fb_width, fb_height;
-
/* Counter for occlusion queries. Note this supports overlapping
* queries.
*/
diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c
index f2d6043e2e..6a81e4d8cc 100644
--- a/src/gallium/drivers/softpipe/sp_prim_setup.c
+++ b/src/gallium/drivers/softpipe/sp_prim_setup.c
@@ -485,7 +485,7 @@ setup_fragcoord_coeff(struct setup_stage *setup, uint slot)
/*Y*/
if (setup->softpipe->rasterizer->origin_lower_left) {
/* y=0=bottom */
- const int winHeight = setup->softpipe->fb_height;
+ const int winHeight = setup->softpipe->framebuffer.height;
setup->coef[slot].a0[1] = (float) (winHeight - 1);
setup->coef[slot].dady[1] = -1.0;
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c
index 9a39249576..f1e9b80e09 100644
--- a/src/gallium/drivers/softpipe/sp_quad_stipple.c
+++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c
@@ -25,7 +25,7 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
int y0, y1;
uint stipple0, stipple1;
if (softpipe->rasterizer->origin_lower_left) {
- y0 = softpipe->fb_height - 1 - quad->y0;
+ y0 = softpipe->framebuffer.height - 1 - quad->y0;
y1 = y0 - 1;
}
else {
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 53b2056b8a..14abb20eeb 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -171,8 +171,8 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
static void
compute_cliprect(struct softpipe_context *sp)
{
- uint surfWidth = sp->fb_width;
- uint surfHeight = sp->fb_height;
+ uint surfWidth = sp->framebuffer.width;
+ uint surfHeight = sp->framebuffer.height;
if (sp->rasterizer->scissor) {
/* clip to scissor rect */
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index 2f55684464..ba8c9eece7 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -48,9 +48,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
struct softpipe_context *sp = softpipe_context(pipe);
uint i;
- /* updated below */
- sp->fb_width = sp->fb_height = 0;
-
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
/* check if changing cbuf */
if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
@@ -63,10 +60,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
/* update cache */
sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]);
}
- if (fb->cbufs[i]) {
- sp->fb_width = fb->cbufs[i]->width;
- sp->fb_height = fb->cbufs[i]->height;
- }
}
sp->framebuffer.num_cbufs = fb->num_cbufs;
@@ -81,11 +74,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
/* update cache */
sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf);
-
- if (!sp->fb_width && fb->zsbuf) {
- sp->fb_width = fb->zsbuf->width;
- sp->fb_height = fb->zsbuf->height;
- }
}
#if 0
@@ -113,9 +101,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
}
#endif
+ sp->framebuffer.width = fb->width;
+ sp->framebuffer.height = fb->height;
+
sp->dirty |= SP_NEW_FRAMEBUFFER;
}
-
-
-
-