summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/softpipe
diff options
context:
space:
mode:
authorChristian König <[email protected]>2010-10-12 23:05:25 +0200
committerChristian König <[email protected]>2010-10-12 23:07:29 +0200
commit695cc370a280a637f411f5ff3877b3fd1c05e424 (patch)
tree69ae2a8fbecfa553faba59274688ffe11ee1a612 /src/gallium/drivers/softpipe
parentf3e34ba6fba76870b1c91a27adb706d1b87aeec8 (diff)
parent48156b87bc9d3e09ec34372d69504a787332ea0b (diff)
Merge branch 'master' of ssh://git.freedesktop.org/git/mesa/mesa into pipe-video
Conflicts: configure.ac src/gallium/drivers/nvfx/Makefile src/gallium/include/pipe/p_defines.h src/gallium/include/pipe/p_screen.h src/gallium/include/state_tracker/dri1_api.h src/gallium/include/state_tracker/drm_api.h src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r--src/gallium/drivers/softpipe/Makefile3
-rw-r--r--src/gallium/drivers/softpipe/SConscript3
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c95
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h22
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c207
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c329
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c201
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c44
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c39
-rw-r--r--src/gallium/drivers/softpipe/sp_query.c84
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c47
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c52
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h143
-rw-r--r--src/gallium/drivers/softpipe/sp_state_blend.c64
-rw-r--r--src/gallium/drivers/softpipe/sp_state_clip.c30
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c13
-rw-r--r--src/gallium/drivers/softpipe/sp_state_rasterizer.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c127
-rw-r--r--src/gallium/drivers/softpipe/sp_state_shader.c (renamed from src/gallium/drivers/softpipe/sp_state_fs.c)118
-rw-r--r--src/gallium/drivers/softpipe/sp_state_so.c140
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c38
-rw-r--r--src/gallium/drivers/softpipe/sp_surface.c20
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c18
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c60
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c179
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h9
29 files changed, 1344 insertions, 776 deletions
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index 3111c49a2c2..8876bd16398 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -23,8 +23,9 @@ C_SOURCES = \
sp_state_blend.c \
sp_state_clip.c \
sp_state_derived.c \
- sp_state_fs.c \
sp_state_sampler.c \
+ sp_state_shader.c \
+ sp_state_so.c \
sp_state_rasterizer.c \
sp_state_surface.c \
sp_state_vertex.c \
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index c51f449c638..dea7f885e0d 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -24,9 +24,10 @@ softpipe = env.ConvenienceLibrary(
'sp_state_blend.c',
'sp_state_clip.c',
'sp_state_derived.c',
- 'sp_state_fs.c',
'sp_state_rasterizer.c',
'sp_state_sampler.c',
+ 'sp_state_shader.c',
+ 'sp_state_so.c',
'sp_state_surface.c',
'sp_state_vertex.c',
'sp_surface.c',
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index f6e2b80d46e..b5d30bc6fc9 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -36,6 +36,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "tgsi/tgsi_exec.h"
#include "sp_clear.h"
#include "sp_context.h"
#include "sp_flush.h"
@@ -113,6 +114,11 @@ softpipe_destroy( struct pipe_context *pipe )
pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL);
}
+ for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+ sp_destroy_tex_tile_cache(softpipe->geometry_tex_cache[i]);
+ pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], NULL);
+ }
+
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
uint j;
@@ -123,6 +129,8 @@ softpipe_destroy( struct pipe_context *pipe )
}
}
+ tgsi_exec_machine_destroy(softpipe->fs_machine);
+
FREE( softpipe );
}
@@ -171,7 +179,12 @@ softpipe_is_resource_referenced( struct pipe_context *pipe,
softpipe->vertex_tex_cache[i]->texture == texture)
return PIPE_REFERENCED_FOR_READ;
}
-
+ for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+ if (softpipe->geometry_tex_cache[i] &&
+ softpipe->geometry_tex_cache[i]->texture == texture)
+ return PIPE_REFERENCED_FOR_READ;
+ }
+
return PIPE_UNREFERENCED;
}
@@ -215,68 +228,26 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.priv = priv;
/* state setters */
- softpipe->pipe.create_blend_state = softpipe_create_blend_state;
- softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
- softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
-
- softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
- softpipe->pipe.bind_fragment_sampler_states = softpipe_bind_sampler_states;
- softpipe->pipe.bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states;
- softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
-
- softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
- softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
- softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
-
- softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
- softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
- softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
-
- softpipe->pipe.create_fs_state = softpipe_create_fs_state;
- softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
- softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
-
- softpipe->pipe.create_vs_state = softpipe_create_vs_state;
- softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
- softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
-
- softpipe->pipe.create_gs_state = softpipe_create_gs_state;
- softpipe->pipe.bind_gs_state = softpipe_bind_gs_state;
- softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
-
- softpipe->pipe.create_vertex_elements_state = softpipe_create_vertex_elements_state;
- softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
- softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
-
- softpipe->pipe.set_blend_color = softpipe_set_blend_color;
- softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
- softpipe->pipe.set_clip_state = softpipe_set_clip_state;
- softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
+ softpipe_init_blend_funcs(&softpipe->pipe);
+ softpipe_init_clip_funcs(&softpipe->pipe);
+ softpipe_init_query_funcs( softpipe );
+ softpipe_init_rasterizer_funcs(&softpipe->pipe);
+ softpipe_init_sampler_funcs(&softpipe->pipe);
+ softpipe_init_shader_funcs(&softpipe->pipe);
+ softpipe_init_streamout_funcs(&softpipe->pipe);
+ softpipe_init_texture_funcs( &softpipe->pipe );
+ softpipe_init_vertex_funcs(&softpipe->pipe);
+
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
- softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
- softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
- softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views;
- softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views;
- softpipe->pipe.create_sampler_view = softpipe_create_sampler_view;
- softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy;
- softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
-
- softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
-
- softpipe->pipe.draw_arrays = softpipe_draw_arrays;
- softpipe->pipe.draw_elements = softpipe_draw_elements;
- softpipe->pipe.draw_range_elements = softpipe_draw_range_elements;
- softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced;
- softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced;
+
+ softpipe->pipe.draw_vbo = softpipe_draw_vbo;
+ softpipe->pipe.draw_stream_output = softpipe_draw_stream_output;
softpipe->pipe.clear = softpipe_clear;
softpipe->pipe.flush = softpipe_flush;
softpipe->pipe.is_resource_referenced = softpipe_is_resource_referenced;
- softpipe_init_query_funcs( softpipe );
- softpipe_init_texture_funcs( &softpipe->pipe );
-
softpipe->pipe.render_condition = softpipe_render_condition;
/*
@@ -292,6 +263,11 @@ softpipe_create_context( struct pipe_screen *screen,
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
}
+ for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+ softpipe->geometry_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
+ }
+
+ softpipe->fs_machine = tgsi_exec_machine_create();
/* setup quad rendering stages */
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
@@ -308,10 +284,17 @@ softpipe_create_context( struct pipe_screen *screen,
goto fail;
draw_texture_samplers(softpipe->draw,
+ PIPE_SHADER_VERTEX,
PIPE_MAX_VERTEX_SAMPLERS,
(struct tgsi_sampler **)
softpipe->tgsi.vert_samplers_list);
+ draw_texture_samplers(softpipe->draw,
+ PIPE_SHADER_GEOMETRY,
+ PIPE_MAX_GEOMETRY_SAMPLERS,
+ (struct tgsi_sampler **)
+ softpipe->tgsi.geom_samplers_list);
+
if (debug_get_bool_option( "SP_NO_RAST", FALSE ))
softpipe->no_rast = TRUE;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 92607874b60..9361a3df09e 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -50,6 +50,7 @@ struct softpipe_tex_tile_cache;
struct sp_fragment_shader;
struct sp_vertex_shader;
struct sp_velems_state;
+struct sp_so_state;
struct softpipe_context {
@@ -59,12 +60,14 @@ struct softpipe_context {
struct pipe_blend_state *blend;
struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_state *geometry_samplers[PIPE_MAX_GEOMETRY_SAMPLERS];
struct pipe_depth_stencil_alpha_state *depth_stencil;
struct pipe_rasterizer_state *rasterizer;
struct sp_fragment_shader *fs;
struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs;
struct sp_velems_state *velems;
+ struct sp_so_state *so;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -76,13 +79,24 @@ struct softpipe_context {
struct pipe_scissor_state scissor;
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer index_buffer;
+ struct {
+ struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
+ int offset[PIPE_MAX_SO_BUFFERS];
+ int so_count[PIPE_MAX_SO_BUFFERS];
+ int num_buffers;
+ } so_target;
+ struct pipe_query_data_so_statistics so_stats;
unsigned num_samplers;
unsigned num_sampler_views;
unsigned num_vertex_samplers;
unsigned num_vertex_sampler_views;
+ unsigned num_geometry_samplers;
+ unsigned num_geometry_sampler_views;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of SP_NEW_x flags */
@@ -98,6 +112,7 @@ struct softpipe_context {
/** Mapped constant buffers */
const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
+ unsigned const_buffer_size[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
/** Vertex format */
struct vertex_info vertex_info;
@@ -109,6 +124,9 @@ struct softpipe_context {
/** The reduced version of the primitive supplied by the state tracker */
unsigned reduced_api_prim;
+ /** Derived information about which winding orders to cull */
+ unsigned cull_mode;
+
/**
* The reduced primitive after unfilled triangles, wide-line decomposition,
* etc, are taken into account. This is the primitive type that's actually
@@ -136,10 +154,13 @@ struct softpipe_context {
/** TGSI exec things */
struct {
+ struct sp_sampler_varient *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS];
struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS];
struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS];
} tgsi;
+ struct tgsi_exec_machine *fs_machine;
+
/** The primitive drawing context */
struct draw_context *draw;
@@ -155,6 +176,7 @@ struct softpipe_context {
unsigned tex_timestamp;
struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
+ struct softpipe_tex_tile_cache *geometry_tex_cache[PIPE_MAX_GEOMETRY_SAMPLERS];
unsigned use_sse : 1;
unsigned dump_fs : 1;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index b30036e2303..01b4ca985d0 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -47,152 +47,79 @@
+void
+softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode)
+{
+ struct softpipe_context *sp = softpipe_context(pipe);
+ struct draw_context *draw = sp->draw;
+ const unsigned start = 0;
+ const unsigned count = sp->so_target.so_count[0];
+ void *buf = sp->so_target.buffer[0]->data;
+ int offset = sp->so_target.offset[0];
-/**
- * Draw vertex arrays, with optional indexing.
- * Basically, map the vertex buffers (and drawing surfaces), then hand off
- * the drawing to the 'draw' module.
- */
-static void
-softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount);
+ if (!softpipe_check_render_cond(sp) ||
+ sp->so_target.num_buffers != 1)
+ return;
+ sp->reduced_api_prim = u_reduced_prim(mode);
-void
-softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count)
-{
- softpipe_draw_range_elements_instanced(pipe,
- NULL,
- 0,
- 0,
- 0,
- 0xffffffff,
- mode,
- start,
- count,
- 0,
- 1);
-}
+ if (sp->dirty) {
+ softpipe_update_derived(sp);
+ }
+ softpipe_map_transfers(sp);
-void
-softpipe_draw_range_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned min_index,
- unsigned max_index,
- unsigned mode, unsigned start, unsigned count)
-{
- softpipe_draw_range_elements_instanced(pipe,
- indexBuffer,
- indexSize,
- indexBias,
- min_index,
- max_index,
- mode,
- start,
- count,
- 0,
- 1);
-}
+ /* Map so buffers */
+ if (offset < 0) /* we were appending so start from beginning */
+ offset = 0;
+ buf = (void*)((int32_t*)buf + offset);
+ draw_set_mapped_vertex_buffer(draw, 0, buf);
+ draw_set_mapped_index_buffer(draw, NULL);
-void
-softpipe_draw_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize, int indexBias,
- unsigned mode, unsigned start, unsigned count)
-{
- softpipe_draw_range_elements_instanced(pipe,
- indexBuffer,
- indexSize,
- indexBias,
- 0,
- 0xffffffff,
- mode,
- start,
- count,
- 0,
- 1);
-}
+ /* draw! */
+ draw_arrays(draw, mode, start, count);
-void
-softpipe_draw_arrays_instanced(struct pipe_context *pipe,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount)
-{
- softpipe_draw_range_elements_instanced(pipe,
- NULL,
- 0,
- 0,
- 0,
- 0xffffffff,
- mode,
- start,
- count,
- startInstance,
- instanceCount);
-}
+ /* unmap vertex/index buffers - will cause draw module to flush */
+ draw_set_mapped_vertex_buffer(draw, 0, NULL);
-void
-softpipe_draw_elements_instanced(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount)
-{
- softpipe_draw_range_elements_instanced(pipe,
- indexBuffer,
- indexSize,
- indexBias,
- 0,
- 0xffffffff,
- mode,
- start,
- count,
- startInstance,
- instanceCount);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
+
+ /* Note: leave drawing surfaces mapped */
+ sp->dirty_render_cache = TRUE;
}
-static void
-softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount)
+
+/**
+ * This function handles drawing indexed and non-indexed prims,
+ * instanced and non-instanced drawing, with or without min/max element
+ * indexes.
+ * All the other drawing functions are expressed in terms of this
+ * function.
+ *
+ * For non-indexed prims, indexBuffer should be NULL.
+ * For non-instanced drawing, instanceCount should be 1.
+ * When the min/max element indexes aren't known, minIndex should be 0
+ * and maxIndex should be ~0.
+ */
+void
+softpipe_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info)
{
struct softpipe_context *sp = softpipe_context(pipe);
struct draw_context *draw = sp->draw;
+ void *mapped_indices = NULL;
unsigned i;
if (!softpipe_check_render_cond(sp))
return;
- sp->reduced_api_prim = u_reduced_prim(mode);
+ sp->reduced_api_prim = u_reduced_prim(info->mode);
if (sp->dirty) {
softpipe_update_derived(sp);
@@ -207,32 +134,20 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
}
/* Map index buffer, if present */
- if (indexBuffer) {
- void *mapped_indexes = softpipe_resource(indexBuffer)->data;
- draw_set_mapped_element_buffer_range(draw,
- indexSize,
- indexBias,
- minIndex,
- maxIndex,
- mapped_indexes);
- } else {
- /* no index/element buffer */
- draw_set_mapped_element_buffer_range(draw,
- 0, 0,
- start,
- start + count - 1,
- NULL);
- }
+ if (info->indexed && sp->index_buffer.buffer)
+ mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+
+ draw_set_mapped_index_buffer(draw, mapped_indices);
/* draw! */
- draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount);
+ draw_vbo(draw, info);
/* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
- if (indexBuffer) {
- draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+ if (mapped_indices) {
+ draw_set_mapped_index_buffer(draw, NULL);
}
/*
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 5024fc8a819..1071011db0e 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -31,6 +31,7 @@
#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
#include "draw/draw_context.h"
#include "sp_flush.h"
#include "sp_context.h"
@@ -56,6 +57,9 @@ softpipe_flush( struct pipe_context *pipe,
for (i = 0; i < softpipe->num_vertex_sampler_views; i++) {
sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]);
}
+ for (i = 0; i < softpipe->num_geometry_sampler_views; i++) {
+ sp_flush_tex_tile_cache(softpipe->geometry_tex_cache[i]);
+ }
}
if (flags & PIPE_FLUSH_SWAPBUFFERS) {
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index a58bc107c0a..c60249dbfbc 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -158,26 +158,27 @@ static INLINE cptrf4 get_vert( const void *vertex_buffer,
* draw elements / indexed primitives
*/
static void
-sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
+sp_vbuf_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
struct softpipe_context *softpipe = cvbr->softpipe;
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
const void *vertex_buffer = cvbr->vertex_buffer;
- struct setup_context *setup_ctx = cvbr->setup;
+ struct setup_context *setup = cvbr->setup;
+ const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
unsigned i;
switch (cvbr->prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < nr; i++) {
- sp_setup_point( setup_ctx,
+ sp_setup_point( setup,
get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
case PIPE_PRIM_LINES:
for (i = 1; i < nr; i += 2) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
}
@@ -185,7 +186,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
case PIPE_PRIM_LINE_STRIP:
for (i = 1; i < nr; i ++) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
}
@@ -193,48 +194,41 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
case PIPE_PRIM_LINE_LOOP:
for (i = 1; i < nr; i ++) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
}
if (nr) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, indices[nr-1], stride),
get_vert(vertex_buffer, indices[0], stride) );
}
break;
case PIPE_PRIM_TRIANGLES:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 2; i < nr; i += 3) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-2], stride) );
- }
- }
- else {
- for (i = 2; i < nr; i += 3) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ for (i = 2; i < nr; i += 3) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
+ if (flatshade_first) {
for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
+ /* emit first triangle vertex as first triangle vertex */
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
- get_vert(vertex_buffer, indices[i-(i&1)], stride),
- get_vert(vertex_buffer, indices[i-2], stride) );
+ get_vert(vertex_buffer, indices[i-(i&1)], stride) );
+
}
}
else {
for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
+ /* emit last triangle vertex as last triangle vertex */
+ sp_setup_tri( setup,
get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
@@ -243,17 +237,19 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_TRIANGLE_FAN:
- if (softpipe->rasterizer->flatshade_first) {
+ if (flatshade_first) {
for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
+ /* emit first non-spoke vertex as first vertex */
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[0], stride),
- get_vert(vertex_buffer, indices[i-1], stride) );
+ get_vert(vertex_buffer, indices[0], stride) );
}
}
else {
for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
+ /* emit last non-spoke vertex as last vertex */
+ sp_setup_tri( setup,
get_vert(vertex_buffer, indices[0], stride),
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
@@ -262,43 +258,88 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
+ /* GL quads don't follow provoking vertex convention */
+ if (flatshade_first) {
+ /* emit last quad vertex as first triangle vertex */
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride) );
+ }
+ }
+ else {
+ /* emit last quad vertex as last triangle vertex */
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
+ /* GL quad strips don't follow provoking vertex convention */
+ if (flatshade_first) {
+ /* emit last quad vertex as first triangle vertex */
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride) );
+ }
+ }
+ else {
+ /* emit last quad vertex as last triangle vertex */
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
}
break;
case PIPE_PRIM_POLYGON:
/* Almost same as tri fan but the _first_ vertex specifies the flat
- * shading color. Note that the first polygon vertex is passed as
- * the last triangle vertex here.
- * flatshade_first state makes no difference.
+ * shading color.
*/
- for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[0], stride) );
+ if (flatshade_first) {
+ /* emit first polygon vertex as first triangle vertex */
+ for (i = 2; i < nr; i += 1) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[0], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ }
+ else {
+ /* emit first polygon vertex as last triangle vertex */
+ for (i = 2; i < nr; i += 1) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[0], stride) );
+ }
}
break;
@@ -317,23 +358,24 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
struct softpipe_context *softpipe = cvbr->softpipe;
- struct setup_context *setup_ctx = cvbr->setup;
+ struct setup_context *setup = cvbr->setup;
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
const void *vertex_buffer =
(void *) get_vert(cvbr->vertex_buffer, start, stride);
+ const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
unsigned i;
switch (cvbr->prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < nr; i++) {
- sp_setup_point( setup_ctx,
+ sp_setup_point( setup,
get_vert(vertex_buffer, i-0, stride) );
}
break;
case PIPE_PRIM_LINES:
for (i = 1; i < nr; i += 2) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
}
@@ -341,7 +383,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
case PIPE_PRIM_LINE_STRIP:
for (i = 1; i < nr; i ++) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
}
@@ -349,48 +391,40 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
case PIPE_PRIM_LINE_LOOP:
for (i = 1; i < nr; i ++) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
}
if (nr) {
- sp_setup_line( setup_ctx,
+ sp_setup_line( setup,
get_vert(vertex_buffer, nr-1, stride),
get_vert(vertex_buffer, 0, stride) );
}
break;
case PIPE_PRIM_TRIANGLES:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 2; i < nr; i += 3) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-2, stride) );
- }
- }
- else {
- for (i = 2; i < nr; i += 3) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 2; i < nr; i += 3) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
case PIPE_PRIM_TRIANGLE_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
+ if (flatshade_first) {
for (i = 2; i < nr; i++) {
- sp_setup_tri( setup_ctx,
+ /* emit first triangle vertex as first triangle vertex */
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i+(i&1)-1, stride),
- get_vert(vertex_buffer, i-(i&1), stride),
- get_vert(vertex_buffer, i-2, stride) );
+ get_vert(vertex_buffer, i-(i&1), stride) );
}
}
else {
for (i = 2; i < nr; i++) {
- sp_setup_tri( setup_ctx,
+ /* emit last triangle vertex as last triangle vertex */
+ sp_setup_tri( setup,
get_vert(vertex_buffer, i+(i&1)-2, stride),
get_vert(vertex_buffer, i-(i&1)-1, stride),
get_vert(vertex_buffer, i-0, stride) );
@@ -399,17 +433,19 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_TRIANGLE_FAN:
- if (softpipe->rasterizer->flatshade_first) {
+ if (flatshade_first) {
for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
+ /* emit first non-spoke vertex as first vertex */
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, 0, stride),
- get_vert(vertex_buffer, i-1, stride) );
+ get_vert(vertex_buffer, 0, stride) );
}
}
else {
for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
+ /* emit last non-spoke vertex as last vertex */
+ sp_setup_tri( setup,
get_vert(vertex_buffer, 0, stride),
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
@@ -418,42 +454,86 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride) );
+ /* GL quads don't follow provoking vertex convention */
+ if (flatshade_first) {
+ /* emit last quad vertex as first triangle vertex */
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride) );
+ }
+ }
+ else {
+ /* emit last quad vertex as last triangle vertex */
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-0, stride) );
+ /* GL quad strips don't follow provoking vertex convention */
+ if (flatshade_first) {
+ /* emit last quad vertex as first triangle vertex */
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride) );
+ }
+ }
+ else {
+ /* emit last quad vertex as last triangle vertex */
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
}
break;
case PIPE_PRIM_POLYGON:
/* Almost same as tri fan but the _first_ vertex specifies the flat
- * shading color. Note that the first polygon vertex is passed as
- * the last triangle vertex here.
- * flatshade_first state makes no difference.
+ * shading color.
*/
- for (i = 2; i < nr; i += 1) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, 0, stride) );
+ if (flatshade_first) {
+ /* emit first polygon vertex as first triangle vertex */
+ for (i = 2; i < nr; i += 1) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, 0, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ }
+ else {
+ /* emit first polygon vertex as last triangle vertex */
+ for (i = 2; i < nr; i += 1) {
+ sp_setup_tri( setup,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, 0, stride) );
+ }
}
break;
@@ -462,6 +542,22 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
}
}
+static void
+sp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices)
+{
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ struct softpipe_context *softpipe = cvbr->softpipe;
+ unsigned i;
+
+ for (i = 0; i < softpipe->so_target.num_buffers; ++i) {
+ softpipe->so_target.so_count[i] += vertices;
+ }
+
+ softpipe->so_stats.num_primitives_written = primitives;
+ softpipe->so_stats.primitives_storage_needed =
+ vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
+}
+
static void
sp_vbuf_destroy(struct vbuf_render *vbr)
@@ -492,9 +588,10 @@ sp_create_vbuf_backend(struct softpipe_context *sp)
cvbr->base.map_vertices = sp_vbuf_map_vertices;
cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices;
cvbr->base.set_primitive = sp_vbuf_set_primitive;
- cvbr->base.draw = sp_vbuf_draw;
+ cvbr->base.draw_elements = sp_vbuf_draw_elements;
cvbr->base.draw_arrays = sp_vbuf_draw_arrays;
cvbr->base.release_vertices = sp_vbuf_release_vertices;
+ cvbr->base.set_stream_output_info = sp_vbuf_so_info;
cvbr->base.destroy = sp_vbuf_destroy;
cvbr->softpipe = sp;
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index ead489393ef..6af1b2d0618 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -33,6 +33,7 @@
#include "pipe/p_defines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_format.h"
#include "sp_context.h"
#include "sp_quad.h"
#include "sp_tile_cache.h"
@@ -207,7 +208,7 @@ logicop_quad(struct quad_stage *qs,
res4[j] = ~0;
break;
default:
- assert(0);
+ assert(0 && "invalid logicop mode");
}
for (j = 0; j < 4; j++) {
@@ -220,11 +221,19 @@ logicop_quad(struct quad_stage *qs,
+/**
+ * Do blending for a 2x2 quad for one color buffer.
+ * \param quadColor the incoming quad colors
+ * \param dest the destination/framebuffer quad colors
+ * \param blend_index which set of blending terms to use
+ * \param has_dst_alpha does the dest color buffer have an alpha channel?
+ */
static void
blend_quad(struct quad_stage *qs,
float (*quadColor)[4],
float (*dest)[4],
- unsigned cbuf)
+ unsigned blend_index,
+ boolean has_dst_alpha)
{
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
@@ -234,7 +243,7 @@ blend_quad(struct quad_stage *qs,
/*
* Compute src/first term RGB
*/
- switch (softpipe->blend->rt[cbuf].rgb_src_factor) {
+ switch (softpipe->blend->rt[blend_index].rgb_src_factor) {
case PIPE_BLENDFACTOR_ONE:
VEC4_COPY(source[0], quadColor[0]); /* R */
VEC4_COPY(source[1], quadColor[1]); /* G */
@@ -259,24 +268,34 @@ blend_quad(struct quad_stage *qs,
VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
break;
case PIPE_BLENDFACTOR_DST_ALPHA:
- {
- const float *alpha = dest[3];
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
+ if (has_dst_alpha) {
+ const float *alpha = dest[3];
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ else {
+ VEC4_COPY(source[0], quadColor[0]); /* R */
+ VEC4_COPY(source[1], quadColor[1]); /* G */
+ VEC4_COPY(source[2], quadColor[2]); /* B */
+ }
+ break;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- {
- const float *alpha = quadColor[3];
- float diff[4], temp[4];
- VEC4_SUB(diff, one, dest[3]);
- VEC4_MIN(temp, alpha, diff);
- VEC4_MUL(source[0], quadColor[0], temp); /* R */
- VEC4_MUL(source[1], quadColor[1], temp); /* G */
- VEC4_MUL(source[2], quadColor[2], temp); /* B */
- }
- break;
+ if (has_dst_alpha) {
+ const float *alpha = quadColor[3];
+ float diff[4], temp[4];
+ VEC4_SUB(diff, one, dest[3]);
+ VEC4_MIN(temp, alpha, diff);
+ VEC4_MUL(source[0], quadColor[0], temp); /* R */
+ VEC4_MUL(source[1], quadColor[1], temp); /* G */
+ VEC4_MUL(source[2], quadColor[2], temp); /* B */
+ }
+ else {
+ VEC4_COPY(source[0], zero); /* R */
+ VEC4_COPY(source[1], zero); /* G */
+ VEC4_COPY(source[2], zero); /* B */
+ }
+ break;
case PIPE_BLENDFACTOR_CONST_COLOR:
{
float comp[4];
@@ -329,14 +348,19 @@ blend_quad(struct quad_stage *qs,
}
break;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, dest[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
- }
- break;
+ if (has_dst_alpha) {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, dest[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ else {
+ VEC4_COPY(source[0], zero); /* R */
+ VEC4_COPY(source[1], zero); /* G */
+ VEC4_COPY(source[2], zero); /* B */
+ }
+ break;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
{
float inv_comp[4];
@@ -378,13 +402,13 @@ blend_quad(struct quad_stage *qs,
assert(0); /* to do */
break;
default:
- assert(0);
+ assert(0 && "invalid rgb src factor");
}
/*
* Compute src/first term A
*/
- switch (softpipe->blend->rt[cbuf].alpha_src_factor) {
+ switch (softpipe->blend->rt[blend_index].alpha_src_factor) {
case PIPE_BLENDFACTOR_ONE:
VEC4_COPY(source[3], quadColor[3]); /* A */
break;
@@ -399,7 +423,10 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_DST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
+ if (has_dst_alpha)
+ VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
+ else
+ VEC4_COPY(source[3], quadColor[3]); /* A */
break;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
/* multiply alpha by 1.0 */
@@ -429,12 +456,15 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_INV_DST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, dest[3]);
- VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
- }
- break;
+ if (has_dst_alpha) {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, dest[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+ }
+ else {
+ VEC4_COPY(source[3], zero); /* A */
+ }
+ break;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
@@ -446,14 +476,14 @@ blend_quad(struct quad_stage *qs,
}
break;
default:
- assert(0);
+ assert(0 && "invalid alpha src factor");
}
/*
* Compute dest/second term RGB
*/
- switch (softpipe->blend->rt[cbuf].rgb_dst_factor) {
+ switch (softpipe->blend->rt[blend_index].rgb_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
/* dest = dest * 1 NO-OP, leave dest as-is */
break;
@@ -468,9 +498,14 @@ blend_quad(struct quad_stage *qs,
VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
break;
case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
- VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
- VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
+ if (has_dst_alpha) {
+ VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
+ VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
+ VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
+ }
+ else {
+ /* dest = dest * 1 NO-OP, leave dest as-is */
+ }
break;
case PIPE_BLENDFACTOR_DST_COLOR:
VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
@@ -478,15 +513,20 @@ blend_quad(struct quad_stage *qs,
VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
break;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- {
- const float *alpha = quadColor[3];
- float diff[4], temp[4];
- VEC4_SUB(diff, one, dest[3]);
- VEC4_MIN(temp, alpha, diff);
- VEC4_MUL(dest[0], quadColor[0], temp); /* R */
- VEC4_MUL(dest[1], quadColor[1], temp); /* G */
- VEC4_MUL(dest[2], quadColor[2], temp); /* B */
- }
+ if (has_dst_alpha) {
+ const float *alpha = quadColor[3];
+ float diff[4], temp[4];
+ VEC4_SUB(diff, one, dest[3]);
+ VEC4_MIN(temp, alpha, diff);
+ VEC4_MUL(dest[0], quadColor[0], temp); /* R */
+ VEC4_MUL(dest[1], quadColor[1], temp); /* G */
+ VEC4_MUL(dest[2], quadColor[2], temp); /* B */
+ }
+ else {
+ VEC4_COPY(dest[0], zero); /* R */
+ VEC4_COPY(dest[1], zero); /* G */
+ VEC4_COPY(dest[2], zero); /* B */
+ }
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
{
@@ -539,13 +579,18 @@ blend_quad(struct quad_stage *qs,
}
break;
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[3]); /* A */
- VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
- VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
- VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
- }
+ if (has_dst_alpha) {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[3]); /* A */
+ VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+ VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+ VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+ }
+ else {
+ VEC4_COPY(dest[0], zero); /* R */
+ VEC4_COPY(dest[1], zero); /* G */
+ VEC4_COPY(dest[2], zero); /* B */
+ }
break;
case PIPE_BLENDFACTOR_INV_DST_COLOR:
{
@@ -587,13 +632,13 @@ blend_quad(struct quad_stage *qs,
assert(0);
break;
default:
- assert(0);
+ assert(0 && "invalid rgb dst factor");
}
/*
* Compute dest/second term A
*/
- switch (softpipe->blend->rt[cbuf].alpha_dst_factor) {
+ switch (softpipe->blend->rt[blend_index].alpha_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
/* dest = dest * 1 NO-OP, leave dest as-is */
break;
@@ -605,7 +650,12 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_DST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
+ if (has_dst_alpha) {
+ VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
+ }
+ else {
+ /* dest = dest * 1 NO-OP, leave dest as-is */
+ }
break;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
/* dest = dest * 1 NO-OP, leave dest as-is */
@@ -634,12 +684,15 @@ blend_quad(struct quad_stage *qs,
case PIPE_BLENDFACTOR_INV_DST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[3]); /* A */
- VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
- }
- break;
+ if (has_dst_alpha) {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[3]); /* A */
+ VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
+ }
+ else {
+ VEC4_COPY(dest[3], zero); /* A */
+ }
+ break;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
@@ -650,13 +703,13 @@ blend_quad(struct quad_stage *qs,
}
break;
default:
- assert(0);
+ assert(0 && "invalid alpha dst factor");
}
/*
* Combine RGB terms
*/
- switch (softpipe->blend->rt[cbuf].rgb_func) {
+ switch (softpipe->blend->rt[blend_index].rgb_func) {
case PIPE_BLEND_ADD:
VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
@@ -683,13 +736,13 @@ blend_quad(struct quad_stage *qs,
VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
break;
default:
- assert(0);
+ assert(0 && "invalid rgb blend func");
}
/*
* Combine A terms
*/
- switch (softpipe->blend->rt[cbuf].alpha_func) {
+ switch (softpipe->blend->rt[blend_index].alpha_func) {
case PIPE_BLEND_ADD:
VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
break;
@@ -706,7 +759,7 @@ blend_quad(struct quad_stage *qs,
VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
break;
default:
- assert(0);
+ assert(0 && "invalid alpha blend func");
}
}
@@ -751,6 +804,8 @@ blend_fallback(struct quad_stage *qs,
= sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
quads[0]->input.x0,
quads[0]->input.y0);
+ boolean has_dst_alpha
+ = util_format_has_alpha(softpipe->framebuffer.cbufs[cbuf]->format);
uint q, i, j;
for (q = 0; q < nr; q++) {
@@ -774,7 +829,7 @@ blend_fallback(struct quad_stage *qs,
logicop_quad( qs, quadColor, dest );
}
else if (blend->rt[blend_buf].blend_enable) {
- blend_quad( qs, quadColor, dest, cbuf );
+ blend_quad( qs, quadColor, dest, blend_buf, has_dst_alpha );
}
if (blend->rt[blend_buf].colormask != 0xf)
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 72117c233e5..e9b92626176 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -82,7 +82,7 @@ get_depth_stencil_values( struct depth_data *data,
data->bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
data->stencilVals[j] = tile->data.depth32[y][x] >> 24;
}
- break;
+ break;
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
for (j = 0; j < QUAD_SIZE; j++) {
@@ -92,6 +92,14 @@ get_depth_stencil_values( struct depth_data *data,
data->stencilVals[j] = tile->data.depth32[y][x] & 0xff;
}
break;
+ case PIPE_FORMAT_S8_USCALED:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = quad->input.x0 % TILE_SIZE + (j & 1);
+ int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+ data->bzzzz[j] = 0;
+ data->stencilVals[j] = tile->data.stencil8[y][x];
+ }
+ break;
default:
assert(0);
}
@@ -227,6 +235,14 @@ write_depth_stencil_values( struct depth_data *data,
tile->data.depth32[y][x] = data->bzzzz[j] << 8;
}
break;
+ case PIPE_FORMAT_S8_USCALED:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = quad->input.x0 % TILE_SIZE + (j & 1);
+ int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+ tile->data.stencil8[y][x] = data->stencilVals[j];
+ }
+ break;
+
default:
assert(0);
}
@@ -661,20 +677,6 @@ static unsigned mask_count[16] =
-/** helper to get number of Z buffer bits */
-static unsigned
-get_depth_bits(struct quad_stage *qs)
-{
- struct pipe_surface *zsurf = qs->softpipe->framebuffer.zsbuf;
- if (zsurf)
- return util_format_get_component_bits(zsurf->format,
- UTIL_FORMAT_COLORSPACE_ZS, 0);
- else
- return 0;
-}
-
-
-
/**
* General depth/stencil test function. Used when there's no fast-path.
*/
@@ -693,9 +695,9 @@ depth_test_quads_fallback(struct quad_stage *qs,
nr = alpha_test_quads(qs, quads, nr);
}
- if (get_depth_bits(qs) > 0 &&
- (qs->softpipe->depth_stencil->depth.enabled ||
- qs->softpipe->depth_stencil->stencil[0].enabled)) {
+ if (qs->softpipe->framebuffer.zsbuf &&
+ (qs->softpipe->depth_stencil->depth.enabled ||
+ qs->softpipe->depth_stencil->stencil[0].enabled)) {
data.ps = qs->softpipe->framebuffer.zsbuf;
data.format = data.ps->format;
@@ -794,8 +796,7 @@ choose_depth_test(struct quad_stage *qs,
boolean alpha = qs->softpipe->depth_stencil->alpha.enabled;
- boolean depth = (get_depth_bits(qs) > 0 &&
- qs->softpipe->depth_stencil->depth.enabled);
+ boolean depth = qs->softpipe->depth_stencil->depth.enabled;
unsigned depthfunc = qs->softpipe->depth_stencil->depth.func;
@@ -805,6 +806,9 @@ choose_depth_test(struct quad_stage *qs,
boolean occlusion = qs->softpipe->active_query_count;
+ if(!qs->softpipe->framebuffer.zsbuf)
+ depth = depthwrite = stencil = FALSE;
+
/* default */
qs->run = depth_test_quads_fallback;
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 8ae5a7f028b..90f4787d599 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -50,8 +50,8 @@
struct quad_shade_stage
{
struct quad_stage stage; /**< base class */
- struct tgsi_exec_machine *machine;
- struct tgsi_exec_vector *inputs, *outputs;
+
+ /* no other fields at this time */
};
@@ -70,9 +70,8 @@ quad_shade_stage(struct quad_stage *qs)
static INLINE boolean
shade_quad(struct quad_stage *qs, struct quad_header *quad)
{
- struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
- struct tgsi_exec_machine *machine = qss->machine;
+ struct tgsi_exec_machine *machine = softpipe->fs_machine;
/* run shader */
return softpipe->fs->run( softpipe->fs, machine, quad );
@@ -108,14 +107,14 @@ shade_quads(struct quad_stage *qs,
struct quad_header *quads[],
unsigned nr)
{
- struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
- struct tgsi_exec_machine *machine = qss->machine;
- unsigned i, pass = 0;
+ struct tgsi_exec_machine *machine = softpipe->fs_machine;
+ unsigned i, nr_quads = 0;
+
+ tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
+ softpipe->mapped_constants[PIPE_SHADER_FRAGMENT],
+ softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]);
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i];
- }
machine->InterpCoefs = quads[0]->coef;
for (i = 0; i < nr; i++) {
@@ -125,11 +124,11 @@ shade_quads(struct quad_stage *qs,
if (/*do_coverage*/ 0)
coverage_quad( qs, quads[i] );
- quads[pass++] = quads[i];
+ quads[nr_quads++] = quads[i];
}
- if (pass)
- qs->next->run(qs->next, quads, pass);
+ if (nr_quads)
+ qs->next->run(qs->next, quads, nr_quads);
}
@@ -139,11 +138,10 @@ shade_quads(struct quad_stage *qs,
static void
shade_begin(struct quad_stage *qs)
{
- struct quad_shade_stage *qss = quad_shade_stage(qs);
struct softpipe_context *softpipe = qs->softpipe;
softpipe->fs->prepare( softpipe->fs,
- qss->machine,
+ softpipe->fs_machine,
(struct tgsi_sampler **)
softpipe->tgsi.frag_samplers_list );
@@ -154,10 +152,6 @@ shade_begin(struct quad_stage *qs)
static void
shade_destroy(struct quad_stage *qs)
{
- struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
-
- tgsi_exec_machine_destroy(qss->machine);
-
FREE( qs );
}
@@ -174,16 +168,9 @@ sp_quad_shade_stage( struct softpipe_context *softpipe )
qss->stage.run = shade_quads;
qss->stage.destroy = shade_destroy;
- qss->machine = tgsi_exec_machine_create();
- if (!qss->machine)
- goto fail;
-
return &qss->stage;
fail:
- if (qss && qss->machine)
- tgsi_exec_machine_destroy(qss->machine);
-
FREE(qss);
return NULL;
}
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index 4ef5d9f7b1d..4ae69c1c2bd 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -30,6 +30,7 @@
*/
#include "draw/draw_context.h"
+#include "os/os_time.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "sp_context.h"
@@ -37,8 +38,10 @@
#include "sp_state.h"
struct softpipe_query {
+ unsigned type;
uint64_t start;
uint64_t end;
+ struct pipe_query_data_so_statistics so;
};
@@ -51,8 +54,17 @@ static struct pipe_query *
softpipe_create_query(struct pipe_context *pipe,
unsigned type)
{
- assert(type == PIPE_QUERY_OCCLUSION_COUNTER);
- return (struct pipe_query *)CALLOC_STRUCT( softpipe_query );
+ struct softpipe_query* sq;
+
+ assert(type == PIPE_QUERY_OCCLUSION_COUNTER ||
+ type == PIPE_QUERY_TIME_ELAPSED ||
+ type == PIPE_QUERY_SO_STATISTICS ||
+ type == PIPE_QUERY_GPU_FINISHED ||
+ type == PIPE_QUERY_TIMESTAMP_DISJOINT);
+ sq = CALLOC_STRUCT( softpipe_query );
+ sq->type = type;
+
+ return (struct pipe_query *)sq;
}
@@ -68,8 +80,25 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
{
struct softpipe_context *softpipe = softpipe_context( pipe );
struct softpipe_query *sq = softpipe_query(q);
-
- sq->start = softpipe->occlusion_count;
+
+ switch (sq->type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ sq->start = softpipe->occlusion_count;
+ break;
+ case PIPE_QUERY_TIME_ELAPSED:
+ sq->start = 1000*os_time_get();
+ break;
+ case PIPE_QUERY_SO_STATISTICS:
+ sq->so.num_primitives_written = 0;
+ sq->so.primitives_storage_needed = 0;
+ break;
+ case PIPE_QUERY_GPU_FINISHED:
+ break;
+ case PIPE_QUERY_TIMESTAMP_DISJOINT:
+ default:
+ assert(0);
+ break;
+ }
softpipe->active_query_count++;
softpipe->dirty |= SP_NEW_QUERY;
}
@@ -82,7 +111,26 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
struct softpipe_query *sq = softpipe_query(q);
softpipe->active_query_count--;
- sq->end = softpipe->occlusion_count;
+ switch (sq->type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ sq->end = softpipe->occlusion_count;
+ break;
+ case PIPE_QUERY_TIME_ELAPSED:
+ sq->end = 1000*os_time_get();
+ break;
+ case PIPE_QUERY_SO_STATISTICS:
+ sq->so.num_primitives_written =
+ softpipe->so_stats.num_primitives_written;
+ sq->so.primitives_storage_needed =
+ softpipe->so_stats.primitives_storage_needed;
+ break;
+ case PIPE_QUERY_GPU_FINISHED:
+ case PIPE_QUERY_TIMESTAMP_DISJOINT:
+ break;
+ default:
+ assert(0);
+ break;
+ }
softpipe->dirty |= SP_NEW_QUERY;
}
@@ -91,10 +139,32 @@ static boolean
softpipe_get_query_result(struct pipe_context *pipe,
struct pipe_query *q,
boolean wait,
- uint64_t *result )
+ void *vresult)
{
struct softpipe_query *sq = softpipe_query(q);
- *result = sq->end - sq->start;
+ uint64_t *result = (uint64_t*)vresult;
+
+ switch (sq->type) {
+ case PIPE_QUERY_SO_STATISTICS:
+ memcpy(vresult, &sq->so,
+ sizeof(struct pipe_query_data_so_statistics));
+ break;
+ case PIPE_QUERY_GPU_FINISHED:
+ *result = TRUE;
+ break;
+ case PIPE_QUERY_TIMESTAMP_DISJOINT: {
+ struct pipe_query_data_timestamp_disjoint td;
+ /*os_get_time is in microseconds*/
+ td.frequency = 1000000;
+ td.disjoint = FALSE;
+ memcpy(vresult, &sq->so,
+ sizeof(struct pipe_query_data_timestamp_disjoint));
+ }
+ break;
+ default:
+ *result = sq->end - sq->start;
+ break;
+ }
return TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 00700974c78..25a0a622179 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -31,8 +31,10 @@
#include "util/u_format_s3tc.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "draw/draw_context.h"
#include "state_tracker/sw_winsys.h"
+#include "tgsi/tgsi_exec.h"
#include "sp_texture.h"
#include "sp_screen.h"
@@ -57,7 +59,7 @@ softpipe_get_name(struct pipe_screen *screen)
static int
-softpipe_get_param(struct pipe_screen *screen, int param)
+softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
@@ -72,6 +74,8 @@ softpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 1;
+ case PIPE_CAP_SM3:
+ return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
@@ -80,26 +84,24 @@ softpipe_get_param(struct pipe_screen *screen, int param)
return PIPE_MAX_COLOR_BUFS;
case PIPE_CAP_OCCLUSION_QUERY:
return 1;
+ case PIPE_CAP_TIMER_QUERY:
+ return 1;
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
return 1;
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
+ case PIPE_CAP_TEXTURE_SWIZZLE:
+ return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
return SP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return SP_MAX_TEXTURE_2D_LEVELS;
- case PIPE_CAP_TGSI_CONT_SUPPORTED:
- return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
- case PIPE_CAP_MAX_CONST_BUFFERS:
- return PIPE_MAX_CONSTANT_BUFFERS;
- case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
- return 4096 * 4 * sizeof(float);
case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -109,14 +111,32 @@ softpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 1;
+ case PIPE_CAP_STREAM_OUTPUT:
+ return 1;
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
+ return 0;
default:
return 0;
}
}
+static int
+softpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
+{
+ switch(shader)
+ {
+ case PIPE_SHADER_FRAGMENT:
+ return tgsi_exec_get_shader_param(param);
+ case PIPE_SHADER_VERTEX:
+ case PIPE_SHADER_GEOMETRY:
+ return draw_get_shader_param(shader, param);
+ default:
+ return 0;
+ }
+}
static float
-softpipe_get_paramf(struct pipe_screen *screen, int param)
+softpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
{
switch (param) {
case PIPE_CAP_MAX_LINE_WIDTH:
@@ -144,16 +164,19 @@ softpipe_get_paramf(struct pipe_screen *screen, int param)
*/
static boolean
softpipe_is_format_supported( struct pipe_screen *screen,
- enum pipe_format format,
+ enum pipe_format format,
enum pipe_texture_target target,
+ unsigned sample_count,
unsigned bind,
unsigned geom_flags )
{
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
const struct util_format_description *format_desc;
- assert(target == PIPE_TEXTURE_1D ||
+ assert(target == PIPE_BUFFER ||
+ target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
+ target == PIPE_TEXTURE_RECT ||
target == PIPE_TEXTURE_3D ||
target == PIPE_TEXTURE_CUBE);
@@ -161,6 +184,9 @@ softpipe_is_format_supported( struct pipe_screen *screen,
if (!format_desc)
return FALSE;
+ if (sample_count > 1)
+ return FALSE;
+
if (bind & (PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) {
@@ -271,6 +297,7 @@ softpipe_create_screen(struct sw_winsys *winsys)
screen->base.get_name = softpipe_get_name;
screen->base.get_vendor = softpipe_get_vendor;
screen->base.get_param = softpipe_get_param;
+ screen->base.get_shader_param = softpipe_get_shader_param;
screen->base.get_paramf = softpipe_get_paramf;
screen->base.is_format_supported = softpipe_is_format_supported;
screen->base.context_create = softpipe_create_context;
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index 86354664e4b..5d727dc00df 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -111,34 +111,13 @@ struct setup_context {
uint numFragsWritten; /**< per primitive */
#endif
- unsigned winding; /* which winding to cull */
+ unsigned cull_face; /* which faces cull */
unsigned nr_vertex_attrs;
};
-/**
- * Do triangle cull test using tri determinant (sign indicates orientation)
- * \return true if triangle is to be culled.
- */
-static INLINE boolean
-cull_tri(const struct setup_context *setup, float det)
-{
- if (det != 0) {
- /* if (det < 0 then Z points toward camera and triangle is
- * counter-clockwise winding.
- */
- unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
-
- if ((winding & setup->winding) == 0)
- return FALSE;
- }
-
- /* Culled:
- */
- return TRUE;
-}
@@ -304,7 +283,10 @@ setup_sort_vertices(struct setup_context *setup,
const float (*v1)[4],
const float (*v2)[4])
{
- setup->vprovoke = v2;
+ if (setup->softpipe->rasterizer->flatshade_first)
+ setup->vprovoke = v0;
+ else
+ setup->vprovoke = v2;
/* determine bottom to top order of vertices */
{
@@ -390,8 +372,16 @@ setup_sort_vertices(struct setup_context *setup,
* 0 = front-facing, 1 = back-facing
*/
setup->facing =
- ((det > 0.0) ^
- (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW));
+ ((det < 0.0) ^
+ (setup->softpipe->rasterizer->front_ccw));
+
+ {
+ unsigned face = setup->facing == 0 ? PIPE_FACE_FRONT : PIPE_FACE_BACK;
+
+ if (face & setup->cull_face)
+ return FALSE;
+ }
+
/* Prepare pixel offset for rasterisation:
* - pixel center (0.5, 0.5) for GL, or
@@ -829,11 +819,9 @@ sp_setup_tri(struct setup_context *setup,
setup->numFragsWritten = 0;
#endif
- if (cull_tri( setup, det ))
- return;
-
if (!setup_sort_vertices( setup, det, v0, v1, v2 ))
return;
+
setup_tri_coefficients( setup );
setup_tri_edges( setup );
@@ -1417,14 +1405,14 @@ sp_setup_prepare(struct setup_context *setup)
sp->quad.first->begin( sp->quad.first );
if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
- sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL &&
- sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) {
+ sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL &&
+ sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) {
/* we'll do culling */
- setup->winding = sp->rasterizer->cull_mode;
+ setup->cull_face = sp->rasterizer->cull_face;
}
else {
/* 'draw' will do culling */
- setup->winding = PIPE_WINDING_NONE;
+ setup->cull_face = PIPE_FACE_NONE;
}
}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index f97fc6eca8f..525bf23734a 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -51,6 +51,8 @@
#define SP_NEW_VS 0x2000
#define SP_NEW_QUERY 0x4000
#define SP_NEW_GS 0x8000
+#define SP_NEW_SO 0x10000
+#define SP_NEW_SO_BUFFERS 0x20000
struct tgsi_sampler;
@@ -68,6 +70,8 @@ struct sp_fragment_shader {
struct tgsi_shader_info info;
+ struct draw_fragment_shader *draw_shader;
+
boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
@@ -98,6 +102,7 @@ struct sp_vertex_shader {
struct sp_geometry_shader {
struct pipe_shader_state shader;
struct draw_geometry_shader *draw_data;
+ int max_sampler;
};
struct sp_velems_state {
@@ -105,141 +110,45 @@ struct sp_velems_state {
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
+struct sp_so_state {
+ struct pipe_stream_output_state base;
+};
-void *
-softpipe_create_blend_state(struct pipe_context *,
- const struct pipe_blend_state *);
-void softpipe_bind_blend_state(struct pipe_context *,
- void *);
-void softpipe_delete_blend_state(struct pipe_context *,
- void *);
-void *
-softpipe_create_sampler_state(struct pipe_context *,
- const struct pipe_sampler_state *);
-void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
void
-softpipe_bind_vertex_sampler_states(struct pipe_context *,
- unsigned num_samplers,
- void **samplers);
-void softpipe_delete_sampler_state(struct pipe_context *, void *);
-
-void *
-softpipe_create_depth_stencil_state(struct pipe_context *,
- const struct pipe_depth_stencil_alpha_state *);
-void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
-void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
-
-void *
-softpipe_create_rasterizer_state(struct pipe_context *,
- const struct pipe_rasterizer_state *);
-void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
-void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
-
-void softpipe_set_framebuffer_state( struct pipe_context *,
- const struct pipe_framebuffer_state * );
-
-void softpipe_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color );
-
-void softpipe_set_stencil_ref( struct pipe_context *pipe,
- const struct pipe_stencil_ref *stencil_ref );
-
-void softpipe_set_clip_state( struct pipe_context *,
- const struct pipe_clip_state * );
-
-void softpipe_set_constant_buffer(struct pipe_context *,
- uint shader, uint index,
- struct pipe_resource *buf);
-
-void *softpipe_create_fs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void softpipe_bind_fs_state(struct pipe_context *, void *);
-void softpipe_delete_fs_state(struct pipe_context *, void *);
-void *softpipe_create_vs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void softpipe_bind_vs_state(struct pipe_context *, void *);
-void softpipe_delete_vs_state(struct pipe_context *, void *);
-void *softpipe_create_gs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void softpipe_bind_gs_state(struct pipe_context *, void *);
-void softpipe_delete_gs_state(struct pipe_context *, void *);
-
-void *softpipe_create_vertex_elements_state(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-void softpipe_bind_vertex_elements_state(struct pipe_context *, void *);
-void softpipe_delete_vertex_elements_state(struct pipe_context *, void *);
-
-void softpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
-
-void softpipe_set_scissor_state( struct pipe_context *,
- const struct pipe_scissor_state * );
-
-void softpipe_set_sampler_views( struct pipe_context *,
- unsigned num,
- struct pipe_sampler_view ** );
+softpipe_init_blend_funcs(struct pipe_context *pipe);
void
-softpipe_set_vertex_sampler_views(struct pipe_context *,
- unsigned num,
- struct pipe_sampler_view **);
-
-struct pipe_sampler_view *
-softpipe_create_sampler_view(struct pipe_context *pipe,
- struct pipe_resource *texture,
- const struct pipe_sampler_view *templ);
+softpipe_init_clip_funcs(struct pipe_context *pipe);
void
-softpipe_sampler_view_destroy(struct pipe_context *pipe,
- struct pipe_sampler_view *view);
+softpipe_init_sampler_funcs(struct pipe_context *pipe);
-void softpipe_set_viewport_state( struct pipe_context *,
- const struct pipe_viewport_state * );
-
-void softpipe_set_vertex_buffers(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_buffer *);
+void
+softpipe_init_rasterizer_funcs(struct pipe_context *pipe);
+void
+softpipe_init_shader_funcs(struct pipe_context *pipe);
-void softpipe_update_derived( struct softpipe_context *softpipe );
+void
+softpipe_init_streamout_funcs(struct pipe_context *pipe);
+void
+softpipe_init_vertex_funcs(struct pipe_context *pipe);
-void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count);
+void
+softpipe_set_framebuffer_state(struct pipe_context *,
+ const struct pipe_framebuffer_state *);
-void softpipe_draw_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize, int indexBias,
- unsigned mode, unsigned start, unsigned count);
void
-softpipe_draw_range_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned min_index,
- unsigned max_index,
- unsigned mode, unsigned start, unsigned count);
+softpipe_update_derived( struct softpipe_context *softpipe );
void
-softpipe_draw_arrays_instanced(struct pipe_context *pipe,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount);
+softpipe_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
void
-softpipe_draw_elements_instanced(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize,
- int indexBias,
- unsigned mode,
- unsigned start,
- unsigned count,
- unsigned startInstance,
- unsigned instanceCount);
+softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode);
void
softpipe_map_transfers(struct softpipe_context *sp);
diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c
index c63a49e90b0..12863824b8e 100644
--- a/src/gallium/drivers/softpipe/sp_state_blend.c
+++ b/src/gallium/drivers/softpipe/sp_state_blend.c
@@ -34,15 +34,17 @@
#include "sp_state.h"
-void *
+static void *
softpipe_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
return mem_dup(blend, sizeof(*blend));
}
-void softpipe_bind_blend_state( struct pipe_context *pipe,
- void *blend )
+
+static void
+softpipe_bind_blend_state(struct pipe_context *pipe,
+ void *blend)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -53,15 +55,18 @@ void softpipe_bind_blend_state( struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_BLEND;
}
-void softpipe_delete_blend_state(struct pipe_context *pipe,
- void *blend)
+
+static void
+softpipe_delete_blend_state(struct pipe_context *pipe,
+ void *blend)
{
FREE( blend );
}
-void softpipe_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color )
+static void
+softpipe_set_blend_color(struct pipe_context *pipe,
+ const struct pipe_blend_color *blend_color)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -73,19 +78,15 @@ void softpipe_set_blend_color( struct pipe_context *pipe,
}
-/** XXX move someday? Or consolidate all these simple state setters
- * into one file.
- */
-
-
-void *
+static void *
softpipe_create_depth_stencil_state(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *depth_stencil)
{
return mem_dup(depth_stencil, sizeof(*depth_stencil));
}
-void
+
+static void
softpipe_bind_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
@@ -96,14 +97,17 @@ softpipe_bind_depth_stencil_state(struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA;
}
-void
+
+static void
softpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
{
FREE( depth );
}
-void softpipe_set_stencil_ref( struct pipe_context *pipe,
- const struct pipe_stencil_ref *stencil_ref )
+
+static void
+softpipe_set_stencil_ref(struct pipe_context *pipe,
+ const struct pipe_stencil_ref *stencil_ref)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -111,3 +115,29 @@ void softpipe_set_stencil_ref( struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA;
}
+
+
+static void
+softpipe_set_sample_mask(struct pipe_context *pipe,
+ unsigned sample_mask)
+{
+}
+
+
+void
+softpipe_init_blend_funcs(struct pipe_context *pipe)
+{
+ pipe->create_blend_state = softpipe_create_blend_state;
+ pipe->bind_blend_state = softpipe_bind_blend_state;
+ pipe->delete_blend_state = softpipe_delete_blend_state;
+
+ pipe->set_blend_color = softpipe_set_blend_color;
+
+ pipe->create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
+ pipe->bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
+ pipe->delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
+
+ pipe->set_stencil_ref = softpipe_set_stencil_ref;
+
+ pipe->set_sample_mask = softpipe_set_sample_mask;
+}
diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c
index 4946c776e3e..f3a4c234e27 100644
--- a/src/gallium/drivers/softpipe/sp_state_clip.c
+++ b/src/gallium/drivers/softpipe/sp_state_clip.c
@@ -32,8 +32,9 @@
#include "draw/draw_context.h"
-void softpipe_set_clip_state( struct pipe_context *pipe,
- const struct pipe_clip_state *clip )
+static void
+softpipe_set_clip_state(struct pipe_context *pipe,
+ const struct pipe_clip_state *clip)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -42,8 +43,9 @@ void softpipe_set_clip_state( struct pipe_context *pipe,
}
-void softpipe_set_viewport_state( struct pipe_context *pipe,
- const struct pipe_viewport_state *viewport )
+static void
+softpipe_set_viewport_state(struct pipe_context *pipe,
+ const struct pipe_viewport_state *viewport)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -55,8 +57,9 @@ void softpipe_set_viewport_state( struct pipe_context *pipe,
}
-void softpipe_set_scissor_state( struct pipe_context *pipe,
- const struct pipe_scissor_state *scissor )
+static void
+softpipe_set_scissor_state(struct pipe_context *pipe,
+ const struct pipe_scissor_state *scissor)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -67,8 +70,9 @@ void softpipe_set_scissor_state( struct pipe_context *pipe,
}
-void softpipe_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
+static void
+softpipe_set_polygon_stipple(struct pipe_context *pipe,
+ const struct pipe_poly_stipple *stipple)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -77,3 +81,13 @@ void softpipe_set_polygon_stipple( struct pipe_context *pipe,
softpipe->poly_stipple = *stipple; /* struct copy */
softpipe->dirty |= SP_NEW_STIPPLE;
}
+
+
+void
+softpipe_init_clip_funcs(struct pipe_context *pipe)
+{
+ pipe->set_clip_state = softpipe_set_clip_state;
+ pipe->set_viewport_state = softpipe_set_viewport_state;
+ pipe->set_scissor_state = softpipe_set_scissor_state;
+ pipe->set_polygon_stipple = softpipe_set_polygon_stipple;
+}
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 4c6d4909f5b..3ba4d934fd2 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -225,6 +225,19 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
}
}
}
+
+ for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+ struct softpipe_tex_tile_cache *tc = softpipe->geometry_tex_cache[i];
+
+ if (tc->texture) {
+ struct softpipe_resource *spt = softpipe_resource(tc->texture);
+
+ if (spt->timestamp != tc->timestamp) {
+ sp_tex_tile_cache_validate_texture(tc);
+ tc->timestamp = spt->timestamp;
+ }
+ }
+ }
}
diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
index c9ede09f268..3cd4acd7432 100644
--- a/src/gallium/drivers/softpipe/sp_state_rasterizer.c
+++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
@@ -33,15 +33,17 @@
-void *
+static void *
softpipe_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rast)
{
return mem_dup(rast, sizeof(*rast));
}
-void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
- void *rasterizer)
+
+static void
+softpipe_bind_rasterizer_state(struct pipe_context *pipe,
+ void *rasterizer)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -56,10 +58,19 @@ void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_RASTERIZER;
}
-void softpipe_delete_rasterizer_state(struct pipe_context *pipe,
- void *rasterizer)
+
+static void
+softpipe_delete_rasterizer_state(struct pipe_context *pipe,
+ void *rasterizer)
{
FREE( rasterizer );
}
+void
+softpipe_init_rasterizer_funcs(struct pipe_context *pipe)
+{
+ pipe->create_rasterizer_state = softpipe_create_rasterizer_state;
+ pipe->bind_rasterizer_state = softpipe_bind_rasterizer_state;
+ pipe->delete_rasterizer_state = softpipe_delete_rasterizer_state;
+}
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index 2692f06c927..b59fbc33ed6 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -33,7 +33,6 @@
#include "util/u_inlines.h"
#include "draw/draw_context.h"
-#include "draw/draw_context.h"
#include "sp_context.h"
#include "sp_state.h"
@@ -54,7 +53,7 @@ static struct sp_sampler *sp_sampler( struct pipe_sampler_state *sampler )
}
-void *
+static void *
softpipe_create_sampler_state(struct pipe_context *pipe,
const struct pipe_sampler_state *sampler)
{
@@ -67,7 +66,7 @@ softpipe_create_sampler_state(struct pipe_context *pipe,
}
-void
+static void
softpipe_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
@@ -94,7 +93,7 @@ softpipe_bind_sampler_states(struct pipe_context *pipe,
}
-void
+static void
softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
unsigned num_samplers,
void **samplers)
@@ -118,11 +117,42 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
softpipe->num_vertex_samplers = num_samplers;
+ draw_set_samplers(softpipe->draw,
+ softpipe->vertex_samplers,
+ softpipe->num_vertex_samplers);
+
+ softpipe->dirty |= SP_NEW_SAMPLER;
+}
+
+static void
+softpipe_bind_geometry_sampler_states(struct pipe_context *pipe,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ unsigned i;
+
+ assert(num_samplers <= PIPE_MAX_GEOMETRY_SAMPLERS);
+
+ /* Check for no-op */
+ if (num_samplers == softpipe->num_geometry_samplers &&
+ !memcmp(softpipe->geometry_samplers, samplers, num_samplers * sizeof(void *)))
+ return;
+
+ draw_flush(softpipe->draw);
+
+ for (i = 0; i < num_samplers; ++i)
+ softpipe->geometry_samplers[i] = samplers[i];
+ for (i = num_samplers; i < PIPE_MAX_GEOMETRY_SAMPLERS; ++i)
+ softpipe->geometry_samplers[i] = NULL;
+
+ softpipe->num_geometry_samplers = num_samplers;
+
softpipe->dirty |= SP_NEW_SAMPLER;
}
-struct pipe_sampler_view *
+static struct pipe_sampler_view *
softpipe_create_sampler_view(struct pipe_context *pipe,
struct pipe_resource *resource,
const struct pipe_sampler_view *templ)
@@ -141,7 +171,7 @@ softpipe_create_sampler_view(struct pipe_context *pipe,
}
-void
+static void
softpipe_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
@@ -150,7 +180,7 @@ softpipe_sampler_view_destroy(struct pipe_context *pipe,
}
-void
+static void
softpipe_set_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@@ -180,7 +210,7 @@ softpipe_set_sampler_views(struct pipe_context *pipe,
}
-void
+static void
softpipe_set_vertex_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@@ -207,6 +237,41 @@ softpipe_set_vertex_sampler_views(struct pipe_context *pipe,
softpipe->num_vertex_sampler_views = num;
+ draw_set_sampler_views(softpipe->draw,
+ softpipe->vertex_sampler_views,
+ softpipe->num_vertex_sampler_views);
+
+ softpipe->dirty |= SP_NEW_TEXTURE;
+}
+
+
+static void
+softpipe_set_geometry_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ uint i;
+
+ assert(num <= PIPE_MAX_GEOMETRY_SAMPLERS);
+
+ /* Check for no-op */
+ if (num == softpipe->num_geometry_sampler_views &&
+ !memcmp(softpipe->geometry_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
+ return;
+ }
+
+ draw_flush(softpipe->draw);
+
+ for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+ pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], view);
+ sp_tex_tile_cache_set_sampler_view(softpipe->geometry_tex_cache[i], view);
+ }
+
+ softpipe->num_geometry_sampler_views = num;
+
softpipe->dirty |= SP_NEW_TEXTURE;
}
@@ -262,8 +327,6 @@ get_sampler_varient( unsigned unit,
}
-
-
void
softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
{
@@ -293,6 +356,30 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
}
}
+ if (softpipe->gs) {
+ for (i = 0; i <= softpipe->gs->max_sampler; i++) {
+ if (softpipe->geometry_samplers[i]) {
+ struct pipe_resource *texture = NULL;
+
+ if (softpipe->geometry_sampler_views[i]) {
+ texture = softpipe->geometry_sampler_views[i]->texture;
+ }
+
+ softpipe->tgsi.geom_samplers_list[i] =
+ get_sampler_varient(
+ i,
+ sp_sampler(softpipe->geometry_samplers[i]),
+ texture,
+ TGSI_PROCESSOR_GEOMETRY );
+
+ sp_sampler_varient_bind_texture(
+ softpipe->tgsi.geom_samplers_list[i],
+ softpipe->geometry_tex_cache[i],
+ texture );
+ }
+ }
+ }
+
for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) {
if (softpipe->sampler[i]) {
struct pipe_resource *texture = NULL;
@@ -314,9 +401,7 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
}
}
-
-
-void
+static void
softpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
@@ -332,4 +417,20 @@ softpipe_delete_sampler_state(struct pipe_context *pipe,
}
+void
+softpipe_init_sampler_funcs(struct pipe_context *pipe)
+{
+ pipe->create_sampler_state = softpipe_create_sampler_state;
+ pipe->bind_fragment_sampler_states = softpipe_bind_sampler_states;
+ pipe->bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states;
+ pipe->bind_geometry_sampler_states = softpipe_bind_geometry_sampler_states;
+ pipe->delete_sampler_state = softpipe_delete_sampler_state;
+
+ pipe->set_fragment_sampler_views = softpipe_set_sampler_views;
+ pipe->set_vertex_sampler_views = softpipe_set_vertex_sampler_views;
+ pipe->set_geometry_sampler_views = softpipe_set_geometry_sampler_views;
+
+ pipe->create_sampler_view = softpipe_create_sampler_view;
+ pipe->sampler_view_destroy = softpipe_sampler_view_destroy;
+}
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_shader.c
index 7f072f5a269..7fff338ccea 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_shader.c
@@ -35,12 +35,14 @@
#include "util/u_inlines.h"
#include "draw/draw_context.h"
#include "draw/draw_vs.h"
+#include "draw/draw_gs.h"
#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_parse.h"
-void *
+static void *
softpipe_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -58,7 +60,15 @@ softpipe_create_fs_state(struct pipe_context *pipe,
state = softpipe_create_fs_exec( softpipe, templ );
}
- assert(state);
+ if (!state)
+ return NULL;
+
+ /* draw's fs state */
+ state->draw_shader = draw_create_fragment_shader(softpipe->draw, templ);
+ if (!state->draw_shader) {
+ state->delete( state );
+ return NULL;
+ }
/* get/save the summary info for this shader */
tgsi_scan_shader(templ->tokens, &state->info);
@@ -74,7 +84,7 @@ softpipe_create_fs_state(struct pipe_context *pipe,
}
-void
+static void
softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -88,22 +98,35 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
softpipe->fs = fs;
+ draw_bind_fragment_shader(softpipe->draw,
+ (softpipe->fs ? softpipe->fs->draw_shader : NULL));
+
softpipe->dirty |= SP_NEW_FS;
}
-void
+static void
softpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_fragment_shader *state = fs;
assert(fs != softpipe_context(pipe)->fs);
-
+
+ if (softpipe->fs_machine->Tokens == state->shader.tokens) {
+ /* unbind the shader from the tgsi executor if we're
+ * deleting it.
+ */
+ tgsi_exec_machine_bind_shader(softpipe->fs_machine, NULL, 0, NULL);
+ }
+
+ draw_delete_fragment_shader(softpipe->draw, state->draw_shader);
+
state->delete( state );
}
-void *
+static void *
softpipe_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -138,7 +161,7 @@ fail:
}
-void
+static void
softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -152,7 +175,7 @@ softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
}
-void
+static void
softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -164,33 +187,8 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
FREE( state );
}
-void
-softpipe_set_constant_buffer(struct pipe_context *pipe,
- uint shader, uint index,
- struct pipe_resource *constants)
-{
- struct softpipe_context *softpipe = softpipe_context(pipe);
- unsigned size = constants ? constants->width0 : 0;
- const void *data = constants ? softpipe_resource(constants)->data : NULL;
-
- assert(shader < PIPE_SHADER_TYPES);
- assert(index == 0);
-
- draw_flush(softpipe->draw);
-
- /* note: reference counting */
- pipe_resource_reference(&softpipe->constants[shader][index], constants);
-
- if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
- draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
- }
- softpipe->mapped_constants[shader][index] = data;
- softpipe->dirty |= SP_NEW_CONSTANTS;
-}
-
-
-void *
+static void *
softpipe_create_gs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -215,6 +213,8 @@ softpipe_create_gs_state(struct pipe_context *pipe,
if (state->draw_data == NULL)
goto fail;
+ state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+
return state;
fail:
@@ -227,7 +227,7 @@ fail:
}
-void
+static void
softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -241,7 +241,7 @@ softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
}
-void
+static void
softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -253,3 +253,49 @@ softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
(state) ? state->draw_data : 0);
FREE(state);
}
+
+
+static void
+softpipe_set_constant_buffer(struct pipe_context *pipe,
+ uint shader, uint index,
+ struct pipe_resource *constants)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ unsigned size = constants ? constants->width0 : 0;
+ const void *data = constants ? softpipe_resource(constants)->data : NULL;
+
+ assert(shader < PIPE_SHADER_TYPES);
+
+ draw_flush(softpipe->draw);
+
+ /* note: reference counting */
+ pipe_resource_reference(&softpipe->constants[shader][index], constants);
+
+ if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
+ draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
+ }
+
+ softpipe->mapped_constants[shader][index] = data;
+ softpipe->const_buffer_size[shader][index] = size;
+
+ softpipe->dirty |= SP_NEW_CONSTANTS;
+}
+
+
+void
+softpipe_init_shader_funcs(struct pipe_context *pipe)
+{
+ pipe->create_fs_state = softpipe_create_fs_state;
+ pipe->bind_fs_state = softpipe_bind_fs_state;
+ pipe->delete_fs_state = softpipe_delete_fs_state;
+
+ pipe->create_vs_state = softpipe_create_vs_state;
+ pipe->bind_vs_state = softpipe_bind_vs_state;
+ pipe->delete_vs_state = softpipe_delete_vs_state;
+
+ pipe->create_gs_state = softpipe_create_gs_state;
+ pipe->bind_gs_state = softpipe_bind_gs_state;
+ pipe->delete_gs_state = softpipe_delete_gs_state;
+
+ pipe->set_constant_buffer = softpipe_set_constant_buffer;
+}
diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
new file mode 100644
index 00000000000..ddfa3ef765a
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_state_so.c
@@ -0,0 +1,140 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "sp_context.h"
+#include "sp_state.h"
+#include "sp_texture.h"
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "draw/draw_context.h"
+
+
+static void *
+softpipe_create_stream_output_state(struct pipe_context *pipe,
+ const struct pipe_stream_output_state *templ)
+{
+ struct sp_so_state *so;
+ so = (struct sp_so_state *) CALLOC_STRUCT(sp_so_state);
+
+ if (so) {
+ so->base.num_outputs = templ->num_outputs;
+ so->base.stride = templ->stride;
+ memcpy(so->base.output_buffer,
+ templ->output_buffer,
+ sizeof(int) * templ->num_outputs);
+ memcpy(so->base.register_index,
+ templ->register_index,
+ sizeof(int) * templ->num_outputs);
+ memcpy(so->base.register_mask,
+ templ->register_mask,
+ sizeof(ubyte) * templ->num_outputs);
+ }
+ return so;
+}
+
+
+static void
+softpipe_bind_stream_output_state(struct pipe_context *pipe,
+ void *so)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ struct sp_so_state *sp_so = (struct sp_so_state *) so;
+
+ softpipe->so = sp_so;
+
+ softpipe->dirty |= SP_NEW_SO;
+
+ if (sp_so)
+ draw_set_so_state(softpipe->draw, &sp_so->base);
+}
+
+
+static void
+softpipe_delete_stream_output_state(struct pipe_context *pipe, void *so)
+{
+ FREE( so );
+}
+
+
+static void
+softpipe_set_stream_output_buffers(struct pipe_context *pipe,
+ struct pipe_resource **buffers,
+ int *offsets,
+ int num_buffers)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ int i;
+ void *map_buffers[PIPE_MAX_SO_BUFFERS];
+
+ assert(num_buffers <= PIPE_MAX_SO_BUFFERS);
+ if (num_buffers > PIPE_MAX_SO_BUFFERS)
+ num_buffers = PIPE_MAX_SO_BUFFERS;
+
+ softpipe->dirty |= SP_NEW_SO_BUFFERS;
+
+ for (i = 0; i < num_buffers; ++i) {
+ void *mapped;
+ struct softpipe_resource *res = softpipe_resource(buffers[i]);
+
+ if (!res) {
+ /* the whole call is invalid, bail out */
+ softpipe->so_target.num_buffers = 0;
+ draw_set_mapped_so_buffers(softpipe->draw, 0, 0);
+ return;
+ }
+
+ softpipe->so_target.buffer[i] = res;
+ softpipe->so_target.offset[i] = offsets[i];
+ softpipe->so_target.so_count[i] = 0;
+
+ mapped = res->data;
+ if (offsets[i] >= 0)
+ map_buffers[i] = ((char*)mapped) + offsets[i];
+ else {
+ /* this is a buffer append */
+ assert(!"appending not implemented");
+ map_buffers[i] = mapped;
+ }
+ }
+ softpipe->so_target.num_buffers = num_buffers;
+
+ draw_set_mapped_so_buffers(softpipe->draw, map_buffers, num_buffers);
+}
+
+
+
+void
+softpipe_init_streamout_funcs(struct pipe_context *pipe)
+{
+ pipe->create_stream_output_state = softpipe_create_stream_output_state;
+ pipe->bind_stream_output_state = softpipe_bind_stream_output_state;
+ pipe->delete_stream_output_state = softpipe_delete_stream_output_state;
+
+ pipe->set_stream_output_buffers = softpipe_set_stream_output_buffers;
+}
+
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index 462f4d2655e..7d8055f2baf 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -36,7 +36,7 @@
#include "draw/draw_context.h"
-void *
+static void *
softpipe_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
@@ -51,7 +51,8 @@ softpipe_create_vertex_elements_state(struct pipe_context *pipe,
return velems;
}
-void
+
+static void
softpipe_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{
@@ -66,13 +67,15 @@ softpipe_bind_vertex_elements_state(struct pipe_context *pipe,
draw_set_vertex_elements(softpipe->draw, sp_velems->count, sp_velems->velem);
}
-void
+
+static void
softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
-void
+
+static void
softpipe_set_vertex_buffers(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_buffer *buffers)
@@ -88,3 +91,30 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(softpipe->draw, count, buffers);
}
+
+
+static void
+softpipe_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+
+ if (ib)
+ memcpy(&softpipe->index_buffer, ib, sizeof(softpipe->index_buffer));
+ else
+ memset(&softpipe->index_buffer, 0, sizeof(softpipe->index_buffer));
+
+ draw_set_index_buffer(softpipe->draw, ib);
+}
+
+
+void
+softpipe_init_vertex_funcs(struct pipe_context *pipe)
+{
+ pipe->create_vertex_elements_state = softpipe_create_vertex_elements_state;
+ pipe->bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
+ pipe->delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
+
+ pipe->set_vertex_buffers = softpipe_set_vertex_buffers;
+ pipe->set_index_buffer = softpipe_set_index_buffer;
+}
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index b04c2a63ad6..55b27e60100 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -25,26 +25,14 @@
*
**************************************************************************/
-#include "util/u_rect.h"
+#include "util/u_surface.h"
#include "sp_context.h"
#include "sp_surface.h"
-
-static void
-sp_surface_copy(struct pipe_context *pipe,
- struct pipe_surface *dest, unsigned destx, unsigned desty,
- struct pipe_surface *src, unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
-{
- util_surface_copy(pipe, FALSE,
- dest, destx, desty,
- src, srcx, srcy,
- width, height);
-}
-
void
sp_init_surface_functions(struct softpipe_context *sp)
{
- sp->pipe.surface_copy = sp_surface_copy;
- sp->pipe.surface_fill = util_surface_fill;
+ sp->pipe.resource_copy_region = util_resource_copy_region;
+ sp->pipe.clear_render_target = util_clear_render_target;
+ sp->pipe.clear_depth_stencil = util_clear_depth_stencil;
}
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index ff83c66d8b2..088e48f81fe 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -71,7 +71,7 @@ lerp(float a, float v0, float v1)
/**
- * Do 2D/biliner interpolation of float values.
+ * Do 2D/bilinear interpolation of float values.
* v00, v10, v01 and v11 are typically four texture samples in a square/box.
* a and b are the horizontal and vertical interpolants.
* It's important that this function is inlined when compiled with
@@ -105,14 +105,14 @@ lerp_3d(float a, float b, float c,
/**
* Compute coord % size for repeat wrap modes.
- * Note that if coord is a signed integer, coord % size doesn't give
- * the right value for coord < 0 (in terms of texture repeat). Just
- * casting to unsigned fixes that.
+ * Note that if coord is negative, coord % size doesn't give the right
+ * value. To avoid that problem we add a large multiple of the size
+ * (rather than using a conditional).
*/
static INLINE int
repeat(int coord, unsigned size)
{
- return (int) ((unsigned) coord % size);
+ return (coord + size * 1024) % size;
}
@@ -656,7 +656,8 @@ get_texel_2d(const struct sp_sampler_varient *samp,
if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
y < 0 || y >= (int) u_minify(texture->height0, level)) {
- return samp->sampler->border_color;
+ return sp_tex_tile_cache_border_color(samp->cache,
+ samp->sampler->border_color);
}
else {
return get_texel_2d_no_border( samp, addr, x, y );
@@ -750,7 +751,8 @@ get_texel_3d(const struct sp_sampler_varient *samp,
if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
y < 0 || y >= (int) u_minify(texture->height0, level) ||
z < 0 || z >= (int) u_minify(texture->depth0, level)) {
- return samp->sampler->border_color;
+ return sp_tex_tile_cache_border_color(samp->cache,
+ samp->sampler->border_color);
}
else {
return get_texel_3d_no_border( samp, addr, x, y, z );
@@ -1785,6 +1787,7 @@ get_lambda_func(const union sp_sampler_key key)
case PIPE_TEXTURE_1D:
return compute_lambda_1d;
case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_RECT:
case PIPE_TEXTURE_CUBE:
return compute_lambda_2d;
case PIPE_TEXTURE_3D:
@@ -1809,6 +1812,7 @@ get_img_filter(const union sp_sampler_key key,
return img_filter_1d_linear;
break;
case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_RECT:
/* Try for fast path:
*/
if (key.bits.is_pot &&
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index fbce9e042ba..e817c0c8cf5 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -63,19 +63,21 @@ sp_create_tex_tile_cache( struct pipe_context *pipe )
void
sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
{
- uint pos;
+ if (tc) {
+ uint pos;
- for (pos = 0; pos < NUM_ENTRIES; pos++) {
- /*assert(tc->entries[pos].x < 0);*/
- }
- if (tc->transfer) {
- tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
- }
- if (tc->tex_trans) {
- tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
- }
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ /*assert(tc->entries[pos].x < 0);*/
+ }
+ if (tc->transfer) {
+ tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
+ }
+ if (tc->tex_trans) {
+ tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
+ }
- FREE( tc );
+ FREE( tc );
+ }
}
@@ -115,6 +117,20 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc)
}
}
+static boolean
+sp_tex_tile_is_compat_view(struct softpipe_tex_tile_cache *tc,
+ struct pipe_sampler_view *view)
+{
+ if (!view)
+ return FALSE;
+ return (tc->texture == view->texture &&
+ tc->format == view->format &&
+ tc->swizzle_r == view->swizzle_r &&
+ tc->swizzle_g == view->swizzle_g &&
+ tc->swizzle_b == view->swizzle_b &&
+ tc->swizzle_a == view->swizzle_a);
+}
+
/**
* Specify the sampler view to cache.
*/
@@ -127,7 +143,7 @@ sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
assert(!tc->transfer);
- if (tc->texture != texture) {
+ if (!sp_tex_tile_is_compat_view(tc, view)) {
pipe_resource_reference(&tc->texture, texture);
if (tc->tex_trans) {
@@ -282,3 +298,23 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
+/**
+ * Return the swizzled border color.
+ */
+const float *
+sp_tex_tile_cache_border_color(struct softpipe_tex_tile_cache *tc,
+ const float border_color[4])
+{
+ float rgba01[6];
+
+ COPY_4V(rgba01, border_color);
+ rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
+ rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
+
+ tc->swz_border_color[0] = rgba01[tc->swizzle_r];
+ tc->swz_border_color[1] = rgba01[tc->swizzle_g];
+ tc->swz_border_color[2] = rgba01[tc->swizzle_b];
+ tc->swz_border_color[3] = rgba01[tc->swizzle_a];
+
+ return tc->swz_border_color;
+}
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
index 0794ffa0c53..05f25133daa 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -90,6 +90,8 @@ struct softpipe_tex_tile_cache
unsigned format;
struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */
+
+ float swz_border_color[4]; /**< swizzled border color */
};
@@ -154,7 +156,9 @@ sp_get_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
-
+const float *
+sp_tex_tile_cache_border_color(struct softpipe_tex_tile_cache *tc,
+ const float border_color[4]);
#endif /* SP_TEX_TILE_CACHE_H */
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 7aa85559b23..4e6123fbd07 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -343,11 +343,15 @@ softpipe_get_transfer(struct pipe_context *pipe,
if (spt) {
struct pipe_transfer *pt = &spt->base;
enum pipe_format format = resource->format;
+ const unsigned hgt = u_minify(spr->base.height0, sr.level);
+ const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
+
pipe_resource_reference(&pt->resource, resource);
pt->sr = sr;
pt->usage = usage;
pt->box = *box;
pt->stride = spr->stride[sr.level];
+ pt->slice_stride = pt->stride * nblocksy;
spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z);
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index f4db6f6ef00..aa76b8aa1ec 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -38,6 +38,8 @@
#include "util/u_tile.h"
#include "sp_tile_cache.h"
+static struct softpipe_cached_tile *
+sp_alloc_tile(struct softpipe_tile_cache *tc);
/**
@@ -94,9 +96,19 @@ sp_create_tile_cache( struct pipe_context *pipe )
if (tc) {
tc->pipe = pipe;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
- tc->entries[pos].addr.bits.invalid = 1;
+ tc->tile_addrs[pos].bits.invalid = 1;
+ }
+ tc->last_tile_addr.bits.invalid = 1;
+
+ /* this allocation allows us to guarantee that allocation
+ * failures are never fatal later
+ */
+ tc->tile = MALLOC_STRUCT( softpipe_cached_tile );
+ if (!tc->tile)
+ {
+ FREE(tc);
+ return NULL;
}
- tc->last_tile = &tc->entries[0]; /* any tile */
/* XXX this code prevents valgrind warnings about use of uninitialized
* memory in programs that don't clear the surface before rendering.
@@ -115,16 +127,21 @@ sp_create_tile_cache( struct pipe_context *pipe )
void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
{
- uint pos;
+ if (tc) {
+ uint pos;
- for (pos = 0; pos < NUM_ENTRIES; pos++) {
- /*assert(tc->entries[pos].x < 0);*/
- }
- if (tc->transfer) {
- tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
- }
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ /*assert(tc->entries[pos].x < 0);*/
+ FREE( tc->entries[pos] );
+ }
+ FREE( tc->tile );
+
+ if (tc->transfer) {
+ tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
+ }
- FREE( tc );
+ FREE( tc );
+ }
}
@@ -283,8 +300,15 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
uint numCleared = 0;
assert(pt->resource);
+ if (!tc->tile)
+ tc->tile = sp_alloc_tile(tc);
+
/* clear the scratch tile to the clear value */
- clear_tile(&tc->tile, pt->resource->format, tc->clear_val);
+ if (tc->depth_stencil) {
+ clear_tile(tc->tile, pt->resource->format, tc->clear_val);
+ } else {
+ clear_tile_rgba(tc->tile, pt->resource->format, tc->clear_color);
+ }
/* push the tile to all positions marked as clear */
for (y = 0; y < h; y += TILE_SIZE) {
@@ -292,11 +316,18 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
union tile_address addr = tile_address(x, y);
if (is_clear_flag_set(tc->clear_flags, addr)) {
- pipe_put_tile_raw(tc->pipe,
- pt,
- x, y, TILE_SIZE, TILE_SIZE,
- tc->tile.data.color32, 0/*STRIDE*/);
-
+ /* write the scratch tile to the surface */
+ if (tc->depth_stencil) {
+ pipe_put_tile_raw(tc->pipe,
+ pt,
+ x, y, TILE_SIZE, TILE_SIZE,
+ tc->tile->data.any, 0/*STRIDE*/);
+ }
+ else {
+ pipe_put_tile_rgba(tc->pipe, pt,
+ x, y, TILE_SIZE, TILE_SIZE,
+ (float *) tc->tile->data.color);
+ }
numCleared++;
}
}
@@ -310,6 +341,27 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
#endif
}
+static void
+sp_flush_tile(struct softpipe_tile_cache* tc, unsigned pos)
+{
+ if (!tc->tile_addrs[pos].bits.invalid) {
+ if (tc->depth_stencil) {
+ pipe_put_tile_raw(tc->pipe, tc->transfer,
+ tc->tile_addrs[pos].bits.x * TILE_SIZE,
+ tc->tile_addrs[pos].bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
+ tc->entries[pos]->data.depth32, 0/*STRIDE*/);
+ }
+ else {
+ pipe_put_tile_rgba(tc->pipe, tc->transfer,
+ tc->tile_addrs[pos].bits.x * TILE_SIZE,
+ tc->tile_addrs[pos].bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
+ (float *) tc->entries[pos]->data.color);
+ }
+ tc->tile_addrs[pos].bits.invalid = 1; /* mark as empty */
+ }
+}
/**
* Flush the tile cache: write all dirty tiles back to the transfer.
@@ -324,28 +376,21 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc)
if (pt) {
/* caching a drawing transfer */
for (pos = 0; pos < NUM_ENTRIES; pos++) {
- struct softpipe_cached_tile *tile = tc->entries + pos;
- if (!tile->addr.bits.invalid) {
- if (tc->depth_stencil) {
- pipe_put_tile_raw(tc->pipe, pt,
- tile->addr.bits.x * TILE_SIZE,
- tile->addr.bits.y * TILE_SIZE,
- TILE_SIZE, TILE_SIZE,
- tile->data.depth32, 0/*STRIDE*/);
- }
- else {
- pipe_put_tile_rgba(tc->pipe, pt,
- tile->addr.bits.x * TILE_SIZE,
- tile->addr.bits.y * TILE_SIZE,
- TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
- }
- tile->addr.bits.invalid = 1; /* mark as empty */
- inuse++;
+ struct softpipe_cached_tile *tile = tc->entries[pos];
+ if (!tile)
+ {
+ assert(tc->tile_addrs[pos].bits.invalid);
+ continue;
}
+
+ sp_flush_tile(tc, pos);
+ ++inuse;
}
sp_tile_cache_flush_clear(tc);
+
+
+ tc->last_tile_addr.bits.invalid = 1;
}
#if 0
@@ -353,6 +398,38 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc)
#endif
}
+static struct softpipe_cached_tile *
+sp_alloc_tile(struct softpipe_tile_cache *tc)
+{
+ struct softpipe_cached_tile * tile = MALLOC_STRUCT(softpipe_cached_tile);
+ if (!tile)
+ {
+ /* in this case, steal an existing tile */
+ if (!tc->tile)
+ {
+ unsigned pos;
+ for (pos = 0; pos < NUM_ENTRIES; ++pos) {
+ if (!tc->entries[pos])
+ continue;
+
+ sp_flush_tile(tc, pos);
+ tc->tile = tc->entries[pos];
+ tc->entries[pos] = NULL;
+ break;
+ }
+
+ /* this should never happen */
+ if (!tc->tile)
+ abort();
+ }
+
+ tile = tc->tile;
+ tc->tile = NULL;
+
+ tc->last_tile_addr.bits.invalid = 1;
+ }
+ return tile;
+}
/**
* Get a tile from the cache.
@@ -367,30 +444,35 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
/* cache pos/entry: */
const int pos = CACHE_POS(addr.bits.x,
addr.bits.y);
- struct softpipe_cached_tile *tile = tc->entries + pos;
+ struct softpipe_cached_tile *tile = tc->entries[pos];
+
+ if (!tile) {
+ tile = sp_alloc_tile(tc);
+ tc->entries[pos] = tile;
+ }
- if (addr.value != tile->addr.value) {
+ if (addr.value != tc->tile_addrs[pos].value) {
assert(pt->resource);
- if (tile->addr.bits.invalid == 0) {
+ if (tc->tile_addrs[pos].bits.invalid == 0) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
pipe_put_tile_raw(tc->pipe, pt,
- tile->addr.bits.x * TILE_SIZE,
- tile->addr.bits.y * TILE_SIZE,
+ tc->tile_addrs[pos].bits.x * TILE_SIZE,
+ tc->tile_addrs[pos].bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe_put_tile_rgba(tc->pipe, pt,
- tile->addr.bits.x * TILE_SIZE,
- tile->addr.bits.y * TILE_SIZE,
+ tc->tile_addrs[pos].bits.x * TILE_SIZE,
+ tc->tile_addrs[pos].bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
}
- tile->addr = addr;
+ tc->tile_addrs[pos] = addr;
if (is_clear_flag_set(tc->clear_flags, addr)) {
/* don't get tile from framebuffer, just clear it */
@@ -406,15 +488,15 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
/* get new tile data from transfer */
if (tc->depth_stencil) {
pipe_get_tile_raw(tc->pipe, pt,
- tile->addr.bits.x * TILE_SIZE,
- tile->addr.bits.y * TILE_SIZE,
+ tc->tile_addrs[pos].bits.x * TILE_SIZE,
+ tc->tile_addrs[pos].bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe_get_tile_rgba(tc->pipe, pt,
- tile->addr.bits.x * TILE_SIZE,
- tile->addr.bits.y * TILE_SIZE,
+ tc->tile_addrs[pos].bits.x * TILE_SIZE,
+ tc->tile_addrs[pos].bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
@@ -422,6 +504,7 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
}
tc->last_tile = tile;
+ tc->last_tile_addr = addr;
return tile;
}
@@ -451,7 +534,7 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba,
memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
for (pos = 0; pos < NUM_ENTRIES; pos++) {
- struct softpipe_cached_tile *tile = tc->entries + pos;
- tile->addr.bits.invalid = 1;
+ tc->tile_addrs[pos].bits.invalid = 1;
}
+ tc->last_tile_addr.bits.invalid = 1;
}
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index e03d53eb24e..031c7c1ea5c 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -57,7 +57,6 @@ union tile_address {
struct softpipe_cached_tile
{
- union tile_address addr;
union {
float color[TILE_SIZE][TILE_SIZE][4];
uint color32[TILE_SIZE][TILE_SIZE];
@@ -83,14 +82,16 @@ struct softpipe_tile_cache
struct pipe_transfer *transfer;
void *transfer_map;
- struct softpipe_cached_tile entries[NUM_ENTRIES];
+ union tile_address tile_addrs[NUM_ENTRIES];
+ struct softpipe_cached_tile *entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
float clear_color[4]; /**< for color bufs */
uint clear_val; /**< for z+stencil, or packed color clear value */
boolean depth_stencil; /**< Is the surface a depth/stencil format? */
- struct softpipe_cached_tile tile; /**< scratch tile for clears */
+ struct softpipe_cached_tile *tile; /**< scratch tile for clears */
+ union tile_address last_tile_addr;
struct softpipe_cached_tile *last_tile; /**< most recently retrieved tile */
};
@@ -147,7 +148,7 @@ sp_get_cached_tile(struct softpipe_tile_cache *tc,
{
union tile_address addr = tile_address( x, y );
- if (tc->last_tile->addr.value == addr.value)
+ if (tc->last_tile_addr.value == addr.value)
return tc->last_tile;
return sp_find_cached_tile( tc, addr );