summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/i915
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-07-04 15:04:41 +0200
committerChristian König <[email protected]>2011-07-04 15:04:41 +0200
commitc3b2230b71cb3a00a7f4c0987197d397bada650b (patch)
tree018f5df0f8b5976ddb56ef4f13e9466587838998 /src/gallium/drivers/i915
parent003401f95c9b59471c22368b7da16fe7a951e490 (diff)
parent424b1210d951c206e7c2fb8f2778acbd384eb247 (diff)
Merge remote-tracking branch 'origin/master' into pipe-video
Conflicts: configure.ac src/gallium/drivers/r600/r600_state_inlines.h src/gallium/tests/trivial/Makefile src/gallium/winsys/g3dvl/dri/XF86dri.c src/gallium/winsys/g3dvl/dri/driclient.c src/gallium/winsys/g3dvl/dri/driclient.h src/gallium/winsys/g3dvl/dri/xf86dri.h src/gallium/winsys/g3dvl/dri/xf86dristr.h src/gallium/winsys/r600/drm/r600_bo.c
Diffstat (limited to 'src/gallium/drivers/i915')
-rw-r--r--src/gallium/drivers/i915/Makefile1
-rw-r--r--src/gallium/drivers/i915/SConscript1
-rw-r--r--src/gallium/drivers/i915/TODO15
-rw-r--r--src/gallium/drivers/i915/i915_clear.c2
-rw-r--r--src/gallium/drivers/i915/i915_context.c25
-rw-r--r--src/gallium/drivers/i915/i915_context.h3
-rw-r--r--src/gallium/drivers/i915/i915_fpc.h5
-rw-r--r--src/gallium/drivers/i915/i915_fpc_emit.c72
-rw-r--r--src/gallium/drivers/i915/i915_fpc_translate.c134
-rw-r--r--src/gallium/drivers/i915/i915_query.c86
-rw-r--r--src/gallium/drivers/i915/i915_query.h36
-rw-r--r--src/gallium/drivers/i915/i915_reg.h7
-rw-r--r--src/gallium/drivers/i915/i915_resource.c4
-rw-r--r--src/gallium/drivers/i915/i915_resource.h12
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c196
-rw-r--r--src/gallium/drivers/i915/i915_screen.c15
-rw-r--r--src/gallium/drivers/i915/i915_screen.h6
-rw-r--r--src/gallium/drivers/i915/i915_state.c14
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c30
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c94
-rw-r--r--src/gallium/drivers/i915/i915_state_inlines.h25
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c52
-rw-r--r--src/gallium/drivers/i915/i915_state_static.c15
23 files changed, 682 insertions, 168 deletions
diff --git a/src/gallium/drivers/i915/Makefile b/src/gallium/drivers/i915/Makefile
index b3f387f9335..778124728bb 100644
--- a/src/gallium/drivers/i915/Makefile
+++ b/src/gallium/drivers/i915/Makefile
@@ -21,6 +21,7 @@ C_SOURCES = \
i915_screen.c \
i915_prim_emit.c \
i915_prim_vbuf.c \
+ i915_query.c \
i915_resource.c \
i915_resource_texture.c \
i915_resource_buffer.c \
diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript
index 8f5deed64a9..98370601b7f 100644
--- a/src/gallium/drivers/i915/SConscript
+++ b/src/gallium/drivers/i915/SConscript
@@ -16,6 +16,7 @@ i915 = env.ConvenienceLibrary(
'i915_fpc_translate.c',
'i915_prim_emit.c',
'i915_prim_vbuf.c',
+ 'i915_query.c',
'i915_screen.c',
'i915_state.c',
'i915_state_derived.c',
diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO
index fba180064c3..c26db198d20 100644
--- a/src/gallium/drivers/i915/TODO
+++ b/src/gallium/drivers/i915/TODO
@@ -26,5 +26,20 @@ Random list of problems with i915g:
- src/xvmc/i915_structs.h in xf86-video-intel has a few more bits of various
commands defined. Scavenge them and see what's useful.
+- Do smarter remapping. Right now we send everything onto tex coords 0-7.
+ We could also use diffuse/specular and pack two sets of 2D coords in a single
+ 4D. Is it a big problem though? We're more limited by the # of texture
+ indirections and the # of instructions.
+
+- Leverage draw to enable more caps:
+ * PIPE_CAP_TGSI_INSTANCEID
+ * PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS
+
+- Finish front/back face. We need to add face support to lp_build_system_values_array and use it in draw_llvm.c.
+
+- Replace constants and immediates which are 0,1,-1 or a combination of those with a swizzle.
+
+- i915_delete_fs_state doesn't call draw_delete_fragment_shader. Why?
+
Other bugs can be found here:
https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g
diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 4a97746e981..fcb208d6dae 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -66,7 +66,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
else
clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);
- util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
+ util_pack_color(rgba, cbuf->format, &u_color);
clear_color8888 = u_color.ui;
} else
clear_color = clear_color8888 = 0;
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 7a98ef73c1f..28ff40a2328 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -29,6 +29,7 @@
#include "i915_state.h"
#include "i915_screen.h"
#include "i915_surface.h"
+#include "i915_query.h"
#include "i915_batch.h"
#include "i915_resource.h"
@@ -53,13 +54,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
void *mapped_indices = NULL;
- unsigned cbuf_dirty;
/*
* Ack vs contants here, helps ipers a lot.
*/
- cbuf_dirty = i915->dirty & I915_NEW_VS_CONSTANTS;
i915->dirty &= ~I915_NEW_VS_CONSTANTS;
if (i915->dirty)
@@ -72,15 +71,13 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
draw_set_mapped_index_buffer(draw, mapped_indices);
- if (cbuf_dirty) {
- if (i915->constants[PIPE_SHADER_VERTEX])
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
- i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
- (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
- 4 * sizeof(float)));
- else
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
- }
+ if (i915->constants[PIPE_SHADER_VERTEX])
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
+ i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
+ (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
+ 4 * sizeof(float)));
+ else
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
/*
* Do the drawing
@@ -106,7 +103,7 @@ static void i915_destroy(struct pipe_context *pipe)
if (i915->blitter)
util_blitter_destroy(i915->blitter);
-
+
if(i915->batch)
i915->iws->batchbuffer_destroy(i915->batch);
@@ -150,6 +147,8 @@ i915_create_context(struct pipe_screen *screen, void *priv)
/* init this before draw */
util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
16, UTIL_SLAB_SINGLETHREADED);
+ util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer),
+ 16, UTIL_SLAB_SINGLETHREADED);
/* Batch stream debugging is a bit hacked up at the moment:
*/
@@ -170,9 +169,11 @@ i915_create_context(struct pipe_screen *screen, void *priv)
i915_init_state_functions(i915);
i915_init_flush_functions(i915);
i915_init_resource_functions(i915);
+ i915_init_query_functions(i915);
draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base);
+ draw_enable_point_sprites(i915->draw, TRUE);
/* augmented draw pipeline clobbers state functions */
i915_init_fixup_state_functions(i915);
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 964948edc0e..c964208fedd 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -102,6 +102,8 @@ struct i915_fragment_shader
struct tgsi_shader_info info;
+ struct draw_fragment_shader *draw_data;
+
uint *program;
uint program_len;
@@ -260,6 +262,7 @@ struct i915_context {
int num_validation_buffers;
struct util_slab_mempool transfer_pool;
+ struct util_slab_mempool texture_transfer_pool;
/** blitter/hw-clear */
struct blitter_context* blitter;
diff --git a/src/gallium/drivers/i915/i915_fpc.h b/src/gallium/drivers/i915/i915_fpc.h
index 2f0f99d0468..509395cf1f5 100644
--- a/src/gallium/drivers/i915/i915_fpc.h
+++ b/src/gallium/drivers/i915/i915_fpc.h
@@ -37,6 +37,9 @@
#define I915_PROGRAM_SIZE 192
+/* Use those indices for pos/face routing, must be >= I915_TEX_UNITS */
+#define I915_SEMANTIC_POS 10
+#define I915_SEMANTIC_FACE 11
/**
@@ -67,13 +70,13 @@ struct i915_fp_compile {
uint temp_flag; /**< Tracks temporary regs which are in use */
uint utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */
+ uint register_phases[16];
uint nr_tex_indirect;
uint nr_tex_insn;
uint nr_alu_insn;
uint nr_decl_insn;
boolean error; /**< Set if i915_program_error() is called */
- uint wpos_tex;
uint NumNativeInstructions;
uint NumNativeAluInstructions;
uint NumNativeTexInstructions;
diff --git a/src/gallium/drivers/i915/i915_fpc_emit.c b/src/gallium/drivers/i915/i915_fpc_emit.c
index 76c24d2b2fd..d28595e0fd3 100644
--- a/src/gallium/drivers/i915/i915_fpc_emit.c
+++ b/src/gallium/drivers/i915/i915_fpc_emit.c
@@ -67,7 +67,7 @@ i915_get_temp(struct i915_fp_compile *p)
{
int bit = ffs(~p->temp_flag);
if (!bit) {
- i915_program_error(p, "i915_get_temp: out of temporaries\n");
+ i915_program_error(p, "i915_get_temp: out of temporaries");
return 0;
}
@@ -92,7 +92,7 @@ i915_get_utemp(struct i915_fp_compile * p)
{
int bit = ffs(~p->utemp_flag);
if (!bit) {
- i915_program_error(p, "i915_get_utemp: out of temporaries\n");
+ i915_program_error(p, "i915_get_utemp: out of temporaries");
return 0;
}
@@ -128,9 +128,13 @@ i915_emit_decl(struct i915_fp_compile *p,
else
return reg;
- *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
- *(p->decl++) = D1_MBZ;
- *(p->decl++) = D2_MBZ;
+ if (p->decl< p->declarations + I915_PROGRAM_SIZE) {
+ *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
+ *(p->decl++) = D1_MBZ;
+ *(p->decl++) = D2_MBZ;
+ }
+ else
+ i915_program_error(p, "Out of declarations");
p->nr_decl_insn++;
return reg;
@@ -187,9 +191,16 @@ i915_emit_arith(struct i915_fp_compile * p,
p->utemp_flag = old_utemp_flag; /* restore */
}
- *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
- *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
- *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
+ if (p->csr< p->program + I915_PROGRAM_SIZE) {
+ *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+ *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
+ *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
+ }
+ else
+ i915_program_error(p, "Out of instructions");
+
+ if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+ p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
p->nr_alu_insn++;
return dest;
@@ -245,17 +256,31 @@ uint i915_emit_texld( struct i915_fp_compile *p,
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
- /* is the sampler coord a texcoord input reg? */
- if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
- p->nr_tex_indirect++;
- }
+ /* Output register being oC or oD defines a phase boundary */
+ if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
+ GET_UREG_TYPE(dest) == REG_TYPE_OD)
+ p->nr_tex_indirect++;
- *(p->csr++) = (opcode |
- T0_DEST( dest ) |
- T0_SAMPLER( sampler ));
+ /* Reading from an r# register whose contents depend on output of the
+ * current phase defines a phase boundary.
+ */
+ if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
+ p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
+ p->nr_tex_indirect++;
+
+ if (p->csr< p->program + I915_PROGRAM_SIZE) {
+ *(p->csr++) = (opcode |
+ T0_DEST( dest ) |
+ T0_SAMPLER( sampler ));
+
+ *(p->csr++) = T1_ADDRESS_REG( coord );
+ *(p->csr++) = T2_MBZ;
+ }
+ else
+ i915_program_error(p, "Out of instructions");
- *(p->csr++) = T1_ADDRESS_REG( coord );
- *(p->csr++) = T2_MBZ;
+ if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+ p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
p->nr_tex_insn++;
}
@@ -293,7 +318,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0)
}
}
- i915_program_error(p, "i915_emit_const1f: out of constants\n");
+ i915_program_error(p, "i915_emit_const1f: out of constants");
return 0;
}
@@ -313,6 +338,8 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
if (c1 == 1.0)
return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
+ // XXX emit swizzle here for 0, 1, -1 and any combination thereof
+ // we can use swizzle + neg for that
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (ifs->constant_flags[reg] == 0xf ||
ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
@@ -329,12 +356,10 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
}
}
- i915_program_error(p, "i915_emit_const2f: out of constants\n");
+ i915_program_error(p, "i915_emit_const2f: out of constants");
return 0;
}
-
-
uint
i915_emit_const4f(struct i915_fp_compile * p,
float c0, float c1, float c2, float c3)
@@ -342,6 +367,9 @@ i915_emit_const4f(struct i915_fp_compile * p,
struct i915_fragment_shader *ifs = p->shader;
unsigned reg;
+ // XXX emit swizzle here for 0, 1, -1 and any combination thereof
+ // we can use swizzle + neg for that
+ printf("const %f %f %f %f\n",c0,c1,c2,c3);
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (ifs->constant_flags[reg] == 0xf &&
ifs->constants[reg][0] == c0 &&
@@ -363,7 +391,7 @@ i915_emit_const4f(struct i915_fp_compile * p,
}
}
- i915_program_error(p, "i915_emit_const4f: out of constants\n");
+ i915_program_error(p, "i915_emit_const4f: out of constants");
return 0;
}
diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c
index 27f100843bf..0cbd4f2d748 100644
--- a/src/gallium/drivers/i915/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915/i915_fpc_translate.c
@@ -41,6 +41,9 @@
#include "draw/draw_vertex.h"
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
/**
* Simple pass-through fragment shader to use when we don't have
@@ -72,19 +75,33 @@ static unsigned passthrough[] =
/* 1, -1/3!, 1/5!, -1/7! */
-static const float sin_constants[4] = { 1.0,
+static const float scs_sin_constants[4] = { 1.0,
-1.0f / (3 * 2 * 1),
1.0f / (5 * 4 * 3 * 2 * 1),
-1.0f / (7 * 6 * 5 * 4 * 3 * 2 * 1)
};
/* 1, -1/2!, 1/4!, -1/6! */
-static const float cos_constants[4] = { 1.0,
+static const float scs_cos_constants[4] = { 1.0,
-1.0f / (2 * 1),
1.0f / (4 * 3 * 2 * 1),
-1.0f / (6 * 5 * 4 * 3 * 2 * 1)
};
+/* 2*pi, -(2*pi)^3/3!, (2*pi)^5/5!, -(2*pi)^7/7! */
+static const float sin_constants[4] = { 2.0 * M_PI,
+ -8.0f * M_PI * M_PI * M_PI / (3 * 2 * 1),
+ 32.0f * M_PI * M_PI * M_PI * M_PI * M_PI / (5 * 4 * 3 * 2 * 1),
+ -128.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (7 * 6 * 5 * 4 * 3 * 2 * 1)
+};
+
+/* 1, -(2*pi)^2/2!, (2*pi)^4/4!, -(2*pi)^6/6! */
+static const float cos_constants[4] = { 1.0,
+ -4.0f * M_PI * M_PI / (2 * 1),
+ 16.0f * M_PI * M_PI * M_PI * M_PI / (4 * 3 * 2 * 1),
+ -64.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (6 * 5 * 4 * 3 * 2 * 1)
+};
+
/**
@@ -185,12 +202,12 @@ src_vector(struct i915_fp_compile *p,
switch (sem_name) {
case TGSI_SEMANTIC_POSITION:
- debug_printf("SKIP SEM POS\n");
- /*
- assert(p->wpos_tex != -1);
- src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL);
- */
- break;
+ {
+ /* for fragcoord */
+ int real_tex_unit = get_mapping(fs, I915_SEMANTIC_POS);
+ src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
+ break;
+ }
case TGSI_SEMANTIC_COLOR:
if (sem_ind == 0) {
src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
@@ -212,6 +229,13 @@ src_vector(struct i915_fp_compile *p,
src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
break;
}
+ case TGSI_SEMANTIC_FACE:
+ {
+ /* for back/front faces */
+ int real_tex_unit = get_mapping(fs, I915_SEMANTIC_FACE);
+ src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_X);
+ break;
+ }
default:
i915_program_error(p, "Bad source->Index");
return 0;
@@ -237,7 +261,6 @@ src_vector(struct i915_fp_compile *p,
source->Register.SwizzleZ,
source->Register.SwizzleW);
-
/* There's both negate-all-components and per-component negation.
* Try to handle both here.
*/
@@ -252,6 +275,9 @@ src_vector(struct i915_fp_compile *p,
/* XXX enable these assertions, or fix things */
assert(!source->Register.Absolute);
#endif
+ if (source->Register.Absolute)
+ debug_printf("Unhandled absolute value\n");
+
return src;
}
@@ -419,11 +445,6 @@ emit_simple_arith_swap2(struct i915_fp_compile *p,
emit_simple_arith(p, &inst2, opcode, numArgs, fs);
}
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
/*
* Translate TGSI instruction to i915 instruction.
*
@@ -477,13 +498,6 @@ i915_translate_instruction(struct i915_fp_compile *p,
i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
- /* By choosing different taylor constants, could get rid of this mul:
- */
- i915_emit_arith(p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0);
-
/*
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1
@@ -516,6 +530,18 @@ i915_translate_instruction(struct i915_fp_compile *p,
i915_emit_const4fv(p, cos_constants), 0);
break;
+ case TGSI_OPCODE_DDX:
+ case TGSI_OPCODE_DDY:
+ /* XXX We just output 0 here */
+ debug_printf("Punting DDX/DDX\n");
+ src0 = get_result_vector(p, &inst->Dst[0]);
+ i915_emit_arith(p,
+ A0_MOV,
+ get_result_vector(p, &inst->Dst[0]),
+ get_result_flags(inst), 0,
+ swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0, 0);
+ break;
+
case TGSI_OPCODE_DP2:
src0 = src_vector(p, &inst->Src[0], fs);
src1 = src_vector(p, &inst->Src[1], fs);
@@ -754,9 +780,9 @@ i915_translate_instruction(struct i915_fp_compile *p,
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x
* t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x
- * scs.x = DP4 t1, sin_constants
+ * scs.x = DP4 t1, scs_sin_constants
* t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1
- * scs.y = DP4 t1, cos_constants
+ * scs.y = DP4 t1, scs_cos_constants
*/
i915_emit_arith(p,
A0_MUL,
@@ -791,7 +817,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
get_result_vector(p, &inst->Dst[0]),
A0_DEST_CHANNEL_Y, 0,
swizzle(tmp1, W, Z, Y, X),
- i915_emit_const4fv(p, sin_constants), 0);
+ i915_emit_const4fv(p, scs_sin_constants), 0);
}
if (writemask & TGSI_WRITEMASK_X) {
@@ -806,7 +832,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
get_result_vector(p, &inst->Dst[0]),
A0_DEST_CHANNEL_X, 0,
swizzle(tmp, ONE, Z, Y, X),
- i915_emit_const4fv(p, cos_constants), 0);
+ i915_emit_const4fv(p, scs_cos_constants), 0);
}
break;
@@ -853,13 +879,6 @@ i915_translate_instruction(struct i915_fp_compile *p,
i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
- /* By choosing different taylor constants, could get rid of this mul:
- */
- i915_emit_arith(p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0);
-
/*
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x
@@ -907,7 +926,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
break;
case TGSI_OPCODE_SNE:
- /* if we're neither < nor > then we're != */
+ /* if we're < or > then we're != */
src0 = src_vector(p, &inst->Src[0], fs);
src1 = src_vector(p, &inst->Src[1], fs);
tmp = i915_get_utemp(p);
@@ -1070,9 +1089,11 @@ i915_translate_instructions(struct i915_fp_compile *p,
for (i = parse.FullToken.FullDeclaration.Range.First;
i <= parse.FullToken.FullDeclaration.Range.Last;
i++) {
- assert(i < I915_MAX_TEMPORARY);
- /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
- p->temp_flag |= (1 << i); /* mark temp as used */
+ if (i >= I915_MAX_TEMPORARY)
+ debug_printf("Too many temps (%d)\n",i);
+ else
+ /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
+ p->temp_flag |= (1 << i); /* mark temp as used */
}
}
break;
@@ -1144,6 +1165,8 @@ i915_init_compile(struct i915_context *i915,
ifs->num_constants = 0;
memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags));
+ memset(&p->register_phases, 0, sizeof(p->register_phases));
+
for (i = 0; i < I915_TEX_UNITS; i++)
ifs->generic_mapping[i] = -1;
@@ -1161,8 +1184,6 @@ i915_init_compile(struct i915_context *i915,
p->temp_flag = ~0x0 << I915_MAX_TEMPORARY;
p->utemp_flag = ~0x7;
- p->wpos_tex = -1;
-
/* initialize the first program word */
*(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM;
@@ -1181,7 +1202,7 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
unsigned long decl_size = (unsigned long) (p->decl - p->declarations);
if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT)
- i915_program_error(p, "Exceeded max nr indirect texture lookups");
+ debug_printf("Exceeded max nr indirect texture lookups\n");
if (p->nr_tex_insn > I915_MAX_TEX_INSN)
i915_program_error(p, "Exceeded max TEX instructions");
@@ -1234,40 +1255,6 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
}
-/**
- * Find an unused texture coordinate slot to use for fragment WPOS.
- * Update p->fp->wpos_tex with the result (-1 if no used texcoord slot is found).
- */
-static void
-i915_find_wpos_space(struct i915_fp_compile *p)
-{
-#if 0
- const uint inputs
- = p->shader->inputs_read | (1 << TGSI_ATTRIB_POS); /*XXX hack*/
- uint i;
-
- p->wpos_tex = -1;
-
- if (inputs & (1 << TGSI_ATTRIB_POS)) {
- for (i = 0; i < I915_TEX_UNITS; i++) {
- if ((inputs & (1 << (TGSI_ATTRIB_TEX0 + i))) == 0) {
- p->wpos_tex = i;
- return;
- }
- }
-
- i915_program_error(p, "No free texcoord for wpos value");
- }
-#else
- if (p->shader->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
- /* frag shader using the fragment position input */
-#if 0
- assert(0);
-#endif
- }
-#endif
-}
-
@@ -1314,7 +1301,6 @@ i915_translate_fragment_program( struct i915_context *i915,
}
p = i915_init_compile(i915, fs);
- i915_find_wpos_space(p);
i915_translate_instructions(p, tokens, fs);
i915_fixup_depth_write(p);
diff --git a/src/gallium/drivers/i915/i915_query.c b/src/gallium/drivers/i915/i915_query.c
new file mode 100644
index 00000000000..c886df74bad
--- /dev/null
+++ b/src/gallium/drivers/i915/i915_query.c
@@ -0,0 +1,86 @@
+/**************************************************************************
+ *
+ * Copyright 2011 The Chromium OS authors.
+ * 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 GOOGLE 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.
+ *
+ **************************************************************************/
+
+/* Fake occlusion queries which return 0, it's better than crashing */
+
+#include "pipe/p_compiler.h"
+
+#include "util/u_memory.h"
+
+#include "i915_context.h"
+#include "i915_query.h"
+
+struct i915_query
+{
+ unsigned query;
+};
+
+static struct pipe_query *i915_create_query(struct pipe_context *ctx,
+ unsigned query_type)
+{
+ struct i915_query *query = CALLOC_STRUCT( i915_query );
+
+ return (struct pipe_query *)query;
+}
+
+static void i915_destroy_query(struct pipe_context *ctx,
+ struct pipe_query *query)
+{
+ FREE(query);
+}
+
+static void i915_begin_query(struct pipe_context *ctx,
+ struct pipe_query *query)
+{
+}
+
+static void i915_end_query(struct pipe_context *ctx, struct pipe_query *query)
+{
+}
+
+static boolean i915_get_query_result(struct pipe_context *ctx,
+ struct pipe_query *query,
+ boolean wait,
+ void *vresult)
+{
+ uint64_t *result = (uint64_t*)vresult;
+
+ /* 2* viewport Max */
+ *result = 512*1024*1024;
+ return TRUE;
+}
+
+void
+i915_init_query_functions(struct i915_context *i915)
+{
+ i915->base.create_query = i915_create_query;
+ i915->base.destroy_query = i915_destroy_query;
+ i915->base.begin_query = i915_begin_query;
+ i915->base.end_query = i915_end_query;
+ i915->base.get_query_result = i915_get_query_result;
+}
+
diff --git a/src/gallium/drivers/i915/i915_query.h b/src/gallium/drivers/i915/i915_query.h
new file mode 100644
index 00000000000..2c689ea6b1c
--- /dev/null
+++ b/src/gallium/drivers/i915/i915_query.h
@@ -0,0 +1,36 @@
+/**************************************************************************
+ *
+ * Copyright 2011 The Chromium OS authors.
+ * 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 GOOGLE 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 I915_QUERY_H
+#define I915_QUERY_H
+
+struct i915_context;
+struct pipe_context;
+
+void i915_init_query_functions( struct i915_context *i915 );
+
+#endif /* I915_QUERY_H */
diff --git a/src/gallium/drivers/i915/i915_reg.h b/src/gallium/drivers/i915/i915_reg.h
index 6fe032cdb6e..14e786d0f2a 100644
--- a/src/gallium/drivers/i915/i915_reg.h
+++ b/src/gallium/drivers/i915/i915_reg.h
@@ -170,6 +170,13 @@
#define COLOR_BUF_RGB555 (1<<8)
#define COLOR_BUF_RGB565 (2<<8)
#define COLOR_BUF_ARGB8888 (3<<8)
+#define COLOR_BUF_YCRCB_SWAP (4<<8)
+#define COLOR_BUF_YCRCB_NORMAL (5<<8)
+#define COLOR_BUF_YCRCB_SWAPUV (6<<8)
+#define COLOR_BUF_YCRCB_SWAPUVY (7<<8)
+#define COLOR_BUF_ARGB4444 (8<<8)
+#define COLOR_BUF_ARGB1555 (9<<8)
+#define COLOR_BUF_ARGB2101010 (10<<8)
#define DEPTH_FRMT_16_FIXED 0
#define DEPTH_FRMT_16_FLOAT (1<<2)
#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2)
diff --git a/src/gallium/drivers/i915/i915_resource.c b/src/gallium/drivers/i915/i915_resource.c
index 7f52ba11d61..b4719af1fb6 100644
--- a/src/gallium/drivers/i915/i915_resource.c
+++ b/src/gallium/drivers/i915/i915_resource.c
@@ -7,12 +7,12 @@
static struct pipe_resource *
i915_resource_create(struct pipe_screen *screen,
- const struct pipe_resource *template)
+ const struct pipe_resource *template)
{
if (template->target == PIPE_BUFFER)
return i915_buffer_create(screen, template);
else
- return i915_texture_create(screen, template);
+ return i915_texture_create(screen, template, FALSE);
}
diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h
index c15ecdfc22a..14eed2c4a79 100644
--- a/src/gallium/drivers/i915/i915_resource.h
+++ b/src/gallium/drivers/i915/i915_resource.h
@@ -45,6 +45,15 @@ struct i915_buffer {
boolean free_on_destroy;
};
+
+/* Texture transfer. */
+struct i915_transfer {
+ /* Base class. */
+ struct pipe_transfer b;
+ struct pipe_resource *staging_texture;
+};
+
+
#define I915_MAX_TEXTURE_2D_LEVELS 12 /* max 2048x2048 */
#define I915_MAX_TEXTURE_3D_LEVELS 9 /* max 256x256x256 */
@@ -101,7 +110,8 @@ static INLINE struct i915_buffer *i915_buffer(struct pipe_resource *resource)
struct pipe_resource *
i915_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *template);
+ const struct pipe_resource *template,
+ boolean force_untiled);
struct pipe_resource *
i915_texture_from_handle(struct pipe_screen * screen,
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index b74b19d0fe4..0b6424f8d16 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -37,6 +37,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_rect.h"
#include "i915_context.h"
#include "i915_resource.h"
@@ -710,7 +711,7 @@ i915_texture_destroy(struct pipe_screen *screen,
FREE(tex);
}
-static struct pipe_transfer *
+static struct pipe_transfer *
i915_texture_get_transfer(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
@@ -719,19 +720,45 @@ i915_texture_get_transfer(struct pipe_context *pipe,
{
struct i915_context *i915 = i915_context(pipe);
struct i915_texture *tex = i915_texture(resource);
- struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool);
+ struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool);
+ boolean use_staging_texture = FALSE;
if (transfer == NULL)
return NULL;
- transfer->resource = resource;
- transfer->level = level;
- transfer->usage = usage;
- transfer->box = *box;
- transfer->stride = tex->stride;
- /* FIXME: layer_stride */
+ transfer->b.resource = resource;
+ transfer->b.level = level;
+ transfer->b.usage = usage;
+ transfer->b.box = *box;
+ transfer->b.stride = tex->stride;
+ transfer->staging_texture = NULL;
+ /* XXX: handle depth textures everyhwere*/
+ transfer->b.layer_stride = 0;
+ transfer->b.data = NULL;
+
+ /* if we use staging transfers, only support textures we can render to,
+ * because we need that for u_blitter */
+ if (i915->blitter &&
+ i915_is_format_supported(NULL, /* screen */
+ transfer->b.resource->format,
+ 0, /* target */
+ 1, /* sample count */
+ PIPE_BIND_RENDER_TARGET) &&
+ (usage & PIPE_TRANSFER_WRITE) &&
+ !(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED)))
+ use_staging_texture = TRUE;
+
+ use_staging_texture = FALSE;
+
+ if (use_staging_texture) {
+ /*
+ * Allocate the untiled staging texture.
+ * If the alloc fails, transfer->staging_texture is NULL and we fallback to a map()
+ */
+ transfer->staging_texture = i915_texture_create(pipe->screen, resource, TRUE);
+ }
- return transfer;
+ return (struct pipe_transfer*)transfer;
}
static void
@@ -739,17 +766,33 @@ i915_transfer_destroy(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_context *i915 = i915_context(pipe);
- util_slab_free(&i915->transfer_pool, transfer);
+ struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
+
+ if ((itransfer->staging_texture) &&
+ (transfer->usage & PIPE_TRANSFER_WRITE)) {
+ struct pipe_box sbox;
+
+ u_box_origin_2d(itransfer->b.box.width, itransfer->b.box.height, &sbox);
+ pipe->resource_copy_region(pipe, itransfer->b.resource, itransfer->b.level,
+ itransfer->b.box.x, itransfer->b.box.y, itransfer->b.box.z,
+ itransfer->staging_texture,
+ 0, &sbox);
+ pipe->flush(pipe, NULL);
+ pipe_resource_reference(&itransfer->staging_texture, NULL);
+ }
+
+ util_slab_free(&i915->texture_transfer_pool, itransfer);
}
static void *
i915_texture_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct pipe_resource *resource = transfer->resource;
- struct i915_texture *tex = i915_texture(resource);
+ struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
+ struct pipe_resource *resource = itransfer->b.resource;
+ struct i915_texture *tex = NULL;
struct i915_winsys *iws = i915_screen(pipe->screen)->iws;
- struct pipe_box *box = &transfer->box;
+ struct pipe_box *box = &itransfer->b.box;
enum pipe_format format = resource->format;
unsigned offset;
char *map;
@@ -757,18 +800,25 @@ i915_texture_transfer_map(struct pipe_context *pipe,
if (resource->target != PIPE_TEXTURE_3D &&
resource->target != PIPE_TEXTURE_CUBE)
assert(box->z == 0);
- offset = i915_texture_offset(tex, transfer->level, box->z);
- /* TODO this is a sledgehammer */
- pipe->flush(pipe, NULL);
+ if (itransfer->staging_texture) {
+ tex = i915_texture(itransfer->staging_texture);
+ } else {
+ /* TODO this is a sledgehammer */
+ tex = i915_texture(resource);
+ pipe->flush(pipe, NULL);
+ }
+
+ offset = i915_texture_offset(tex, itransfer->b.level, box->z);
map = iws->buffer_map(iws, tex->buffer,
- (transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
- if (map == NULL)
+ (itransfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
+ if (map == NULL) {
return NULL;
+ }
return map + offset +
- box->y / util_format_get_blockheight(format) * transfer->stride +
+ box->y / util_format_get_blockheight(format) * itransfer->b.stride +
box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
}
@@ -776,14 +826,106 @@ static void
i915_texture_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct i915_texture *tex = i915_texture(transfer->resource);
+ struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
+ struct i915_texture *tex = i915_texture(itransfer->b.resource);
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
+
+ if (itransfer->staging_texture)
+ tex = i915_texture(itransfer->staging_texture);
+
iws->buffer_unmap(iws, tex->buffer);
}
+static void i915_transfer_inline_write( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride)
+{
+ struct pipe_transfer *transfer = NULL;
+ struct i915_transfer *itransfer = NULL;
+ const uint8_t *src_data = data;
+ unsigned i;
+
+ transfer = pipe->get_transfer(pipe,
+ resource,
+ level,
+ usage,
+ box );
+ if (transfer == NULL)
+ goto out;
+
+ itransfer = (struct i915_transfer*)transfer;
+
+ if (itransfer->staging_texture) {
+ struct i915_texture *tex = i915_texture(itransfer->staging_texture);
+ enum pipe_format format = tex->b.b.format;
+ struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
+ size_t offset;
+ size_t size;
+
+ offset = i915_texture_offset(tex, transfer->level, transfer->box.z);
+
+ for (i = 0; i < box->depth; i++) {
+ if (!tex->b.b.last_level &&
+ tex->b.b.width0 == transfer->box.width) {
+ unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
+ assert(!offset);
+ assert(!transfer->box.x);
+ assert(tex->stride == transfer->stride);
+
+ offset += tex->stride * nby;
+ size = util_format_get_2d_size(format, transfer->stride,
+ transfer->box.height);
+ iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
+
+ } else {
+ unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
+ int i;
+ offset += util_format_get_stride(format, transfer->box.x);
+ size = transfer->stride;
+
+ for (i = 0; i < nby; i++) {
+ iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
+ offset += tex->stride;
+ }
+ }
+ offset += layer_stride;
+ }
+ } else {
+ uint8_t *map = pipe_transfer_map(pipe, &itransfer->b);
+ if (map == NULL)
+ goto nomap;
+
+ for (i = 0; i < box->depth; i++) {
+ util_copy_rect(map,
+ resource->format,
+ itransfer->b.stride, /* bytes */
+ 0, 0,
+ box->width,
+ box->height,
+ src_data,
+ stride, /* bytes */
+ 0, 0);
+ map += itransfer->b.layer_stride;
+ src_data += layer_stride;
+ }
+nomap:
+ if (map)
+ pipe_transfer_unmap(pipe, &itransfer->b);
+ }
+
+out:
+ if (itransfer)
+ pipe_transfer_destroy(pipe, &itransfer->b);
+}
-struct u_resource_vtbl i915_texture_vtbl =
+
+struct u_resource_vtbl i915_texture_vtbl =
{
i915_texture_get_handle, /* get_handle */
i915_texture_destroy, /* resource_destroy */
@@ -792,7 +934,7 @@ struct u_resource_vtbl i915_texture_vtbl =
i915_texture_transfer_map, /* transfer_map */
u_default_transfer_flush_region, /* transfer_flush_region */
i915_texture_transfer_unmap, /* transfer_unmap */
- u_default_transfer_inline_write /* transfer_inline_write */
+ i915_transfer_inline_write /* transfer_inline_write */
};
@@ -800,7 +942,8 @@ struct u_resource_vtbl i915_texture_vtbl =
struct pipe_resource *
i915_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *template)
+ const struct pipe_resource *template,
+ boolean force_untiled)
{
struct i915_screen *is = i915_screen(screen);
struct i915_winsys *iws = is->iws;
@@ -815,7 +958,10 @@ i915_texture_create(struct pipe_screen *screen,
pipe_reference_init(&tex->b.b.reference, 1);
tex->b.b.screen = screen;
- tex->tiling = i915_texture_tiling(is, tex);
+ if (force_untiled)
+ tex->tiling = I915_TILE_NONE;
+ else
+ tex->tiling = i915_texture_tiling(is, tex);
if (is->is_i945) {
if (!i945_texture_layout(tex))
@@ -836,7 +982,7 @@ i915_texture_create(struct pipe_screen *screen,
buf_usage = I915_NEW_TEXTURE;
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
- &tex->tiling, buf_usage);
+ &tex->tiling, buf_usage);
if (!tex->buffer)
goto fail;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index c86baa58b28..e743f6031eb 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -109,17 +109,17 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_ANISOTROPIC_FILTER:
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_NPOT_TEXTURES:
+ case PIPE_CAP_POINT_SPRITE:
case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
case PIPE_CAP_TEXTURE_SHADOW_MAP:
case PIPE_CAP_TWO_SIDED_STENCIL:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
/* Features that should be supported (boolean caps). */
/* XXX: Just test the code */
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
- /* XXX: No code but hw supports it */
- case PIPE_CAP_POINT_SPRITE:
/* Also lie about these when asked to (needed for GLSL / GL 2.0) */
return is->debug.lie ? 1 : 0;
@@ -129,7 +129,6 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_INDEP_BLEND_FUNC:
case PIPE_CAP_TGSI_INSTANCEID:
- case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_TEXTURE_SWIZZLE:
@@ -254,7 +253,7 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap)
}
}
-static boolean
+boolean
i915_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
@@ -264,7 +263,10 @@ i915_is_format_supported(struct pipe_screen *screen,
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+ PIPE_FORMAT_R8G8B8X8_UNORM,
PIPE_FORMAT_B5G6R5_UNORM,
+ PIPE_FORMAT_B10G10R10A2_UNORM,
PIPE_FORMAT_L8_UNORM,
PIPE_FORMAT_A8_UNORM,
PIPE_FORMAT_I8_UNORM,
@@ -283,7 +285,12 @@ i915_is_format_supported(struct pipe_screen *screen,
};
static const enum pipe_format render_supported[] = {
PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
PIPE_FORMAT_B5G6R5_UNORM,
+ PIPE_FORMAT_B10G10R10A2_UNORM,
+ PIPE_FORMAT_L8_UNORM,
+ PIPE_FORMAT_A8_UNORM,
+ PIPE_FORMAT_I8_UNORM,
PIPE_FORMAT_NONE /* list terminator */
};
static const enum pipe_format depth_supported[] = {
diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h
index cfc585b5350..9f2004eb942 100644
--- a/src/gallium/drivers/i915/i915_screen.h
+++ b/src/gallium/drivers/i915/i915_screen.h
@@ -65,5 +65,11 @@ i915_screen(struct pipe_screen *pscreen)
return (struct i915_screen *) pscreen;
}
+boolean
+i915_is_format_supported(struct pipe_screen *screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned tex_usage);
#endif /* I915_SCREEN_H */
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 1b57c5776f2..f412626955d 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -146,6 +146,7 @@ i915_create_blend_state(struct pipe_context *pipe,
if (blend->dither)
cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE;
+ /* XXX here take the target fixup into account */
if ((blend->rt[0].colormask & PIPE_MASK_R) == 0)
cso_data->LIS5 |= S5_WRITEDISABLE_RED;
@@ -246,7 +247,7 @@ i915_create_sampler_state(struct pipe_context *pipe,
if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
{
cso->state[0] |= (SS2_SHADOW_ENABLE |
- i915_translate_compare_func(sampler->compare_func));
+ i915_translate_shadow_compare_func(sampler->compare_func));
minFilt = FILTER_4X4_FLAT;
magFilt = FILTER_4X4_FLAT;
@@ -466,6 +467,7 @@ i915_create_fs_state(struct pipe_context *pipe,
if (!ifs)
return NULL;
+ ifs->draw_data = draw_create_fragment_shader(i915->draw, templ);
ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
tgsi_scan_shader(templ->tokens, &ifs->info);
@@ -495,6 +497,8 @@ i915_bind_fs_state(struct pipe_context *pipe, void *shader)
i915->fs = (struct i915_fragment_shader*) shader;
+ draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL));
+
i915->dirty |= I915_NEW_FS;
}
@@ -503,12 +507,14 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
{
struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader;
- if (ifs->program)
+ if (ifs->program) {
FREE(ifs->program);
+ ifs->program = NULL;
+ FREE((struct tgsi_token *)ifs->state.tokens);
+ ifs->state.tokens = NULL;
+ }
ifs->program_len = 0;
- FREE((struct tgsi_token *)ifs->state.tokens);
-
FREE(ifs);
}
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index bf6b30a4530..e01f16e715c 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -33,9 +33,10 @@
#include "i915_context.h"
#include "i915_state.h"
#include "i915_debug.h"
+#include "i915_fpc.h"
#include "i915_reg.h"
-static uint find_mapping(struct i915_fragment_shader* fs, int unit)
+static uint find_mapping(const struct i915_fragment_shader* fs, int unit)
{
int i;
for (i = 0; i < I915_TEX_UNITS ; i++)
@@ -58,12 +59,12 @@ static void calculate_vertex_layout(struct i915_context *i915)
const struct i915_fragment_shader *fs = i915->fs;
const enum interp_mode colorInterp = i915->rasterizer->color_interp;
struct vertex_info vinfo;
- boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW;
+ boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW, face;
uint i;
int src;
memset(texCoords, 0, sizeof(texCoords));
- colors[0] = colors[1] = fog = needW = FALSE;
+ colors[0] = colors[1] = fog = needW = face = FALSE;
memset(&vinfo, 0, sizeof(vinfo));
/* Determine which fragment program inputs are needed. Setup HW vertex
@@ -72,6 +73,10 @@ static void calculate_vertex_layout(struct i915_context *i915)
for (i = 0; i < fs->info.num_inputs; i++) {
switch (fs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
+ {
+ uint unit = I915_SEMANTIC_POS;
+ texCoords[find_mapping(fs, unit)] = TRUE;
+ }
break;
case TGSI_SEMANTIC_COLOR:
assert(fs->info.input_semantic_index[i] < 2);
@@ -80,7 +85,6 @@ static void calculate_vertex_layout(struct i915_context *i915)
case TGSI_SEMANTIC_GENERIC:
{
/* texcoords/varyings/other generic */
- /* XXX handle back/front face and point size */
uint unit = fs->info.input_semantic_index[i];
texCoords[find_mapping(fs, unit)] = TRUE;
@@ -90,7 +94,11 @@ static void calculate_vertex_layout(struct i915_context *i915)
case TGSI_SEMANTIC_FOG:
fog = TRUE;
break;
+ case TGSI_SEMANTIC_FACE:
+ face = TRUE;
+ break;
default:
+ debug_printf("Unknown input type %d\n", fs->info.input_semantic_name[i]);
assert(0);
}
}
@@ -147,6 +155,20 @@ static void calculate_vertex_layout(struct i915_context *i915)
vinfo.hwfmt[1] |= hwtc << (i * 4);
}
+ /* front/back face */
+ if (face) {
+ uint slot = find_mapping(fs, I915_SEMANTIC_FACE);
+ debug_printf("Front/back face is broken\n");
+ /* XXX Because of limitations in the draw module, currently src will be 0
+ * for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw
+ * module by adding an extra shader output.
+ */
+ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0);
+ draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_CONSTANT, src);
+ vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4));
+ vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4);
+ }
+
draw_compute_vertex_size(&vinfo);
if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 0155cd83510..39fb13aec7e 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -34,7 +34,9 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "pipe/p_format.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -128,7 +130,7 @@ validate_immediate(struct i915_context *i915, unsigned *batch_space)
static void
emit_immediate(struct i915_context *i915)
{
- /* remove unwatned bits and S7 */
+ /* remove unwanted bits and S7 */
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 |
@@ -341,6 +343,59 @@ emit_constants(struct i915_context *i915)
}
}
+static const struct
+{
+ enum pipe_format format;
+ uint hw_shift_R;
+ uint hw_shift_G;
+ uint hw_shift_B;
+ uint hw_shift_A;
+} fixup_formats[] = {
+ { PIPE_FORMAT_R8G8B8A8_UNORM, 20, 24, 28, 16 /* BGRA */},
+ { PIPE_FORMAT_L8_UNORM, 28, 28, 28, 16 /* RRRA */},
+ { PIPE_FORMAT_I8_UNORM, 28, 28, 28, 16 /* RRRA */},
+ { PIPE_FORMAT_A8_UNORM, 16, 16, 16, 16 /* AAAA */},
+ { PIPE_FORMAT_NONE, 0, 0, 0, 0},
+};
+
+static boolean need_fixup(struct pipe_surface* p)
+{
+ enum pipe_format f;
+
+ /* if we don't have a surface bound yet, we don't need to fixup the shader */
+ if (!p)
+ return FALSE;
+
+ f = p->format;
+ for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
+ if (fixup_formats[i].format == f)
+ return TRUE;
+
+ return FALSE;
+}
+
+static uint fixup_swizzle(enum pipe_format f, uint v)
+{
+ int i;
+
+ for(i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
+ if (fixup_formats[i].format == f)
+ break;
+
+ if (fixup_formats[i].format == PIPE_FORMAT_NONE)
+ return v;
+
+ uint rgba = v & 0xFFFF0000;
+
+ v &= 0xFFFF;
+ v |= ((rgba >> fixup_formats[i].hw_shift_R) & 0xF) << 28;
+ v |= ((rgba >> fixup_formats[i].hw_shift_G) & 0xF) << 24;
+ v |= ((rgba >> fixup_formats[i].hw_shift_B) & 0xF) << 20;
+ v |= ((rgba >> fixup_formats[i].hw_shift_A) & 0xF) << 16;
+
+ return v;
+}
+
static void
validate_program(struct i915_context *i915, unsigned *batch_space)
{
@@ -350,12 +405,39 @@ validate_program(struct i915_context *i915, unsigned *batch_space)
static void
emit_program(struct i915_context *i915)
{
- uint i;
- /* we should always have, at least, a pass-through program */
- assert(i915->fs->program_len > 0);
- for (i = 0; i < i915->fs->program_len; i++) {
- OUT_BATCH(i915->fs->program[i]);
+ struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+ boolean need_format_fixup = need_fixup(cbuf_surface);
+ int i;
+ int fixup_offset = -1;
+
+ /* we should always have, at least, a pass-through program */
+ assert(i915->fs->program_len > 0);
+
+ if (need_format_fixup) {
+ /* Find where we emit the output color */
+ for (i = i915->fs->program_len - 3; i>0; i-=3) {
+ uint instr = i915->fs->program[i];
+ if ((instr & (REG_NR_MASK << A0_DEST_TYPE_SHIFT)) ==
+ (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) ) {
+ /* Found it! */
+ fixup_offset = i + 1;
+ break;
+ }
+ }
+ if (fixup_offset == -1) {
+ need_format_fixup = FALSE;
+ debug_printf("couldn't find fixup offset\n");
}
+ }
+
+ /* emit the program to the hw */
+ for (i = 0; i < i915->fs->program_len; i++) {
+ if (need_format_fixup && (i == fixup_offset) ) {
+ uint v = fixup_swizzle(cbuf_surface->format, i915->fs->program[i]);
+ OUT_BATCH(v);
+ } else
+ OUT_BATCH(i915->fs->program[i]);
+ }
}
static void
diff --git a/src/gallium/drivers/i915/i915_state_inlines.h b/src/gallium/drivers/i915/i915_state_inlines.h
index b589117fbfe..aa992f75c51 100644
--- a/src/gallium/drivers/i915/i915_state_inlines.h
+++ b/src/gallium/drivers/i915/i915_state_inlines.h
@@ -60,6 +60,31 @@ i915_translate_compare_func(unsigned func)
}
static INLINE unsigned
+i915_translate_shadow_compare_func(unsigned func)
+{
+ switch (func) {
+ case PIPE_FUNC_NEVER:
+ return COMPAREFUNC_ALWAYS;
+ case PIPE_FUNC_LESS:
+ return COMPAREFUNC_LEQUAL;
+ case PIPE_FUNC_LEQUAL:
+ return COMPAREFUNC_LESS;
+ case PIPE_FUNC_GREATER:
+ return COMPAREFUNC_GEQUAL;
+ case PIPE_FUNC_GEQUAL:
+ return COMPAREFUNC_GREATER;
+ case PIPE_FUNC_NOTEQUAL:
+ return COMPAREFUNC_EQUAL;
+ case PIPE_FUNC_EQUAL:
+ return COMPAREFUNC_NOTEQUAL;
+ case PIPE_FUNC_ALWAYS:
+ return COMPAREFUNC_NEVER;
+ default:
+ return COMPAREFUNC_NEVER;
+ }
+}
+
+static INLINE unsigned
i915_translate_stencil_op(unsigned op)
{
switch (op) {
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index be70e7a92c9..0103f7c3530 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -62,6 +62,7 @@ static void update_map(struct i915_context *i915,
uint unit,
const struct i915_texture *tex,
const struct i915_sampler_state *sampler,
+ const struct pipe_sampler_view* view,
uint state[2]);
@@ -161,9 +162,10 @@ static void update_samplers(struct i915_context *i915)
i915->current.sampler[unit]); /* the result */
update_map(i915,
unit,
- texture, /* texture */
- i915->sampler[unit], /* sampler state */
- i915->current.texbuffer[unit]); /* the result */
+ texture, /* texture */
+ i915->sampler[unit], /* sampler state */
+ i915->fragment_sampler_views[unit], /* sampler view */
+ i915->current.texbuffer[unit]); /* the result */
i915->current.sampler_enable_nr++;
i915->current.sampler_enable_flags |= (1 << unit);
@@ -180,13 +182,21 @@ struct i915_tracked_state i915_hw_samplers = {
};
-
/***********************************************************************
* Sampler views
*/
-static uint translate_texture_format(enum pipe_format pipeFormat)
+static uint translate_texture_format(enum pipe_format pipeFormat,
+ const struct pipe_sampler_view* view)
{
+ if ( (view->swizzle_r != PIPE_SWIZZLE_RED ||
+ view->swizzle_g != PIPE_SWIZZLE_GREEN ||
+ view->swizzle_b != PIPE_SWIZZLE_BLUE ||
+ view->swizzle_a != PIPE_SWIZZLE_ALPHA ) &&
+ pipeFormat != PIPE_FORMAT_Z24_UNORM_S8_USCALED &&
+ pipeFormat != PIPE_FORMAT_Z24X8_UNORM )
+ debug_printf("i915: unsupported texture swizzle for format %d\n", pipeFormat);
+
switch (pipeFormat) {
case PIPE_FORMAT_L8_UNORM:
return MAPSURF_8BIT | MT_8BIT_L8;
@@ -202,16 +212,16 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
return MAPSURF_16BIT | MT_16BIT_ARGB1555;
case PIPE_FORMAT_B4G4R4A4_UNORM:
return MAPSURF_16BIT | MT_16BIT_ARGB4444;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_ARGB2101010;
case PIPE_FORMAT_B8G8R8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ARGB8888;
case PIPE_FORMAT_B8G8R8X8_UNORM:
return MAPSURF_32BIT | MT_32BIT_XRGB8888;
case PIPE_FORMAT_R8G8B8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ABGR8888;
-#if 0
case PIPE_FORMAT_R8G8B8X8_UNORM:
return MAPSURF_32BIT | MT_32BIT_XBGR8888;
-#endif
case PIPE_FORMAT_YUYV:
return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case PIPE_FORMAT_UYVY:
@@ -232,7 +242,25 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
case PIPE_FORMAT_Z24X8_UNORM:
- return (MAPSURF_32BIT | MT_32BIT_xI824);
+ {
+ if ( view->swizzle_r == PIPE_SWIZZLE_RED &&
+ view->swizzle_g == PIPE_SWIZZLE_RED &&
+ view->swizzle_b == PIPE_SWIZZLE_RED &&
+ view->swizzle_a == PIPE_SWIZZLE_ONE)
+ return (MAPSURF_32BIT | MT_32BIT_xA824);
+ if ( view->swizzle_r == PIPE_SWIZZLE_RED &&
+ view->swizzle_g == PIPE_SWIZZLE_RED &&
+ view->swizzle_b == PIPE_SWIZZLE_RED &&
+ view->swizzle_a == PIPE_SWIZZLE_RED)
+ return (MAPSURF_32BIT | MT_32BIT_xI824);
+ if ( view->swizzle_r == PIPE_SWIZZLE_ZERO &&
+ view->swizzle_g == PIPE_SWIZZLE_ZERO &&
+ view->swizzle_b == PIPE_SWIZZLE_ZERO &&
+ view->swizzle_a == PIPE_SWIZZLE_RED)
+ return (MAPSURF_32BIT | MT_32BIT_xL824);
+ debug_printf("i915: unsupported depth swizzle\n");
+ return (MAPSURF_32BIT | MT_32BIT_xL824);
+ }
default:
debug_printf("i915: translate_texture_format() bad image format %x\n",
pipeFormat);
@@ -262,6 +290,7 @@ static void update_map(struct i915_context *i915,
uint unit,
const struct i915_texture *tex,
const struct i915_sampler_state *sampler,
+ const struct pipe_sampler_view* view,
uint state[2])
{
const struct pipe_resource *pt = &tex->b.b;
@@ -275,7 +304,7 @@ static void update_map(struct i915_context *i915,
assert(height);
assert(depth);
- format = translate_texture_format(pt->format);
+ format = translate_texture_format(pt->format, view);
pitch = tex->stride;
assert(format);
@@ -318,8 +347,9 @@ static void update_maps(struct i915_context *i915)
update_map(i915,
unit,
- texture, /* texture */
- i915->sampler[unit], /* sampler state */
+ texture, /* texture */
+ i915->sampler[unit], /* sampler state */
+ i915->fragment_sampler_views[unit], /* sampler view */
i915->current.texbuffer[unit]);
}
}
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
index 2865298318c..0e4000bc2ab 100644
--- a/src/gallium/drivers/i915/i915_state_static.c
+++ b/src/gallium/drivers/i915/i915_state_static.c
@@ -42,6 +42,18 @@ static unsigned translate_format(enum pipe_format format)
return COLOR_BUF_ARGB8888;
case PIPE_FORMAT_B5G6R5_UNORM:
return COLOR_BUF_RGB565;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ return COLOR_BUF_ARGB1555;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return COLOR_BUF_ARGB8888;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ return COLOR_BUF_ARGB4444;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ return COLOR_BUF_ARGB2101010;
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ return COLOR_BUF_8BIT;
default:
assert(0);
return 0;
@@ -137,7 +149,8 @@ static void update_framebuffer(struct i915_context *i915)
i915->static_dirty |= I915_DST_RECT;
}
- i915->hardware_dirty |= I915_HW_STATIC;
+ /* we also send a new program to make sure the fixup for RGBA surfaces happens */
+ i915->hardware_dirty |= I915_HW_STATIC | I915_HW_PROGRAM;
/* flush the cache in case we sample from the old renderbuffers */
i915_set_flush_dirty(i915, I915_FLUSH_CACHE);