summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStéphane Marchesin <[email protected]>2011-10-08 23:54:53 -0700
committerStéphane Marchesin <[email protected]>2011-10-08 23:54:53 -0700
commit8a22064d316efcdc0d0107fe227a2ed5a746c4f8 (patch)
tree75781f971736cb5ba4d7a024c8bfd41037f5e26d /src
parente125786be8e19a9606afb91cd7e8bc37d035b63f (diff)
i915g: Implement vertex textures.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/i915/i915_context.c8
-rw-r--r--src/gallium/drivers/i915/i915_context.h17
-rw-r--r--src/gallium/drivers/i915/i915_screen.c129
-rw-r--r--src/gallium/drivers/i915/i915_state.c138
4 files changed, 230 insertions, 62 deletions
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 1b30309bb58..ff6d715b72a 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -79,6 +79,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
else
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
+ if (i915->num_vertex_sampler_views > 0)
+ i915_prepare_vertex_sampling(i915,
+ i915->num_vertex_sampler_views,
+ i915->vertex_sampler_views);
+
/*
* Do the drawing
*/
@@ -86,6 +91,9 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (mapped_indices)
draw_set_mapped_index_buffer(draw, NULL);
+
+ if (i915->num_vertex_sampler_views > 0)
+ i915_cleanup_vertex_sampling(i915);
}
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index dacd0a669c1..7f67f5f1340 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -225,6 +225,7 @@ struct i915_context {
*/
const struct i915_blend_state *blend;
const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
const struct i915_depth_stencil_state *depth_stencil;
const struct i915_rasterizer_state *rasterizer;
@@ -238,13 +239,19 @@ struct i915_context {
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_index_buffer index_buffer;
unsigned dirty;
+ struct pipe_resource *mapped_vs_tex[PIPE_MAX_VERTEX_SAMPLERS];
+ struct i915_winsys_buffer* mapped_vs_tex_buffer[PIPE_MAX_VERTEX_SAMPLERS];
+
unsigned num_samplers;
unsigned num_fragment_sampler_views;
+ unsigned num_vertex_samplers;
+ unsigned num_vertex_sampler_views;
struct i915_winsys_batchbuffer *batch;
@@ -361,6 +368,16 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 );
/***********************************************************************
+ * i915_state.c:
+ */
+void i915_prepare_vertex_sampling(struct i915_context *i915,
+ unsigned num,
+ struct pipe_sampler_view **views);
+void i915_cleanup_vertex_sampling(struct i915_context *i915);
+
+
+
+/***********************************************************************
* i915_state_emit.c:
*/
void i915_emit_hardware_state(struct i915_context *i915 );
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index cc818351577..7d9b8653ea6 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -100,6 +100,69 @@ i915_get_name(struct pipe_screen *screen)
}
static int
+i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap)
+{
+ switch(shader) {
+ case PIPE_SHADER_VERTEX:
+ switch (cap) {
+ case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
+ if (debug_get_bool_option("DRAW_USE_LLVM", TRUE))
+ return PIPE_MAX_VERTEX_SAMPLERS;
+ else
+ return 0;
+ default:
+ return draw_get_shader_param(shader, cap);
+ }
+ case PIPE_SHADER_FRAGMENT:
+ /* XXX: these are just shader model 2.0 values, fix this! */
+ switch(cap) {
+ case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
+ return 96;
+ case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
+ return 64;
+ case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
+ return 32;
+ case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
+ return 8;
+ case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
+ return 0;
+ case PIPE_SHADER_CAP_MAX_INPUTS:
+ return 10;
+ case PIPE_SHADER_CAP_MAX_CONSTS:
+ return 32;
+ case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
+ return 1;
+ case PIPE_SHADER_CAP_MAX_TEMPS:
+ return 12; /* XXX: 12 -> 32 ? */
+ case PIPE_SHADER_CAP_MAX_ADDRS:
+ return 0;
+ case PIPE_SHADER_CAP_MAX_PREDS:
+ return 0;
+ case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
+ return 0;
+ case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
+ case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
+ return 1;
+ case PIPE_SHADER_CAP_SUBROUTINES:
+ return 0;
+ case PIPE_SHADER_CAP_INTEGERS:
+ return 0;
+ case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
+ return 8;
+ default:
+ debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
+ return 0;
+ }
+ break;
+ default:
+ return 0;
+ }
+
+}
+
+static int
i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
{
struct i915_screen *is = i915_screen(screen);
@@ -143,7 +206,12 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
/* Texturing. */
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
- return 8;
+ return i915_get_shader_param(screen,
+ PIPE_SHADER_VERTEX,
+ PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS) +
+ i915_get_shader_param(screen,
+ PIPE_SHADER_FRAGMENT,
+ PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS);
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -172,65 +240,6 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
}
}
-static int
-i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap)
-{
- switch(shader) {
- case PIPE_SHADER_VERTEX:
- switch (cap) {
- case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
- return 0;
- default:
- return draw_get_shader_param(shader, cap);
- }
- case PIPE_SHADER_FRAGMENT:
- /* XXX: these are just shader model 2.0 values, fix this! */
- switch(cap) {
- case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
- return 96;
- case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
- return 64;
- case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
- return 32;
- case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
- return 8;
- case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
- return 0;
- case PIPE_SHADER_CAP_MAX_INPUTS:
- return 10;
- case PIPE_SHADER_CAP_MAX_CONSTS:
- return 32;
- case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
- return 1;
- case PIPE_SHADER_CAP_MAX_TEMPS:
- return 12; /* XXX: 12 -> 32 ? */
- case PIPE_SHADER_CAP_MAX_ADDRS:
- return 0;
- case PIPE_SHADER_CAP_MAX_PREDS:
- return 0;
- case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
- return 0;
- case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
- case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
- case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
- case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
- return 1;
- case PIPE_SHADER_CAP_SUBROUTINES:
- return 0;
- case PIPE_SHADER_CAP_INTEGERS:
- return 0;
- case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
- return 8;
- default:
- debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
- return 0;
- }
- default:
- return 0;
- }
-
-}
-
static float
i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap)
{
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 345c109a995..f6e531062fe 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -299,7 +299,38 @@ static void i915_fixup_bind_sampler_states(struct pipe_context *pipe,
i915->saved_bind_sampler_states(pipe, num, sampler);
}
-static void i915_bind_sampler_states(struct pipe_context *pipe,
+static void
+i915_bind_vertex_sampler_states(struct pipe_context *pipe,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ unsigned i;
+
+ assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
+
+ /* Check for no-op */
+ if (num_samplers == i915->num_vertex_samplers &&
+ !memcmp(i915->vertex_samplers, samplers, num_samplers * sizeof(void *)))
+ return;
+
+ draw_flush(i915->draw);
+
+ for (i = 0; i < num_samplers; ++i)
+ i915->vertex_samplers[i] = samplers[i];
+ for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+ i915->vertex_samplers[i] = NULL;
+
+ i915->num_vertex_samplers = num_samplers;
+
+ draw_set_samplers(i915->draw,
+ i915->vertex_samplers,
+ i915->num_vertex_samplers);
+}
+
+
+
+static void i915_bind_fragment_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct i915_context *i915 = i915_context(pipe);
@@ -329,6 +360,76 @@ static void i915_delete_sampler_state(struct pipe_context *pipe,
}
+/**
+ * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
+ */
+void
+i915_prepare_vertex_sampling(struct i915_context *i915,
+ unsigned num,
+ struct pipe_sampler_view **views)
+{
+ struct i915_winsys *iws = i915->iws;
+ unsigned i,j;
+ uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
+ uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
+ const void* data[PIPE_MAX_TEXTURE_LEVELS];
+
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+ if (!num)
+ return;
+
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+ if (view) {
+ struct pipe_resource *tex = view->texture;
+ struct i915_texture *i915_tex = i915_texture(tex);
+ void* addr;
+
+ /* We're referencing the texture's internal data, so save a
+ * reference to it.
+ */
+ pipe_resource_reference(&i915->mapped_vs_tex[i], tex);
+
+ i915->mapped_vs_tex_buffer[i] = i915_tex->buffer;
+ addr = iws->buffer_map(iws,
+ i915_tex->buffer,
+ FALSE /* read only */);
+
+ /* Setup array of mipmap level pointers */
+ /* FIXME: handle 3D textures? */
+ for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
+ unsigned offset = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */);
+ data[j] = addr + offset;
+ row_stride[j] = i915_tex->stride;
+ img_stride[j] = 0; /* FIXME */;
+ }
+
+ draw_set_mapped_texture(i915->draw,
+ i,
+ tex->width0, tex->height0, tex->depth0,
+ view->u.tex.first_level, tex->last_level,
+ row_stride, img_stride, data);
+ } else
+ i915->mapped_vs_tex[i] = NULL;
+ }
+}
+
+void
+i915_cleanup_vertex_sampling(struct i915_context *i915)
+{
+ struct i915_winsys *iws = i915->iws;
+ unsigned i;
+ for (i = 0; i < Elements(i915->mapped_vs_tex); i++) {
+ if (i915->mapped_vs_tex_buffer[i]) {
+ iws->buffer_unmap(iws, i915->mapped_vs_tex_buffer[i]);
+ pipe_resource_reference(&i915->mapped_vs_tex[i], NULL);
+ }
+ }
+}
+
+
+
/** XXX move someday? Or consolidate all these simple state setters
* into one file.
*/
@@ -652,6 +753,37 @@ static void i915_set_fragment_sampler_views(struct pipe_context *pipe,
i915->dirty |= I915_NEW_SAMPLER_VIEW;
}
+static void
+i915_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ uint i;
+
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+
+ /* Check for no-op */
+ if (num == i915->num_vertex_sampler_views &&
+ !memcmp(i915->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
+ return;
+ }
+
+ draw_flush(i915->draw);
+
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+ pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view);
+ }
+
+ i915->num_vertex_sampler_views = num;
+
+ draw_set_sampler_views(i915->draw,
+ i915->vertex_sampler_views,
+ i915->num_vertex_sampler_views);
+}
+
static struct pipe_sampler_view *
i915_create_sampler_view(struct pipe_context *pipe,
@@ -918,7 +1050,8 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.delete_blend_state = i915_delete_blend_state;
i915->base.create_sampler_state = i915_create_sampler_state;
- i915->base.bind_fragment_sampler_states = i915_bind_sampler_states;
+ i915->base.bind_fragment_sampler_states = i915_bind_fragment_sampler_states;
+ i915->base.bind_vertex_sampler_states = i915_bind_vertex_sampler_states;
i915->base.delete_sampler_state = i915_delete_sampler_state;
i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
@@ -948,6 +1081,7 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_polygon_stipple = i915_set_polygon_stipple;
i915->base.set_scissor_state = i915_set_scissor_state;
i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views;
+ i915->base.set_vertex_sampler_views = i915_set_vertex_sampler_views;
i915->base.create_sampler_view = i915_create_sampler_view;
i915->base.sampler_view_destroy = i915_sampler_view_destroy;
i915->base.set_viewport_state = i915_set_viewport_state;