summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorStephane Marchesin <marchesin@icps.u-strasbg.fr>2008-04-02 05:10:52 +0200
committerStephane Marchesin <marchesin@icps.u-strasbg.fr>2008-04-02 05:10:52 +0200
commit901700888e5b4ec4dbec6ac924b542c780edaf52 (patch)
tree7050fa76b0b30b68a1170ed590d59011fd6d2d3c /src/gallium/drivers
parentb1a361ba7a565063200c033e4939e6b28c006b13 (diff)
parentae87909d0d261d0f4e888f6a167e6329eb129a87 (diff)
Merge branch 'gallium-0.1' of git+ssh://marcheu@git.freedesktop.org/git/nouveau/mesa into gallium-0.1
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/cell/common.h21
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c20
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c41
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.c39
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.h5
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c54
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h18
-rw-r--r--src/gallium/drivers/cell/spu/spu_texture.c29
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.c19
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_debug_fp.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_context.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_context.h6
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h6
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c35
-rw-r--r--src/gallium/drivers/nv40/nv40_state.h1
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c20
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c2
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c101
22 files changed, 309 insertions, 129 deletions
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index b0928fefd2..f430e88b9c 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -36,6 +36,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_util.h"
#include "pipe/p_format.h"
+#include "pipe/p_state.h"
/** The standard assert macro doesn't seem to work reliably */
@@ -66,6 +67,8 @@
#define CELL_MAX_SPUS 6
+#define CELL_MAX_SAMPLERS 4
+
#define TILE_SIZE 32
@@ -109,7 +112,7 @@
*/
struct cell_command_depth_stencil_alpha_test {
uint64_t base; /**< Effective address of code start. */
- unsigned size; /**< Size in bytes of test code. */
+ unsigned size; /**< Size in bytes of SPE code. */
unsigned read_depth; /**< Flag: should depth be read? */
unsigned read_stencil; /**< Flag: should stencil be read? */
};
@@ -120,14 +123,14 @@ struct cell_command_depth_stencil_alpha_test {
*/
struct cell_command_blend {
uint64_t base; /**< Effective address of code start. */
- unsigned size; /**< Size in bytes of test code. */
+ unsigned size; /**< Size in bytes of SPE code. */
unsigned read_fb; /**< Flag: should framebuffer be read? */
};
struct cell_command_logicop {
uint64_t base; /**< Effective address of code start. */
- unsigned size; /**< Size in bytes of test code. */
+ unsigned size; /**< Size in bytes of SPE code. */
};
@@ -226,10 +229,20 @@ struct cell_command_release_verts
};
+struct cell_command_sampler
+{
+ uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */
+ uint unit;
+ struct pipe_sampler_state state;
+};
+
+
struct cell_command_texture
{
+ uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */
+ uint unit;
void *start; /**< Address in main memory */
- uint width, height;
+ ushort width, height;
};
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 00f4be7401..52c3126050 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -273,6 +273,7 @@ cell_set_sampler_textures(struct pipe_context *pipe,
pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex);
}
+ cell->num_textures = num;
cell_update_texture_mapping(cell);
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 124670df25..84b48bf4f1 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -55,11 +55,11 @@ cell_get_param(struct pipe_screen *screen, int param)
{
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
+ return PIPE_MAX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
- return 1;
+ return 0;
case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
+ return 0;
case PIPE_CAP_GLSL:
return 1;
case PIPE_CAP_S3TC:
@@ -67,13 +67,13 @@ cell_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
- return 1;
+ return 0;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 1;
case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
+ return 0;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
+ return 0;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 12; /* max 2Kx2K */
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -118,8 +118,12 @@ cell_is_format_supported( struct pipe_screen *screen,
{
switch (type) {
case PIPE_TEXTURE:
- /* cell supports all texture formats, XXX for now anyway */
- return TRUE;
+ /* cell supports most texture formats, XXX for now anyway */
+ if (format == PIPE_FORMAT_DXT5_RGBA ||
+ format == PIPE_FORMAT_R8G8B8A8_SRGB)
+ return FALSE;
+ else
+ return TRUE;
case PIPE_SURFACE:
/* cell supports all (off-screen) surface formats, XXX for now */
return TRUE;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 4c75caa025..9cae67f091 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -121,27 +121,36 @@ cell_emit_state(struct cell_context *cell)
}
if (cell->dirty & CELL_NEW_SAMPLER) {
- if (cell->sampler[0]) {
- emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER,
- cell->sampler[0], sizeof(struct pipe_sampler_state));
+ uint i;
+ for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
+ if (cell->sampler[i]) {
+ struct cell_command_sampler *sampler
+ = cell_batch_alloc(cell, sizeof(*sampler));
+ sampler->opcode = CELL_CMD_STATE_SAMPLER;
+ sampler->unit = i;
+ sampler->state = *cell->sampler[i];
+ }
}
}
if (cell->dirty & CELL_NEW_TEXTURE) {
- struct cell_command_texture texture;
- if (cell->texture[0]) {
- texture.start = cell->texture[0]->tiled_data;
- texture.width = cell->texture[0]->base.width[0];
- texture.height = cell->texture[0]->base.height[0];
+ uint i;
+ for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
+ struct cell_command_texture *texture
+ = cell_batch_alloc(cell, sizeof(*texture));
+ texture->opcode = CELL_CMD_STATE_TEXTURE;
+ texture->unit = i;
+ if (cell->texture[i]) {
+ texture->start = cell->texture[i]->tiled_data;
+ texture->width = cell->texture[i]->base.width[0];
+ texture->height = cell->texture[i]->base.height[0];
+ }
+ else {
+ texture->start = NULL;
+ texture->width = 1;
+ texture->height = 1;
+ }
}
- else {
- texture.start = NULL;
- texture.width = 0;
- texture.height = 0;
- }
-
- emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE,
- &texture, sizeof(struct cell_command_texture));
}
if (cell->dirty & CELL_NEW_VERTEX_INFO) {
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 f10025bd7c..53ae3aa50e 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
@@ -1164,10 +1164,11 @@ int PC_OFFSET(const struct spe_function *f, const void *d)
* masking.
*
* \bug
- * This routine is hard-coded to only work with ARGB8 data.
+ * Only two framebuffer formats are supported at this time.
*/
void
-cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
+cell_generate_logic_op(struct spe_function *f,
+ const struct pipe_blend_state *blend,
struct pipe_surface *surf)
{
const unsigned logic_op = (blend->logicop_enable)
@@ -1235,15 +1236,31 @@ cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
/* Convert fragment colors to framebuffer format in AoS layout.
*/
- data[0] = 0x00010203;
- data[1] = 0x10111213;
- data[2] = 0x04050607;
- data[3] = 0x14151617;
-
- data[4] = 0x0c000408;
- data[5] = 0x80808080;
- data[6] = 0x80808080;
- data[7] = 0x80808080;
+ switch (surf->format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ data[0] = 0x00010203;
+ data[1] = 0x10111213;
+ data[2] = 0x04050607;
+ data[3] = 0x14151617;
+ data[4] = 0x0c000408;
+ data[5] = 0x80808080;
+ data[6] = 0x80808080;
+ data[7] = 0x80808080;
+ break;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ data[0] = 0x03020100;
+ data[1] = 0x13121110;
+ data[2] = 0x07060504;
+ data[3] = 0x17161514;
+ data[4] = 0x0804000c;
+ data[5] = 0x80808080;
+ data[6] = 0x80808080;
+ data[7] = 0x80808080;
+ break;
+ default:
+ fprintf(stderr, "CELL: Bad pixel format in cell_generate_logic_op()");
+ ASSERT(0);
+ }
spe_ilh(f, tmp[0], 0x0808);
spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0));
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
index ab4de96c69..a8267a5133 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
@@ -32,7 +32,8 @@ extern void
cell_generate_alpha_blend(struct cell_blend_state *cb);
extern void
-cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend,
- struct pipe_surface *surf);
+cell_generate_logic_op(struct spe_function *f,
+ const struct pipe_blend_state *blend,
+ struct pipe_surface *surf);
#endif /* CELL_STATE_PER_FRAGMENT_H */
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index d7f46f8024..7f0473d198 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -312,13 +312,13 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat
static void
-cmd_state_sampler(const struct pipe_sampler_state *state)
+cmd_state_sampler(const struct cell_command_sampler *sampler)
{
if (Debug)
- printf("SPU %u: SAMPLER\n",
- spu.init.id);
+ printf("SPU %u: SAMPLER [%u]\n",
+ spu.init.id, sampler->unit);
- memcpy(&spu.sampler[0], state, sizeof(*state));
+ spu.sampler[sampler->unit] = sampler->state;
if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR)
spu.sample_texture = sample_texture_bilinear;
else
@@ -329,17 +329,25 @@ cmd_state_sampler(const struct pipe_sampler_state *state)
static void
cmd_state_texture(const struct cell_command_texture *texture)
{
- if (Debug)
- printf("SPU %u: TEXTURE at %p size %u x %u\n",
- spu.init.id, texture->start, texture->width, texture->height);
-
- memcpy(&spu.texture, texture, sizeof(*texture));
- spu.tex_size = (vector float)
- { spu.texture.width, spu.texture.height, 0.0, 0.0};
- spu.tex_size_mask = (vector unsigned int)
- { spu.texture.width - 1, spu.texture.height - 1, 0, 0 };
- spu.tex_size_x_mask = spu_splats(spu.texture.width - 1);
- spu.tex_size_y_mask = spu_splats(spu.texture.height - 1);
+ const uint unit = texture->unit;
+ const uint width = texture->width;
+ const uint height = texture->height;
+
+ if (Debug) {
+ printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id,
+ texture->unit, texture->start,
+ texture->width, texture->height);
+ }
+
+ spu.texture[unit].start = texture->start;
+ spu.texture[unit].width = width;
+ spu.texture[unit].height = height;
+
+ spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0};
+ spu.texture[unit].tex_size_mask = (vector unsigned int)
+ { width - 1, height - 1, 0, 0 };
+ spu.texture[unit].tex_size_x_mask = spu_splats(width - 1);
+ spu.texture[unit].tex_size_y_mask = spu_splats(height - 1);
}
@@ -471,12 +479,20 @@ cmd_batch(uint opcode)
pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8);
break;
case CELL_CMD_STATE_SAMPLER:
- cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8);
+ {
+ struct cell_command_sampler *sampler
+ = (struct cell_command_sampler *) &buffer[pos];
+ cmd_state_sampler(sampler);
+ pos += sizeof(*sampler) / 8;
+ }
break;
case CELL_CMD_STATE_TEXTURE:
- cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8);
+ {
+ struct cell_command_texture *texture
+ = (struct cell_command_texture *) &buffer[pos];
+ cmd_state_texture(texture);
+ pos += sizeof(*texture) / 8;
+ }
break;
case CELL_CMD_STATE_VERTEX_INFO:
cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index c20452931a..2bfad3535a 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -100,6 +100,17 @@ struct spu_framebuffer {
} ALIGN16_ATTRIB;
+struct spu_texture
+{
+ void *start;
+ uint width, height;
+ vector float tex_size;
+ vector unsigned int tex_size_mask; /**< == int(size - 1) */
+ vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
+ vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
+} ALIGN16_ATTRIB;
+
+
/**
* All SPU global/context state will be in singleton object of this type:
*/
@@ -119,7 +130,7 @@ struct spu_global
logicop_func logicop;
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
- struct cell_command_texture texture;
+ struct spu_texture texture[PIPE_MAX_SAMPLERS];
struct vertex_info vertex_info;
@@ -141,11 +152,6 @@ struct spu_global
/** for converting RGBA to PIPE_FORMAT_x colors */
vector unsigned char color_shuffle;
- vector float tex_size;
- vector unsigned int tex_size_mask; /**< == int(size - 1) */
- vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
- vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
-
vector float (*sample_texture)(vector float texcoord);
} ALIGN16_ATTRIB;
diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c
index 67eb08196a..4612501eb3 100644
--- a/src/gallium/drivers/cell/spu/spu_texture.c
+++ b/src/gallium/drivers/cell/spu/spu_texture.c
@@ -40,25 +40,29 @@
void
invalidate_tex_cache(void)
{
- spu_dcache_mark_dirty((unsigned) spu.texture.start,
- 4 * spu.texture.width * spu.texture.height);
+ uint unit = 0;
+ uint bytes = 4 * spu.texture[unit].width
+ * spu.texture[unit].height;
+
+ spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes);
}
static uint
get_texel(vec_uint4 coordinate)
{
+ const uint unit = 0;
vec_uint4 tmp;
unsigned x = spu_extract(coordinate, 0);
unsigned y = spu_extract(coordinate, 1);
- const unsigned tiles_per_row = spu.texture.width / TILE_SIZE;
+ const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE;
unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row)
+ (x / TILE_SIZE));
unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE)
+ (x % TILE_SIZE));
spu_dcache_fetch_unaligned((qword *) & tmp,
- spu.texture.start + tile_offset + texel_offset,
+ spu.texture[unit].start + tile_offset + texel_offset,
4);
return spu_extract(tmp, 0);
}
@@ -67,13 +71,14 @@ get_texel(vec_uint4 coordinate)
static void
get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
{
- const unsigned texture_ea = (uintptr_t) spu.texture.start;
+ const uint unit = 0;
+ const unsigned texture_ea = (uintptr_t) spu.texture[unit].start;
vec_uint4 tile_x = spu_rlmask(x, -5);
vec_uint4 tile_y = spu_rlmask(y, -5);
const qword offset_x = si_andi((qword) x, 0x1f);
const qword offset_y = si_andi((qword) y, 0x1f);
- const qword tiles_per_row = (qword) spu_splats(spu.texture.width / TILE_SIZE);
+ const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE);
const qword tile_size = (qword) spu_splats(sizeof(tile_t));
qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x);
@@ -101,9 +106,10 @@ get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
vector float
sample_texture_nearest(vector float texcoord)
{
- vector float tc = spu_mul(texcoord, spu.tex_size);
+ const uint unit = 0;
+ vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */
- itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */
+ itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */
uint texel = get_texel(itc);
return spu_unpack_A8R8G8B8(texel);
}
@@ -112,10 +118,11 @@ sample_texture_nearest(vector float texcoord)
vector float
sample_texture_bilinear(vector float texcoord)
{
+ const uint unit = 0;
static const vec_uint4 offset_x = {0, 0, 1, 1};
static const vec_uint4 offset_y = {0, 1, 0, 1};
- vector float tc = spu_mul(texcoord, spu.tex_size);
+ vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size);
tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */
/* integer texcoords S,T: */
@@ -129,8 +136,8 @@ sample_texture_bilinear(vector float texcoord)
x = spu_add(x, offset_x);
y = spu_add(y, offset_y);
- x = spu_and(x, spu.tex_size_x_mask);
- y = spu_and(y, spu.tex_size_y_mask);
+ x = spu_and(x, spu.texture[unit].tex_size_x_mask);
+ y = spu_and(y, spu.texture[unit].tex_size_y_mask);
get_four_texels(x, y, texels);
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index 95c629a8aa..17e337bbdf 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask )
spu.cur_ctile_status = TILE_STATUS_DIRTY;
- if (spu.texture.start) {
+ if (spu.texture[0].start) {
/* texture mapping */
vector float texcoords[4];
eval_coeff(2, (float) x, (float) y, texcoords);
diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c
index 78102dbac2..9b9111167f 100644
--- a/src/gallium/drivers/i915simple/i915_debug.c
+++ b/src/gallium/drivers/i915simple/i915_debug.c
@@ -30,6 +30,7 @@
#include "i915_winsys.h"
#include "i915_debug.h"
#include "pipe/p_winsys.h"
+#include "pipe/p_debug.h"
static void
@@ -39,11 +40,9 @@ PRINTF(
... )
{
va_list args;
- char buffer[256];
va_start( args, fmt );
- vsprintf( buffer, fmt, args );
- stream->winsys->printf( stream->winsys, buffer );
+ debug_vprintf( fmt, args );
va_end( args );
}
@@ -200,14 +199,12 @@ BITS(
... )
{
va_list args;
- char buffer[256];
unsigned himask = ~0UL >> (31 - (hi));
PRINTF(stream, "\t\t ");
va_start( args, fmt );
- vsprintf( buffer, fmt, args );
- stream->winsys->printf( stream->winsys, buffer );
+ debug_vprintf( fmt, args );
va_end( args );
PRINTF(stream, ": 0x%x\n", ((dw) & himask) >> (lo));
@@ -231,13 +228,11 @@ FLAG(
{
if (((dw) >> (bit)) & 1) {
va_list args;
- char buffer[256];
PRINTF(stream, "\t\t ");
va_start( args, fmt );
- vsprintf( buffer, fmt, args );
- stream->winsys->printf( stream->winsys, buffer );
+ debug_vprintf( fmt, args );
va_end( args );
PRINTF(stream, "\n");
@@ -877,11 +872,11 @@ i915_dump_batchbuffer( struct i915_context *i915 )
stream.winsys = i915->pipe.winsys;
if (!start || !end) {
- stream.winsys->printf( stream.winsys, "\n\nBATCH: ???\n");
+ debug_printf( "\n\nBATCH: ???\n");
return;
}
- stream.winsys->printf( stream.winsys, "\n\nBATCH: (%d)\n", bytes / 4);
+ debug_printf( "\n\nBATCH: (%d)\n", bytes / 4);
while (!done &&
stream.offset < bytes)
@@ -893,7 +888,7 @@ i915_dump_batchbuffer( struct i915_context *i915 )
stream.offset >= 0);
}
- stream.winsys->printf( stream.winsys, "END-BATCH\n\n\n");
+ debug_printf( "END-BATCH\n\n\n");
}
diff --git a/src/gallium/drivers/i915simple/i915_debug.h b/src/gallium/drivers/i915simple/i915_debug.h
index 0bcd094233..afb63edabf 100644
--- a/src/gallium/drivers/i915simple/i915_debug.h
+++ b/src/gallium/drivers/i915simple/i915_debug.h
@@ -83,11 +83,9 @@ I915_DBG(
{
if ((i915)->debug & FILE_DEBUG_FLAG) {
va_list args;
- char buffer[256];
va_start( args, fmt );
- vsprintf( buffer, fmt, args );
- i915->pipe.winsys->printf( i915->pipe.winsys, buffer );
+ debug_vprintf( fmt, args );
va_end( args );
}
}
diff --git a/src/gallium/drivers/i915simple/i915_debug_fp.c b/src/gallium/drivers/i915simple/i915_debug_fp.c
index ebfdb3d93c..37a3508fe1 100644
--- a/src/gallium/drivers/i915simple/i915_debug_fp.c
+++ b/src/gallium/drivers/i915simple/i915_debug_fp.c
@@ -39,11 +39,9 @@ PRINTF(
... )
{
va_list args;
- char buffer[256];
va_start( args, fmt );
- vsprintf( buffer, fmt, args );
- stream->winsys->printf( stream->winsys, buffer );
+ debug_vprintf( fmt, args );
va_end( args );
}
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index 8d7bf0b33e..839b98c0ce 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -226,9 +226,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
break;
default:
- winsys->printf(winsys,
- "%s: unknown pci id 0x%x, cannot create screen\n",
- __FUNCTION__, pci_id);
+ debug_printf("%s: unknown pci id 0x%x, cannot create screen\n",
+ __FUNCTION__, pci_id);
return NULL;
}
diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c
index 7c908da672..a276cc0535 100644
--- a/src/gallium/drivers/i965simple/brw_context.c
+++ b/src/gallium/drivers/i965simple/brw_context.c
@@ -77,9 +77,8 @@ struct pipe_context *brw_create(struct pipe_screen *screen,
{
struct brw_context *brw;
- screen->winsys->printf(screen->winsys,
- "%s: creating brw_context with pci id 0x%x\n",
- __FUNCTION__, pci_id);
+ debug_printf("%s: creating brw_context with pci id 0x%x\n",
+ __FUNCTION__, pci_id);
brw = CALLOC_STRUCT(brw_context);
if (brw == NULL)
diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h
index 0c96ba1732..eeccf36785 100644
--- a/src/gallium/drivers/i965simple/brw_context.h
+++ b/src/gallium/drivers/i965simple/brw_context.h
@@ -183,12 +183,12 @@ extern int BRW_DEBUG;
#define DEBUG_MIPTREE 0x800000
#define DBG(...) do { \
- if (BRW_DEBUG & FILE_DEBUG_FLAG) \
- brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
+ if (BRW_DEBUG & FILE_DEBUG_FLAG) \
+ debug_printf(__VA_ARGS__); \
} while(0)
#define PRINT(...) do { \
- brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
+ debug_printf(brw->pipe.winsys, __VA_ARGS__); \
} while(0)
struct brw_state_flags {
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index b50f6f8fef..525eef8d63 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -133,7 +133,7 @@ struct nv40_context {
unsigned fallback_swrast;
/* Context state */
- unsigned dirty;
+ unsigned dirty, draw_dirty;
struct pipe_scissor_state scissor;
unsigned stipple[32];
struct pipe_clip_state clip;
@@ -153,8 +153,10 @@ struct nv40_context {
unsigned nr_samplers;
unsigned nr_textures;
unsigned dirty_samplers;
- struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
+ struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
+ unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX];
+ unsigned vtxelt_nr;
};
static INLINE struct nv40_context *
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 1417c95e75..5dc2991212 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -423,10 +423,9 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_rasterizer_state *rsso = hwcso;
- draw_set_rasterizer_state(nv40->draw, &rsso->pipe);
-
nv40->rasterizer = hwcso;
nv40->dirty |= NV40_NEW_RAST;
+ nv40->draw_dirty |= NV40_NEW_RAST;
}
static void
@@ -445,19 +444,20 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
struct nouveau_stateobj *so = so_new(32, 0);
+ struct nouveau_grobj *curie = nv40->screen->curie;
- so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3);
+ so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
so_data (so, nvgl_comparison_op(cso->depth.func));
so_data (so, cso->depth.writemask ? 1 : 0);
so_data (so, cso->depth.enabled ? 1 : 0);
- so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
+ so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
so_data (so, cso->alpha.enabled ? 1 : 0);
so_data (so, nvgl_comparison_op(cso->alpha.func));
so_data (so, float_to_ubyte(cso->alpha.ref));
if (cso->stencil[0].enabled) {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
+ so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
so_data (so, cso->stencil[0].enabled ? 1 : 0);
so_data (so, cso->stencil[0].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[0].func));
@@ -467,12 +467,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
} else {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
+ so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
so_data (so, 0);
}
if (cso->stencil[1].enabled) {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
+ so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
so_data (so, cso->stencil[1].enabled ? 1 : 0);
so_data (so, cso->stencil[1].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[1].func));
@@ -482,7 +482,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
} else {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
+ so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
so_data (so, 0);
}
@@ -529,10 +529,9 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_vertex_program *vp = hwcso;
- draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL);
-
nv40->vertprog = hwcso;
nv40->dirty |= NV40_NEW_VERTPROG;
+ nv40->draw_dirty |= NV40_NEW_VERTPROG;
}
static void
@@ -595,10 +594,9 @@ nv40_set_clip_state(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_clip_state(nv40->draw, clip);
-
nv40->clip = *clip;
nv40->dirty |= NV40_NEW_UCP;
+ nv40->draw_dirty |= NV40_NEW_UCP;
}
static void
@@ -653,10 +651,9 @@ nv40_set_viewport_state(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_viewport_state(nv40->draw, vpt);
-
nv40->viewport = *vpt;
nv40->dirty |= NV40_NEW_VIEWPORT;
+ nv40->draw_dirty |= NV40_NEW_VIEWPORT;
}
static void
@@ -665,10 +662,11 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_vertex_buffers(nv40->draw, count, vb);
-
memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count);
+ nv40->vtxbuf_nr = count;
+
nv40->dirty |= NV40_NEW_ARRAYS;
+ nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
static void
@@ -677,10 +675,11 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_vertex_elements(nv40->draw, count, ve);
-
memcpy(nv40->vtxelt, ve, sizeof(*ve) * count);
+ nv40->vtxelt_nr = count;
+
nv40->dirty |= NV40_NEW_ARRAYS;
+ nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
void
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h
index ab2866eb7a..e018464c9f 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nv40/nv40_state.h
@@ -42,6 +42,7 @@ struct nv40_vertex_program {
uint32_t ir;
uint32_t or;
+ uint32_t clip_ctrl;
struct nouveau_stateobj *so;
};
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 74feb6d4bf..722b9f31e6 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -144,6 +144,8 @@ nv40_state_validate(struct nv40_context *nv40)
boolean
nv40_state_validate_swtnl(struct nv40_context *nv40)
{
+ struct draw_context *draw = nv40->draw;
+
/* Setup for swtnl */
if (nv40->render_mode == HW) {
NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl);
@@ -155,12 +157,30 @@ nv40_state_validate_swtnl(struct nv40_context *nv40)
nv40->render_mode = SWTNL;
}
+ if (nv40->draw_dirty & NV40_NEW_VERTPROG)
+ draw_bind_vertex_shader(draw, nv40->vertprog->draw);
+
+ if (nv40->draw_dirty & NV40_NEW_RAST)
+ draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe);
+
+ if (nv40->draw_dirty & NV40_NEW_UCP)
+ draw_set_clip_state(draw, &nv40->clip);
+
+ if (nv40->draw_dirty & NV40_NEW_VIEWPORT)
+ draw_set_viewport_state(draw, &nv40->viewport);
+
+ if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
+ draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
+ draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
+ }
+
nv40_state_do_validate(nv40, swtnl_states);
if (nv40->fallback_swrast) {
NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast);
return FALSE;
}
+ nv40->draw_dirty = 0;
return TRUE;
}
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index b66bf26afb..bc53924a67 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -32,7 +32,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
- *fmt = 5;
+ *fmt = NV40TCL_VTXFMT_TYPE_USHORT;
break;
default:
pf_sprint_name(fs, pipe);
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index 40ef7174a4..08d3f387e0 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -37,6 +37,8 @@
#define neg(s) nv40_sr_neg((s))
#define abs(s) nv40_sr_abs((s))
+#define NV40_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n))
+
struct nv40_vpc {
struct nv40_vertex_program *vp;
@@ -200,6 +202,36 @@ emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst)
case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
+ case NV40_VP_INST_DEST_CLIP(0):
+ vp->or |= (1 << 6);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE0;
+ dst.index = NV40_VP_INST_DEST_FOGC;
+ break;
+ case NV40_VP_INST_DEST_CLIP(1):
+ vp->or |= (1 << 7);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE1;
+ dst.index = NV40_VP_INST_DEST_FOGC;
+ break;
+ case NV40_VP_INST_DEST_CLIP(2):
+ vp->or |= (1 << 8);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE2;
+ dst.index = NV40_VP_INST_DEST_FOGC;
+ break;
+ case NV40_VP_INST_DEST_CLIP(3):
+ vp->or |= (1 << 9);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE3;
+ dst.index = NV40_VP_INST_DEST_PSZ;
+ break;
+ case NV40_VP_INST_DEST_CLIP(4):
+ vp->or |= (1 << 10);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE4;
+ dst.index = NV40_VP_INST_DEST_PSZ;
+ break;
+ case NV40_VP_INST_DEST_CLIP(5):
+ vp->or |= (1 << 11);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE5;
+ dst.index = NV40_VP_INST_DEST_PSZ;
+ break;
default:
break;
}
@@ -391,6 +423,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
int ai = -1, ci = -1, ii = -1;
int i;
+ struct {
+ struct nv40_sreg dst;
+ unsigned m;
+ } clip;
+
if (finst->Instruction.Opcode == TGSI_OPCODE_END)
return TRUE;
@@ -464,6 +501,47 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]);
mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+ /* If writing to clip distance regs, need to modify instruction to
+ * change which component is written to. On NV40 the clip regs
+ * are the unused components (yzw) of FOGC/PSZ.
+ */
+ clip.dst = none;
+ if (dst.type == NV40SR_OUTPUT &&
+ dst.index >= NV40_VP_INST_DEST_CLIP(0) &&
+ dst.index <= NV40_VP_INST_DEST_CLIP(5)) {
+ unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0);
+ unsigned m[] =
+ { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W };
+
+ /* Some instructions we can get away with swizzling and/or
+ * changing the writemask. Others, we'll use a temp reg.
+ */
+ switch (finst->Instruction.Opcode) {
+ case TGSI_OPCODE_DST:
+ case TGSI_OPCODE_EXP:
+ case TGSI_OPCODE_LIT:
+ case TGSI_OPCODE_LOG:
+ case TGSI_OPCODE_XPD:
+ clip.dst = dst;
+ clip.m = m[n];
+ dst = temp(vpc);
+ break;
+ case TGSI_OPCODE_DP3:
+ case TGSI_OPCODE_DP4:
+ case TGSI_OPCODE_DPH:
+ case TGSI_OPCODE_POW:
+ case TGSI_OPCODE_RCP:
+ case TGSI_OPCODE_RSQ:
+ mask = m[n];
+ break;
+ default:
+ for (i = 0; i < finst->Instruction.NumSrcRegs; i++)
+ src[i] = swz(src[i], X, X, X, X);
+ mask = m[n];
+ break;
+ }
+ }
+
switch (finst->Instruction.Opcode) {
case TGSI_OPCODE_ABS:
arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none);
@@ -561,6 +639,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
return FALSE;
}
+ if (clip.dst.type != NV40SR_NONE) {
+ arith(vpc, 0, OP_MOV, clip.dst, clip.m,
+ swz(dst, X, X, X, X), none, none);
+ }
+
release_temps(vpc);
return TRUE;
}
@@ -612,6 +695,15 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
return FALSE;
}
break;
+#if 0
+ case TGSI_SEMANTIC_CLIP:
+ if (fdec->Semantic.SemanticIndex >= 6) {
+ NOUVEAU_ERR("bad clip distance index\n");
+ return FALSE;
+ }
+ hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex);
+ break;
+#endif
default:
NOUVEAU_ERR("bad output semantic\n");
return FALSE;
@@ -782,6 +874,7 @@ nv40_vertprog_validate(struct nv40_context *nv40)
{
struct nouveau_winsys *nvws = nv40->nvws;
struct pipe_winsys *ws = nv40->pipe.winsys;
+ struct nouveau_grobj *curie = nv40->screen->curie;
struct nv40_vertex_program *vp;
struct pipe_buffer *constbuf;
boolean upload_code = FALSE, upload_data = FALSE;
@@ -825,12 +918,14 @@ check_gpu_resources:
assert(0);
}
- so = so_new(5, 0);
- so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1);
+ so = so_new(7, 0);
+ so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1);
so_data (so, vp->exec->start);
- so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2);
+ so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2);
so_data (so, vp->ir);
so_data (so, vp->or);
+ so_method(so, curie, NV40TCL_CLIP_PLANE_ENABLE, 1);
+ so_data (so, vp->clip_ctrl);
so_ref(so, &vp->so);
upload_code = TRUE;