aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile7
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c63
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c28
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c50
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.h21
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_limits.h (renamed from src/gallium/drivers/llvmpipe/lp_tile_size.h)37
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c33
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c122
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h48
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c70
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c76
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h139
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_blend.c46
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_clip.c31
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c48
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_rasterizer.c19
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c30
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_surface.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vs.c23
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c28
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_blend.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.c (renamed from src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c)0
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c136
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_image.c22
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_image.h8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_soa.h11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_soa.py45
-rwxr-xr-xsrc/gallium/drivers/llvmpipe/sp2lp.sh34
39 files changed, 637 insertions, 613 deletions
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 4a3fc036c49..4ea367597e1 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -40,7 +40,7 @@ C_SOURCES = \
lp_state_vertex.c \
lp_state_vs.c \
lp_surface.c \
- lp_tex_sample_llvm.c \
+ lp_tex_sample.c \
lp_texture.c \
lp_tile_image.c \
lp_tile_soa.c
@@ -58,8 +58,9 @@ include ../../Makefile.template
lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxiliary/util/u_format_pack.py ../../auxiliary/util/u_format.csv
python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@
-
-LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium libllvmpipe.a
+LDFLAGS += $(LLVM_LDFLAGS)
+LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium libllvmpipe.a $(LLVM_LIBS)
+LD=g++
$(PROGS): lp_test_main.o libllvmpipe.a
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index b9e9826e2a3..2911cf2179a 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -60,7 +60,7 @@ llvmpipe = env.ConvenienceLibrary(
'lp_state_vertex.c',
'lp_state_vs.c',
'lp_surface.c',
- 'lp_tex_sample_llvm.c',
+ 'lp_tex_sample.c',
'lp_texture.c',
'lp_tile_image.c',
'lp_tile_soa.c',
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index f7cf06d8d46..32b80d3a9f6 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -97,63 +97,24 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.winsys = screen->winsys;
llvmpipe->pipe.screen = screen;
llvmpipe->pipe.priv = priv;
- llvmpipe->pipe.destroy = llvmpipe_destroy;
-
- /* state setters */
- llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state;
- llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state;
- llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
-
- llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
- llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states;
- llvmpipe->pipe.bind_vertex_sampler_states = llvmpipe_bind_vertex_sampler_states;
- llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
-
- llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
- llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state;
- llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state;
-
- llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
- llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state;
- llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
-
- llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
- llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state;
- llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
-
- llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state;
- llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
- llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
- llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
- llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
- llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
-
- llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
- llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
- llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
- llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
+ /* Init the pipe context methods */
+ llvmpipe->pipe.destroy = llvmpipe_destroy;
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
- llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
- llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
- llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
- llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
- llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
- llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
- llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
-
- llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
-
- llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
- llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
- llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
-
llvmpipe->pipe.clear = llvmpipe_clear;
llvmpipe->pipe.flush = llvmpipe_flush;
-
+ llvmpipe_init_blend_funcs(llvmpipe);
+ llvmpipe_init_clip_funcs(llvmpipe);
+ llvmpipe_init_draw_funcs(llvmpipe);
+ llvmpipe_init_sampler_funcs(llvmpipe);
llvmpipe_init_query_funcs( llvmpipe );
+ llvmpipe_init_vertex_funcs(llvmpipe);
+ llvmpipe_init_fs_funcs(llvmpipe);
+ llvmpipe_init_vs_funcs(llvmpipe);
+ llvmpipe_init_rasterizer_funcs(llvmpipe);
llvmpipe_init_context_resource_funcs( &llvmpipe->pipe );
+ llvmpipe_init_surface_functions(llvmpipe);
/*
* Create drawing context and plug our rendering stage into it.
@@ -186,8 +147,6 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe);
#endif
- lp_init_surface_functions(llvmpipe);
-
lp_reset_counters();
return &llvmpipe->pipe;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 4848101ffb8..4e597b24796 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -94,9 +94,6 @@ struct llvmpipe_context {
/** Vertex format */
struct vertex_info vertex_info;
- /** Which vertex shader output slot contains point size */
- int psize_slot;
-
/** The tiling engine */
struct lp_setup_context *setup;
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 0b63e1c889e..98780d7631b 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -42,20 +42,12 @@
-void
-llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count)
-{
- llvmpipe_draw_elements(pipe, NULL, 0, 0, mode, start, count);
-}
-
-
/**
* Draw vertex arrays, with optional indexing.
* Basically, map the vertex buffers (and drawing surfaces), then hand off
* the drawing to the 'draw' module.
*/
-void
+static void
llvmpipe_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
@@ -115,7 +107,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
@@ -128,3 +120,19 @@ llvmpipe_draw_elements(struct pipe_context *pipe,
mode, start, count );
}
+
+static void
+llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
+ unsigned start, unsigned count)
+{
+ llvmpipe_draw_elements(pipe, NULL, 0, 0, mode, start, count);
+}
+
+
+void
+llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
+ llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
+ llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 3627dbd759c..644b821957a 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -96,41 +96,40 @@ llvmpipe_flush( struct pipe_context *pipe,
/**
* Flush context if necessary.
*
- * TODO: move this logic to an auxiliary library?
+ * Returns FALSE if it would have block, but do_not_block was set, TRUE
+ * otherwise.
*
- * FIXME: We must implement DISCARD/DONTBLOCK/UNSYNCHRONIZED/etc for
- * textures to avoid blocking.
+ * TODO: move this logic to an auxiliary library?
*/
boolean
-llvmpipe_flush_texture(struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned face,
- unsigned level,
- unsigned flush_flags,
- boolean read_only,
- boolean cpu_access,
- boolean do_not_flush)
+llvmpipe_flush_resource(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned face,
+ unsigned level,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_block)
{
unsigned referenced;
- referenced = pipe->is_resource_referenced(pipe, texture, face, level);
+ referenced = pipe->is_resource_referenced(pipe, resource, face, level);
if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
- if (do_not_flush)
- return FALSE;
-
- /*
- * TODO: The semantics of these flush flags are too obtuse. They should
- * disappear and the pipe driver should just ensure that all visible
- * side-effects happen when they need to happen.
- */
- if (referenced & PIPE_REFERENCED_FOR_WRITE)
- flush_flags |= PIPE_FLUSH_RENDER_CACHE;
+ if (resource->target != PIPE_BUFFER) {
+ /*
+ * TODO: The semantics of these flush flags are too obtuse. They should
+ * disappear and the pipe driver should just ensure that all visible
+ * side-effects happen when they need to happen.
+ */
+ if (referenced & PIPE_REFERENCED_FOR_WRITE)
+ flush_flags |= PIPE_FLUSH_RENDER_CACHE;
- if (referenced & PIPE_REFERENCED_FOR_READ)
- flush_flags |= PIPE_FLUSH_TEXTURE_CACHE;
+ if (referenced & PIPE_REFERENCED_FOR_READ)
+ flush_flags |= PIPE_FLUSH_TEXTURE_CACHE;
+ }
if (cpu_access) {
/*
@@ -139,6 +138,9 @@ llvmpipe_flush_texture(struct pipe_context *pipe,
struct pipe_fence_handle *fence = NULL;
+ if (do_not_block)
+ return FALSE;
+
pipe->flush(pipe, flush_flags, &fence);
if (fence) {
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h
index 2375d22b854..7b605681a93 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.h
+++ b/src/gallium/drivers/llvmpipe/lp_flush.h
@@ -33,17 +33,18 @@
struct pipe_context;
struct pipe_fence_handle;
-void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
- struct pipe_fence_handle **fence);
+void
+llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
+ struct pipe_fence_handle **fence);
boolean
-llvmpipe_flush_texture(struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned face,
- unsigned level,
- unsigned flush_flags,
- boolean read_only,
- boolean cpu_access,
- boolean do_not_flush);
+llvmpipe_flush_resource(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned face,
+ unsigned level,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_block);
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 8690941a507..466a2f54fbe 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -171,15 +171,6 @@ lp_jit_screen_cleanup(struct llvmpipe_screen *screen)
void
lp_jit_screen_init(struct llvmpipe_screen *screen)
{
- util_cpu_detect();
-
-#if 0
- /* For simulating less capable machines */
- util_cpu_caps.has_sse3 = 0;
- util_cpu_caps.has_ssse3 = 0;
- util_cpu_caps.has_sse4_1 = 0;
-#endif
-
lp_build_init();
screen->module = lp_build_module;
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_size.h b/src/gallium/drivers/llvmpipe/lp_limits.h
index f0b983c0632..4102a9df67c 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_size.h
+++ b/src/gallium/drivers/llvmpipe/lp_limits.h
@@ -25,8 +25,12 @@
*
**************************************************************************/
-#ifndef LP_TILE_SIZE_H
-#define LP_TILE_SIZE_H
+/**
+ * Implementation limits for LLVMpipe driver.
+ */
+
+#ifndef LP_LIMITS_H
+#define LP_LIMITS_H
/**
@@ -36,4 +40,31 @@
#define TILE_SIZE (1 << TILE_ORDER)
-#endif
+/**
+ * Max texture sizes
+ */
+#define LP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K for now */
+#define LP_MAX_TEXTURE_3D_LEVELS 10 /* 512 x 512 x 512 for now */
+
+
+/** This must be the larger of LP_MAX_TEXTURE_2D/3D_LEVELS */
+#define LP_MAX_TEXTURE_LEVELS LP_MAX_TEXTURE_2D_LEVELS
+
+
+/**
+ * Max drawing surface size is the max texture size
+ */
+#define LP_MAX_HEIGHT (1 << (LP_MAX_TEXTURE_LEVELS - 1))
+#define LP_MAX_WIDTH (1 << (LP_MAX_TEXTURE_LEVELS - 1))
+
+
+#define LP_MAX_THREADS 8
+
+
+/**
+ * Max bytes per scene. This may be replaced by a runtime parameter.
+ */
+#define LP_MAX_SCENE_SIZE (512 * 1024 * 1024)
+
+
+#endif /* LP_LIMITS_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 4046701b85a..a00a592f2fe 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -28,7 +28,6 @@
#include <limits.h>
#include "util/u_memory.h"
#include "util/u_math.h"
-#include "util/u_cpu_detect.h"
#include "util/u_surface.h"
#include "lp_scene_queue.h"
@@ -122,9 +121,11 @@ lp_rast_end( struct lp_rasterizer *rast )
rast->curr_scene = NULL;
+#ifdef DEBUG
if (0)
- printf("Post render scene: tile read: %d tile write: %d\n",
- tile_read_count, tile_write_count);
+ debug_printf("Post render scene: tile unswizzle: %u tile swizzle: %u\n",
+ lp_tile_unswizzle_count, lp_tile_swizzle_count);
+#endif
}
@@ -869,20 +870,6 @@ create_rast_threads(struct lp_rasterizer *rast)
{
unsigned i;
-#ifdef PIPE_OS_WINDOWS
- /* Multithreading not supported on windows until conditions and barriers are
- * properly implemented. */
- rast->num_threads = 0;
-#else
-#ifdef PIPE_OS_EMBEDDED
- rast->num_threads = 0;
-#else
- rast->num_threads = util_cpu_caps.nr_cpus;
-#endif
- rast->num_threads = debug_get_num_option("LP_NUM_THREADS", rast->num_threads);
- rast->num_threads = MIN2(rast->num_threads, MAX_THREADS);
-#endif
-
/* NOTE: if num_threads is zero, we won't use any threads */
for (i = 0; i < rast->num_threads; i++) {
pipe_semaphore_init(&rast->tasks[i].work_ready, 0);
@@ -895,12 +882,12 @@ create_rast_threads(struct lp_rasterizer *rast)
/**
- * Create new lp_rasterizer.
- * \param empty the queue to put empty scenes on after we've finished
- * processing them.
+ * Create new lp_rasterizer. If num_threads is zero, don't create any
+ * new threads, do rendering synchronously.
+ * \param num_threads number of rasterizer threads to create
*/
struct lp_rasterizer *
-lp_rast_create( void )
+lp_rast_create( unsigned num_threads )
{
struct lp_rasterizer *rast;
unsigned i;
@@ -917,6 +904,8 @@ lp_rast_create( void )
task->thread_index = i;
}
+ rast->num_threads = num_threads;
+
create_rast_threads(rast);
/* for synchronizing rasterization threads */
@@ -955,6 +944,8 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
/* for synchronizing rasterization threads */
pipe_barrier_destroy( &rast->barrier );
+ lp_scene_queue_destroy(rast->full_scenes);
+
FREE(rast);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index a0ecb2fc47f..e2f6f926779 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -134,7 +134,7 @@ struct lp_rast_triangle {
struct lp_rasterizer *
-lp_rast_create( void );
+lp_rast_create( unsigned num_threads );
void
lp_rast_destroy( struct lp_rasterizer * );
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 8bf2b92a6ab..5884d12721e 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -35,9 +35,7 @@
#include "lp_scene.h"
#include "lp_texture.h"
#include "lp_tile_soa.h"
-
-
-#define MAX_THREADS 8 /* XXX probably temporary here */
+#include "lp_limits.h"
struct lp_rasterizer;
@@ -107,16 +105,16 @@ struct lp_rasterizer
* (potentially) shared, these empty scenes should be returned to
* the context which created them rather than retained here.
*/
- struct lp_scene_queue *empty_scenes;
+ /* struct lp_scene_queue *empty_scenes; */
/** The scene currently being rasterized by the threads */
struct lp_scene *curr_scene;
/** A task object for each rasterization thread */
- struct lp_rasterizer_task tasks[MAX_THREADS];
+ struct lp_rasterizer_task tasks[LP_MAX_THREADS];
unsigned num_threads;
- pipe_thread threads[MAX_THREADS];
+ pipe_thread threads[LP_MAX_THREADS];
/** For synchronizing the rasterization threads */
pipe_barrier barrier;
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 182e7cb2303..1482a777ff8 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -32,9 +32,20 @@
#include "util/u_surface.h"
#include "lp_scene.h"
#include "lp_scene_queue.h"
-#include "lp_debug.h"
+/** List of texture references */
+struct texture_ref {
+ struct pipe_resource *texture;
+ struct texture_ref *prev, *next; /**< linked list w/ u_simple_list.h */
+};
+
+
+
+/**
+ * Create a new scene object.
+ * \param queue the queue to put newly rendered/emptied scenes into
+ */
struct lp_scene *
lp_scene_create( struct pipe_context *pipe,
struct lp_scene_queue *queue )
@@ -57,7 +68,7 @@ lp_scene_create( struct pipe_context *pipe,
scene->data.head =
scene->data.tail = CALLOC_STRUCT(data_block);
- make_empty_list(&scene->textures);
+ make_empty_list(&scene->resources);
pipe_mutex_init(scene->mutex);
@@ -66,7 +77,7 @@ lp_scene_create( struct pipe_context *pipe,
/**
- * Free all data associated with the given scene, and free(scene).
+ * Free all data associated with the given scene, and the scene itself.
*/
void
lp_scene_destroy(struct lp_scene *scene)
@@ -178,15 +189,17 @@ lp_scene_reset(struct lp_scene *scene )
/* Release texture refs
*/
{
- struct texture_ref *ref, *next, *ref_list = &scene->textures;
+ struct resource_ref *ref, *next, *ref_list = &scene->resources;
for (ref = ref_list->next; ref != ref_list; ref = next) {
next = next_elem(ref);
- pipe_resource_reference(&ref->texture, NULL);
+ pipe_resource_reference(&ref->resource, NULL);
FREE(ref);
}
make_empty_list(ref_list);
}
+ scene->scene_size = 0;
+
scene->has_color_clear = FALSE;
scene->has_depth_clear = FALSE;
}
@@ -218,7 +231,10 @@ lp_bin_new_data_block( struct data_block_list *list )
}
-/** Return number of bytes used for all bin data within a scene */
+/**
+ * Return number of bytes used for all bin data within a scene.
+ * This does not include resources (textures) referenced by the scene.
+ */
unsigned
lp_scene_data_size( const struct lp_scene *scene )
{
@@ -247,32 +263,34 @@ lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y )
/**
- * Add a reference to a texture by the scene.
+ * Add a reference to a resource by the scene.
*/
void
-lp_scene_texture_reference( struct lp_scene *scene,
- struct pipe_resource *texture )
+lp_scene_add_resource_reference(struct lp_scene *scene,
+ struct pipe_resource *resource)
{
- struct texture_ref *ref = CALLOC_STRUCT(texture_ref);
+ struct resource_ref *ref = CALLOC_STRUCT(resource_ref);
if (ref) {
- struct texture_ref *ref_list = &scene->textures;
- pipe_resource_reference(&ref->texture, texture);
+ struct resource_ref *ref_list = &scene->resources;
+ pipe_resource_reference(&ref->resource, resource);
insert_at_tail(ref_list, ref);
}
+
+ scene->scene_size += llvmpipe_resource_size(resource);
}
/**
- * Does this scene have a reference to the given texture?
+ * Does this scene have a reference to the given resource?
*/
boolean
-lp_scene_is_resource_referenced( const struct lp_scene *scene,
- const struct pipe_resource *texture )
+lp_scene_is_resource_referenced(const struct lp_scene *scene,
+ const struct pipe_resource *resource)
{
- const struct texture_ref *ref_list = &scene->textures;
- const struct texture_ref *ref;
+ const struct resource_ref *ref_list = &scene->resources;
+ const struct resource_ref *ref;
foreach (ref, ref_list) {
- if (ref->texture == texture)
+ if (ref->resource == resource)
return TRUE;
}
return FALSE;
@@ -393,61 +411,6 @@ end:
}
-
-/**
- * Prepare this scene for the rasterizer.
- * Map the framebuffer surfaces. Initialize the 'rast' state.
- */
-static boolean
-lp_scene_map_buffers( struct lp_scene *scene )
-{
- LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
-
- /* XXX framebuffer surfaces are no longer mapped here */
- /* XXX move all map/unmap stuff into rast module... */
-
- return TRUE;
-}
-
-
-
-/**
- * Called after rasterizer as finished rasterizing a scene.
- *
- * We want to call this from the pipe_context's current thread to
- * avoid having to have mutexes on the transfer functions.
- */
-static void
-lp_scene_unmap_buffers( struct lp_scene *scene )
-{
-#if 0
- unsigned i;
-
- for (i = 0; i < scene->fb.nr_cbufs; i++) {
- if (scene->cbuf_map[i]) {
- struct pipe_surface *cbuf = scene->fb.cbufs[i];
- llvmpipe_resource_unmap(cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice);
- scene->cbuf_map[i] = NULL;
- }
- }
-
- if (scene->zsbuf_map) {
- struct pipe_surface *zsbuf = scene->fb.zsbuf;
- llvmpipe_resource_unmap(zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice);
- scene->zsbuf_map = NULL;
- }
-#endif
-
- util_unreference_framebuffer_state( &scene->fb );
-}
-
-
void lp_scene_begin_binning( struct lp_scene *scene,
struct pipe_framebuffer_state *fb )
{
@@ -464,8 +427,7 @@ void lp_scene_begin_binning( struct lp_scene *scene,
void lp_scene_rasterize( struct lp_scene *scene,
- struct lp_rasterizer *rast,
- boolean write_depth )
+ struct lp_rasterizer *rast )
{
if (0) {
unsigned x, y;
@@ -479,11 +441,6 @@ void lp_scene_rasterize( struct lp_scene *scene,
}
}
- scene->write_depth = (scene->fb.zsbuf != NULL &&
- write_depth);
-
- lp_scene_map_buffers( scene );
-
/* Enqueue the scene for rasterization, then immediately wait for
* it to finish.
*/
@@ -494,6 +451,9 @@ void lp_scene_rasterize( struct lp_scene *scene,
* transfers become per-context:
*/
lp_rast_finish( rast );
- lp_scene_unmap_buffers( scene );
+
+ util_unreference_framebuffer_state( &scene->fb );
+
+ /* put scene into the empty list */
lp_scene_enqueue( scene->empty_queue, scene );
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index ac0717db6a1..9467cd6f16d 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -44,10 +44,8 @@ struct lp_scene_queue;
/* We're limited to 2K by 2K for 32bit fixed point rasterization.
* Will need a 64-bit version for larger framebuffers.
*/
-#define MAXHEIGHT 2048
-#define MAXWIDTH 2048
-#define TILES_X (MAXWIDTH / TILE_SIZE)
-#define TILES_Y (MAXHEIGHT / TILE_SIZE)
+#define TILES_X (LP_MAX_WIDTH / TILE_SIZE)
+#define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
#define CMD_BLOCK_MAX 128
@@ -97,10 +95,10 @@ struct data_block_list {
};
-/** List of texture references */
-struct texture_ref {
- struct pipe_resource *texture;
- struct texture_ref *prev, *next; /**< linked list w/ u_simple_list.h */
+/** List of resource references */
+struct resource_ref {
+ struct pipe_resource *resource;
+ struct resource_ref *prev, *next; /**< linked list w/ u_simple_list.h */
};
@@ -118,10 +116,14 @@ struct lp_scene {
/** the framebuffer to render the scene into */
struct pipe_framebuffer_state fb;
- /** list of textures referenced by the scene commands */
- struct texture_ref textures;
+ /** list of resources referenced by the scene commands */
+ struct resource_ref resources;
+
+ /** Approx memory used by the scene (in bytes). This includes the
+ * shared and per-tile bins plus any referenced resources/textures.
+ */
+ unsigned scene_size;
- boolean write_depth;
boolean has_color_clear;
boolean has_depth_clear;
@@ -164,11 +166,11 @@ unsigned lp_scene_data_size( const struct lp_scene *scene );
unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y );
-void lp_scene_texture_reference( struct lp_scene *scene,
- struct pipe_resource *texture );
+void lp_scene_add_resource_reference(struct lp_scene *scene,
+ struct pipe_resource *resource);
-boolean lp_scene_is_resource_referenced( const struct lp_scene *scene,
- const struct pipe_resource *texture );
+boolean lp_scene_is_resource_referenced(const struct lp_scene *scene,
+ const struct pipe_resource *resource );
/**
@@ -184,6 +186,8 @@ lp_scene_alloc( struct lp_scene *scene, unsigned size)
lp_bin_new_data_block( list );
}
+ scene->scene_size += size;
+
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
@@ -206,6 +210,8 @@ lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
lp_bin_new_data_block( list );
}
+ scene->scene_size += size;
+
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
@@ -222,6 +228,7 @@ static INLINE void
lp_scene_putback_data( struct lp_scene *scene, unsigned size)
{
struct data_block_list *list = &scene->data;
+ scene->scene_size -= size;
assert(list->tail->used >= size);
list->tail->used -= size;
}
@@ -304,11 +311,18 @@ lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y );
void
lp_scene_rasterize( struct lp_scene *scene,
- struct lp_rasterizer *rast,
- boolean write_depth );
+ struct lp_rasterizer *rast );
void
lp_scene_begin_binning( struct lp_scene *scene,
struct pipe_framebuffer_state *fb );
+
+static INLINE unsigned
+lp_scene_get_size(const struct lp_scene *scene)
+{
+ return scene->scene_size;
+}
+
+
#endif /* LP_BIN_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 6d309c6b647..111eedc4f23 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -27,6 +27,8 @@
#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_cpu_detect.h"
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
#include "pipe/p_defines.h"
@@ -39,6 +41,7 @@
#include "lp_context.h"
#include "lp_debug.h"
#include "lp_public.h"
+#include "lp_limits.h"
#include "state_tracker/sw_winsys.h"
@@ -94,6 +97,8 @@ llvmpipe_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:
@@ -165,7 +170,7 @@ static boolean
llvmpipe_is_format_supported( struct pipe_screen *_screen,
enum pipe_format format,
enum pipe_texture_target target,
- unsigned tex_usage,
+ unsigned bind,
unsigned geom_flags )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
@@ -173,7 +178,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
const struct util_format_description *format_desc;
format_desc = util_format_description(format);
- if(!format_desc)
+ if (!format_desc)
return FALSE;
assert(target == PIPE_TEXTURE_1D ||
@@ -181,45 +186,42 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
target == PIPE_TEXTURE_3D ||
target == PIPE_TEXTURE_CUBE);
- switch(format) {
- case PIPE_FORMAT_DXT1_RGB:
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- return util_format_s3tc_enabled;
- default:
- break;
- }
-
- if(tex_usage & PIPE_BIND_RENDER_TARGET) {
- if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
+ if (bind & PIPE_BIND_RENDER_TARGET) {
+ if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
- if(format_desc->block.width != 1 ||
- format_desc->block.height != 1)
+ if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return FALSE;
- if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
- format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
+ if (format_desc->block.width != 1 ||
+ format_desc->block.height != 1)
return FALSE;
}
- if(tex_usage & (PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED)) {
- if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
+ if (bind & PIPE_BIND_DISPLAY_TARGET) {
+ if(!winsys->is_displaytarget_format_supported(winsys, bind, format))
return FALSE;
}
- if(tex_usage & PIPE_BIND_DEPTH_STENCIL) {
- if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
+ if (bind & PIPE_BIND_DEPTH_STENCIL) {
+ if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
+ return FALSE;
+
+ if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
/* FIXME: Temporary restriction. See lp_state_fs.c. */
- if(format_desc->block.bits != 32)
+ if (format_desc->block.bits != 32)
return FALSE;
}
+ if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
+ return util_format_s3tc_enabled;
+ }
+
+ /*
+ * Everything else should be supported by u_format.
+ */
return TRUE;
}
@@ -286,12 +288,26 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
screen->base.context_create = llvmpipe_create_context;
screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
- util_format_s3tc_init();
-
llvmpipe_init_screen_resource_funcs(&screen->base);
llvmpipe_init_screen_fence_funcs(&screen->base);
lp_jit_screen_init(screen);
+#ifdef PIPE_OS_WINDOWS
+ /* Multithreading not supported on windows until conditions and barriers are
+ * properly implemented. */
+ screen->num_threads = 0;
+#else
+#ifdef PIPE_OS_EMBEDDED
+ screen->num_threads = 0;
+#else
+ screen->num_threads = util_cpu_caps.nr_cpus;
+#endif
+ screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads);
+ screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS);
+#endif
+
+ util_format_s3tc_init();
+
return &screen->base;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index af25e043cc9..4f394326103 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -58,6 +58,8 @@ struct llvmpipe_screen
LLVMTypeRef context_ptr_type;
+ unsigned num_threads;
+
/* Increments whenever textures are modified. Contexts can track
* this.
*/
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 6be13c60a57..21509560084 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -74,6 +74,26 @@ lp_setup_get_current_scene(struct lp_setup_context *setup)
}
+/**
+ * Check if the size of the current scene has exceeded the limit.
+ * If so, flush/render it.
+ */
+static void
+setup_check_scene_size_and_flush(struct lp_setup_context *setup)
+{
+ if (setup->scene) {
+ struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ unsigned size = lp_scene_get_size(scene);
+
+ if (size > LP_MAX_SCENE_SIZE) {
+ /*printf("LLVMPIPE: scene size = %u, flushing.\n", size);*/
+ set_scene_state( setup, SETUP_FLUSHED );
+ /*assert(lp_scene_get_size(scene) == 0);*/
+ }
+ }
+}
+
+
static void
first_triangle( struct lp_setup_context *setup,
const float (*v0)[4],
@@ -132,14 +152,11 @@ static void reset_context( struct lp_setup_context *setup )
/** Rasterize all scene's bins */
static void
-lp_setup_rasterize_scene( struct lp_setup_context *setup,
- boolean write_depth )
+lp_setup_rasterize_scene( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
- lp_scene_rasterize(scene,
- setup->rast,
- write_depth);
+ lp_scene_rasterize(scene, setup->rast);
reset_context( setup );
@@ -190,7 +207,7 @@ execute_clears( struct lp_setup_context *setup )
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
begin_binning( setup );
- lp_setup_rasterize_scene( setup, TRUE );
+ lp_setup_rasterize_scene( setup );
}
@@ -221,7 +238,7 @@ set_scene_state( struct lp_setup_context *setup,
if (old_state == SETUP_CLEARED)
execute_clears( setup );
else
- lp_setup_rasterize_scene( setup, TRUE );
+ lp_setup_rasterize_scene( setup );
break;
default:
@@ -243,7 +260,7 @@ lp_setup_flush( struct lp_setup_context *setup,
if (setup->scene) {
struct lp_scene *scene = lp_setup_get_current_scene(setup);
- union lp_rast_cmd_arg dummy;
+ union lp_rast_cmd_arg dummy = {0};
if (flags & (PIPE_FLUSH_SWAPBUFFERS |
PIPE_FLUSH_FRAME)) {
@@ -343,20 +360,25 @@ lp_setup_clear( struct lp_setup_context *setup,
struct pipe_fence_handle *
lp_setup_fence( struct lp_setup_context *setup )
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
- const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */
- struct lp_fence *fence = lp_fence_create(rank);
+ if (setup->num_threads == 0) {
+ return NULL;
+ }
+ else {
+ struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */
+ struct lp_fence *fence = lp_fence_create(rank);
- LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
+ LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
- set_scene_state( setup, SETUP_ACTIVE );
+ set_scene_state( setup, SETUP_ACTIVE );
- /* insert the fence into all command bins */
- lp_scene_bin_everywhere( scene,
- lp_rast_fence,
- lp_rast_arg_fence(fence) );
+ /* insert the fence into all command bins */
+ lp_scene_bin_everywhere( scene,
+ lp_rast_fence,
+ lp_rast_arg_fence(fence) );
- return (struct pipe_fence_handle *) fence;
+ return (struct pipe_fence_handle *) fence;
+ }
}
@@ -591,10 +613,14 @@ lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
void
lp_setup_update_state( struct lp_setup_context *setup )
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ struct lp_scene *scene;
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
+ setup_check_scene_size_and_flush(setup);
+
+ scene = lp_setup_get_current_scene(setup);
+
assert(setup->fs.current.jit_function);
/* Some of the 'draw' pipeline stages may have changed some driver state.
@@ -715,7 +741,7 @@ lp_setup_update_state( struct lp_setup_context *setup )
*/
for (i = 0; i < Elements(setup->fs.current_tex); i++) {
if (setup->fs.current_tex[i])
- lp_scene_texture_reference(scene, setup->fs.current_tex[i]);
+ lp_scene_add_resource_reference(scene, setup->fs.current_tex[i]);
}
}
}
@@ -736,6 +762,8 @@ lp_setup_destroy( struct lp_setup_context *setup )
reset_context( setup );
+ util_unreference_framebuffer_state(&setup->fb);
+
for (i = 0; i < Elements(setup->fs.current_tex); i++) {
pipe_resource_reference(&setup->fs.current_tex[i], NULL);
}
@@ -750,6 +778,8 @@ lp_setup_destroy( struct lp_setup_context *setup )
lp_scene_destroy(scene);
}
+ lp_scene_queue_destroy(setup->empty_scenes);
+
lp_rast_destroy( setup->rast );
FREE( setup );
@@ -765,8 +795,9 @@ struct lp_setup_context *
lp_setup_create( struct pipe_context *pipe,
struct draw_context *draw )
{
- unsigned i;
+ struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
struct lp_setup_context *setup = CALLOC_STRUCT(lp_setup_context);
+ unsigned i;
if (!setup)
return NULL;
@@ -779,7 +810,8 @@ lp_setup_create( struct pipe_context *pipe,
/* XXX: move this to the screen and share between contexts:
*/
- setup->rast = lp_rast_create();
+ setup->num_threads = screen->num_threads;
+ setup->rast = lp_rast_create(screen->num_threads);
if (!setup->rast)
goto fail;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 4594f7597d5..584764ce8ac 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -80,6 +80,7 @@ struct lp_setup_context
* create/install this itself now.
*/
struct draw_stage *vbuf;
+ unsigned num_threads;
struct lp_rasterizer *rast;
struct lp_scene *scenes[MAX_SCENES]; /**< all the scenes */
struct lp_scene *scene; /**< current scene being built */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
index a4012754784..5d3122e8ba2 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
@@ -440,7 +440,12 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
static void
lp_setup_vbuf_destroy(struct vbuf_render *vbr)
{
- lp_setup_destroy(lp_setup_context(vbr));
+ struct lp_setup_context *setup = lp_setup_context(vbr);
+ if (setup->vertex_buffer) {
+ align_free(setup->vertex_buffer);
+ setup->vertex_buffer = NULL;
+ }
+ lp_setup_destroy(setup);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index dcbff190b62..18143807c91 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -31,11 +31,10 @@
#ifndef LP_STATE_H
#define LP_STATE_H
-#include "gallivm/lp_bld.h"
-
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
#include "lp_jit.h"
+#include "gallivm/lp_bld.h"
#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */
@@ -85,8 +84,6 @@ struct lp_fragment_shader_variant_key
struct lp_fragment_shader_variant
{
- struct lp_fragment_shader *shader;
-
struct lp_fragment_shader_variant_key key;
LLVMValueRef function[2];
@@ -97,11 +94,7 @@ struct lp_fragment_shader_variant
};
-/**
- * Subclass of pipe_shader_state (though it doesn't really need to be).
- *
- * This is starting to look an awful lot like a quad pipeline stage...
- */
+/** Subclass of pipe_shader_state */
struct lp_fragment_shader
{
struct pipe_shader_state base;
@@ -109,140 +102,58 @@ struct lp_fragment_shader
struct tgsi_shader_info info;
struct lp_fragment_shader_variant *variants;
-
- struct lp_fragment_shader_variant *current;
};
/** Subclass of pipe_shader_state */
-struct lp_vertex_shader {
+struct lp_vertex_shader
+{
struct pipe_shader_state shader;
struct draw_vertex_shader *draw_data;
};
-struct lp_velems_state {
+
+/** Vertex element state */
+struct lp_velems_state
+{
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
-void *
-llvmpipe_create_blend_state(struct pipe_context *,
- const struct pipe_blend_state *);
-void llvmpipe_bind_blend_state(struct pipe_context *,
- void *);
-void llvmpipe_delete_blend_state(struct pipe_context *,
- void *);
-
-void *
-llvmpipe_create_sampler_state(struct pipe_context *,
- const struct pipe_sampler_state *);
-void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
void
-llvmpipe_bind_vertex_sampler_states(struct pipe_context *,
- unsigned num_samplers,
- void **samplers);
-void llvmpipe_delete_sampler_state(struct pipe_context *, void *);
-
-void *
-llvmpipe_create_depth_stencil_state(struct pipe_context *,
- const struct pipe_depth_stencil_alpha_state *);
-void llvmpipe_bind_depth_stencil_state(struct pipe_context *, void *);
-void llvmpipe_delete_depth_stencil_state(struct pipe_context *, void *);
-
-void *
-llvmpipe_create_rasterizer_state(struct pipe_context *,
- const struct pipe_rasterizer_state *);
-void llvmpipe_bind_rasterizer_state(struct pipe_context *, void *);
-void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *);
-
-void llvmpipe_set_framebuffer_state( struct pipe_context *,
- const struct pipe_framebuffer_state * );
-
-void llvmpipe_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color );
-
-void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
- const struct pipe_stencil_ref *stencil_ref );
-
-void llvmpipe_set_clip_state( struct pipe_context *,
- const struct pipe_clip_state * );
-
-void llvmpipe_set_constant_buffer(struct pipe_context *,
- uint shader, uint index,
- struct pipe_resource *buf);
-
-void *llvmpipe_create_fs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void llvmpipe_bind_fs_state(struct pipe_context *, void *);
-void llvmpipe_delete_fs_state(struct pipe_context *, void *);
-void *llvmpipe_create_vs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void llvmpipe_bind_vs_state(struct pipe_context *, void *);
-void llvmpipe_delete_vs_state(struct pipe_context *, void *);
-
-void *llvmpipe_create_vertex_elements_state(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-void llvmpipe_bind_vertex_elements_state(struct pipe_context *, void *);
-void llvmpipe_delete_vertex_elements_state(struct pipe_context *, void *);
-
-void llvmpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
-
-void llvmpipe_set_scissor_state( struct pipe_context *,
- const struct pipe_scissor_state * );
-
-void llvmpipe_set_fragment_sampler_views(struct pipe_context *,
- unsigned num,
- struct pipe_sampler_view **);
+llvmpipe_set_framebuffer_state(struct pipe_context *,
+ const struct pipe_framebuffer_state *);
void
-llvmpipe_set_vertex_sampler_views(struct pipe_context *,
- unsigned num,
- struct pipe_sampler_view **);
-
-struct pipe_sampler_view *
-llvmpipe_create_sampler_view(struct pipe_context *pipe,
- struct pipe_resource *texture,
- const struct pipe_sampler_view *templ);
+llvmpipe_update_fs(struct llvmpipe_context *lp);
void
-llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
- struct pipe_sampler_view *view);
+llvmpipe_update_derived(struct llvmpipe_context *llvmpipe);
-void llvmpipe_set_viewport_state( struct pipe_context *,
- const struct pipe_viewport_state * );
-
-void llvmpipe_set_vertex_buffers(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_buffer *);
+void
+llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe);
-void llvmpipe_update_fs(struct llvmpipe_context *lp);
+void
+llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe);
-void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe );
+void
+llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe);
+void
+llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe);
-void llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
- unsigned start, unsigned count);
+void
+llvmpipe_init_clip_funcs(struct llvmpipe_context *llvmpipe);
-void llvmpipe_draw_elements(struct pipe_context *pipe,
- struct pipe_resource *indexBuffer,
- unsigned indexSize, int indexBias,
- unsigned mode, unsigned start, unsigned count);
void
-llvmpipe_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);
+llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe);
void
-llvmpipe_map_texture_surfaces(struct llvmpipe_context *lp);
+llvmpipe_init_vs_funcs(struct llvmpipe_context *llvmpipe);
void
-llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp);
+llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe);
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
index 4ee28473e80..8569507f4e5 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -40,15 +40,16 @@
#include "lp_state.h"
-void *
+static void *
llvmpipe_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
return mem_dup(blend, sizeof(*blend));
}
-void llvmpipe_bind_blend_state( struct pipe_context *pipe,
- void *blend )
+
+static void
+llvmpipe_bind_blend_state(struct pipe_context *pipe, void *blend)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -62,15 +63,17 @@ void llvmpipe_bind_blend_state( struct pipe_context *pipe,
llvmpipe->dirty |= LP_NEW_BLEND;
}
-void llvmpipe_delete_blend_state(struct pipe_context *pipe,
- void *blend)
+
+static void
+llvmpipe_delete_blend_state(struct pipe_context *pipe, void *blend)
{
FREE( blend );
}
-void llvmpipe_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color )
+static void
+llvmpipe_set_blend_color(struct pipe_context *pipe,
+ const struct pipe_blend_color *blend_color)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -93,14 +96,15 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
*/
-void *
+static void *
llvmpipe_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
llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
@@ -116,14 +120,17 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA;
}
-void
+
+static void
llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
{
FREE( depth );
}
-void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
- const struct pipe_stencil_ref *stencil_ref )
+
+static void
+llvmpipe_set_stencil_ref(struct pipe_context *pipe,
+ const struct pipe_stencil_ref *stencil_ref)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -142,3 +149,18 @@ void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
}
+void
+llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state;
+ llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state;
+ llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
+
+ llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
+ llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state;
+ llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state;
+
+ llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
+
+ llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_clip.c b/src/gallium/drivers/llvmpipe/lp_state_clip.c
index df68f27acc9..32ae079cc15 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_clip.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_clip.c
@@ -32,8 +32,9 @@
#include "draw/draw_context.h"
-void llvmpipe_set_clip_state( struct pipe_context *pipe,
- const struct pipe_clip_state *clip )
+static void
+llvmpipe_set_clip_state(struct pipe_context *pipe,
+ const struct pipe_clip_state *clip)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -42,8 +43,9 @@ void llvmpipe_set_clip_state( struct pipe_context *pipe,
}
-void llvmpipe_set_viewport_state( struct pipe_context *pipe,
- const struct pipe_viewport_state *viewport )
+static void
+llvmpipe_set_viewport_state(struct pipe_context *pipe,
+ const struct pipe_viewport_state *viewport)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -55,8 +57,9 @@ void llvmpipe_set_viewport_state( struct pipe_context *pipe,
}
-void llvmpipe_set_scissor_state( struct pipe_context *pipe,
- const struct pipe_scissor_state *scissor )
+static void
+llvmpipe_set_scissor_state(struct pipe_context *pipe,
+ const struct pipe_scissor_state *scissor)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -67,8 +70,9 @@ void llvmpipe_set_scissor_state( struct pipe_context *pipe,
}
-void llvmpipe_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
+static void
+llvmpipe_set_polygon_stipple(struct pipe_context *pipe,
+ const struct pipe_poly_stipple *stipple)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -77,3 +81,14 @@ void llvmpipe_set_polygon_stipple( struct pipe_context *pipe,
llvmpipe->poly_stipple = *stipple; /* struct copy */
llvmpipe->dirty |= LP_NEW_STIPPLE;
}
+
+
+
+void
+llvmpipe_init_clip_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
+ llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
+ llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
+ llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 59d5a440c03..513e62e39e5 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -403,9 +403,7 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef step2_ptr)
{
const struct tgsi_token *tokens = shader->base.tokens;
- LLVMTypeRef elem_type;
LLVMTypeRef vec_type;
- LLVMTypeRef int_vec_type;
LLVMValueRef consts_ptr;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef z = interp->pos[2];
@@ -422,9 +420,7 @@ generate_fs(struct llvmpipe_context *lp,
stencil_refs[0] = lp_jit_context_stencil_ref_front_value(builder, context_ptr);
stencil_refs[1] = lp_jit_context_stencil_ref_back_value(builder, context_ptr);
- elem_type = lp_build_elem_type(type);
vec_type = lp_build_vec_type(type);
- int_vec_type = lp_build_int_vec_type(type);
consts_ptr = lp_jit_context_constants(builder, context_ptr);
@@ -474,7 +470,7 @@ generate_fs(struct llvmpipe_context *lp,
lp_build_tgsi_soa(builder, tokens, type, &mask,
consts_ptr, interp->pos, interp->inputs,
- outputs, sampler);
+ outputs, sampler, &shader->info);
for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -546,7 +542,6 @@ generate_blend(const struct pipe_blend_state *blend,
struct lp_build_flow_context *flow;
struct lp_build_mask_context mask_ctx;
LLVMTypeRef vec_type;
- LLVMTypeRef int_vec_type;
LLVMValueRef const_ptr;
LLVMValueRef con[4];
LLVMValueRef dst[4];
@@ -561,7 +556,6 @@ generate_blend(const struct pipe_blend_state *blend,
lp_build_mask_begin(&mask_ctx, flow, type, mask);
vec_type = lp_build_vec_type(type);
- int_vec_type = lp_build_int_vec_type(type);
const_ptr = lp_jit_context_blend_color(builder, context_ptr);
const_ptr = LLVMBuildBitCast(builder, const_ptr,
@@ -624,10 +618,8 @@ generate_fragment(struct llvmpipe_context *lp,
struct lp_type fs_type;
struct lp_type blend_type;
LLVMTypeRef fs_elem_type;
- LLVMTypeRef fs_vec_type;
LLVMTypeRef fs_int_vec_type;
LLVMTypeRef blend_vec_type;
- LLVMTypeRef blend_int_vec_type;
LLVMTypeRef arg_types[15];
LLVMTypeRef func_type;
LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
@@ -682,11 +674,9 @@ generate_fragment(struct llvmpipe_context *lp,
*/
fs_elem_type = lp_build_elem_type(fs_type);
- fs_vec_type = lp_build_vec_type(fs_type);
fs_int_vec_type = lp_build_int_vec_type(fs_type);
blend_vec_type = lp_build_vec_type(blend_type);
- blend_int_vec_type = lp_build_int_vec_type(blend_type);
arg_types[0] = screen->context_ptr_type; /* context */
arg_types[1] = LLVMInt32Type(); /* x */
@@ -945,7 +935,6 @@ generate_variant(struct llvmpipe_context *lp,
if(!variant)
return NULL;
- variant->shader = shader;
memcpy(&variant->key, key, sizeof *key);
generate_fragment(lp, shader, variant, 0);
@@ -959,7 +948,7 @@ generate_variant(struct llvmpipe_context *lp,
}
-void *
+static void *
llvmpipe_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -975,11 +964,16 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
/* we need to keep a local copy of the tokens */
shader->base.tokens = tgsi_dup_tokens(templ->tokens);
+ if (LP_DEBUG & DEBUG_TGSI) {
+ debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader);
+ tgsi_dump(templ->tokens, 0);
+ }
+
return shader;
}
-void
+static void
llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -995,7 +989,7 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
}
-void
+static void
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -1038,7 +1032,7 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
-void
+static void
llvmpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
struct pipe_resource *constants)
@@ -1112,8 +1106,8 @@ make_variant_key(struct llvmpipe_context *lp,
unsigned chan;
format_desc = util_format_description(lp->framebuffer.cbufs[i]->format);
- assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB ||
- format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB);
+ assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
+ format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
key->blend.rt[i].colormask = lp->blend->rt[i].colormask;
@@ -1169,8 +1163,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */
}
- shader->current = variant;
-
/* TODO: put this in the variant */
/* TODO: most of these can be relaxed, in particular the colormask */
opaque = !key.blend.logicop_enable &&
@@ -1184,7 +1176,19 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
? TRUE : FALSE;
lp_setup_set_fs_functions(lp->setup,
- shader->current->jit_function[RAST_WHOLE],
- shader->current->jit_function[RAST_EDGE_TEST],
+ variant->jit_function[RAST_WHOLE],
+ variant->jit_function[RAST_EDGE_TEST],
opaque);
}
+
+
+
+void
+llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
+ llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state;
+ llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
+
+ llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index 47f65fe72d1..622eb47ff45 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -34,7 +34,7 @@
-void *
+static void *
llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rast)
{
@@ -46,7 +46,7 @@ llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
-void
+static void
llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -71,16 +71,27 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW,
llvmpipe->rasterizer->scissor,
llvmpipe->rasterizer->gl_rasterization_rules);
+ lp_setup_set_flatshade_first( llvmpipe->setup,
+ llvmpipe->rasterizer->flatshade_first);
}
llvmpipe->dirty |= LP_NEW_RASTERIZER;
}
-void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
- void *rasterizer)
+static void
+llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
+ void *rasterizer)
{
FREE( rasterizer );
}
+
+void
+llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
+ llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state;
+ llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 3552ff50ce1..55d43368a3e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -41,7 +41,7 @@
-void *
+static void *
llvmpipe_create_sampler_state(struct pipe_context *pipe,
const struct pipe_sampler_state *sampler)
{
@@ -49,7 +49,7 @@ llvmpipe_create_sampler_state(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
@@ -76,7 +76,7 @@ llvmpipe_bind_sampler_states(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
unsigned num_samplers,
void **samplers)
@@ -104,7 +104,7 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@@ -133,7 +133,7 @@ llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@@ -163,7 +163,7 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
}
-struct pipe_sampler_view *
+static struct pipe_sampler_view *
llvmpipe_create_sampler_view(struct pipe_context *pipe,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
@@ -182,7 +182,7 @@ llvmpipe_create_sampler_view(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
@@ -191,7 +191,7 @@ llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
}
-void
+static void
llvmpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
@@ -199,4 +199,16 @@ llvmpipe_delete_sampler_state(struct pipe_context *pipe,
}
-
+void
+llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
+
+ llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states;
+ llvmpipe->pipe.bind_vertex_sampler_states = llvmpipe_bind_vertex_sampler_states;
+ llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
+ llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
+ llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
+ llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
+ llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c
index 7d86c5750c5..63b8f27b39c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c
@@ -52,8 +52,8 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
boolean changed = !util_framebuffer_state_equal(&lp->framebuffer, fb);
- assert(fb->width <= MAXWIDTH);
- assert(fb->height <= MAXHEIGHT);
+ assert(fb->width <= LP_MAX_WIDTH);
+ assert(fb->height <= LP_MAX_HEIGHT);
if (changed) {
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index f6427aa908e..113f13db018 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -35,7 +35,7 @@
#include "draw/draw_context.h"
-void *
+static void *
llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
@@ -50,7 +50,7 @@ llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
return velems;
}
-void
+static void
llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{
@@ -65,13 +65,13 @@ llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
draw_set_vertex_elements(llvmpipe->draw, lp_velems->count, lp_velems->velem);
}
-void
+static void
llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
-void
+static void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_buffer *buffers)
@@ -87,3 +87,15 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(llvmpipe->draw, count, buffers);
}
+
+
+
+void
+llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
+ llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
+ llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
+
+ llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vs.c b/src/gallium/drivers/llvmpipe/lp_state_vs.c
index 884e3878e62..f2d88089906 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vs.c
@@ -28,15 +28,17 @@
#include "pipe/p_defines.h"
+#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_parse.h"
#include "util/u_memory.h"
#include "draw/draw_context.h"
#include "lp_context.h"
+#include "lp_debug.h"
#include "lp_state.h"
-void *
+static void *
llvmpipe_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -57,6 +59,11 @@ llvmpipe_create_vs_state(struct pipe_context *pipe,
if (state->draw_data == NULL)
goto fail;
+ if (LP_DEBUG & DEBUG_TGSI) {
+ debug_printf("llvmpipe: Create vertex shader %p:\n", (void *) state);
+ tgsi_dump(templ->tokens, 0);
+ }
+
return state;
fail:
@@ -69,7 +76,7 @@ fail:
}
-void
+static void
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -87,7 +94,7 @@ llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
}
-void
+static void
llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@@ -99,3 +106,13 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
FREE( (void *)state->shader.tokens );
FREE( state );
}
+
+
+
+void
+llvmpipe_init_vs_funcs(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state;
+ llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
+ llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 1a116989d4c..8bd83f576f4 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -28,9 +28,9 @@
#include "util/u_rect.h"
#include "lp_context.h"
#include "lp_flush.h"
+#include "lp_limits.h"
#include "lp_surface.h"
#include "lp_texture.h"
-#include "lp_tile_size.h"
/**
@@ -59,19 +59,19 @@ lp_surface_copy(struct pipe_context *pipe,
struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst->texture);
const enum pipe_format format = src_tex->base.format;
- llvmpipe_flush_texture(pipe,
- dst->texture, dst->face, dst->level,
- 0, /* flush_flags */
- FALSE, /* read_only */
- FALSE, /* cpu_access */
- FALSE); /* do_not_flush */
+ llvmpipe_flush_resource(pipe,
+ dst->texture, dst->face, dst->level,
+ 0, /* flush_flags */
+ FALSE, /* read_only */
+ FALSE, /* cpu_access */
+ FALSE); /* do_not_block */
- llvmpipe_flush_texture(pipe,
- src->texture, src->face, src->level,
- 0, /* flush_flags */
- TRUE, /* read_only */
- FALSE, /* cpu_access */
- FALSE); /* do_not_flush */
+ llvmpipe_flush_resource(pipe,
+ src->texture, src->face, src->level,
+ 0, /* flush_flags */
+ TRUE, /* read_only */
+ FALSE, /* cpu_access */
+ FALSE); /* do_not_block */
/*
printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
@@ -146,7 +146,7 @@ lp_surface_copy(struct pipe_context *pipe,
void
-lp_init_surface_functions(struct llvmpipe_context *lp)
+llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
{
lp->pipe.surface_copy = lp_surface_copy;
lp->pipe.surface_fill = util_surface_fill;
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.h b/src/gallium/drivers/llvmpipe/lp_surface.h
index 4d78a53c4f5..b1b896ebd90 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.h
+++ b/src/gallium/drivers/llvmpipe/lp_surface.h
@@ -36,7 +36,7 @@ struct llvmpipe_context;
extern void
-lp_init_surface_functions(struct llvmpipe_context *lp);
+llvmpipe_init_surface_functions(struct llvmpipe_context *lp);
#endif /* LP_SURFACE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 818f7a9a562..fae7bf3fcf2 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -154,7 +154,6 @@ add_blend_test(LLVMModuleRef module,
enum vector_mode mode,
struct lp_type type)
{
- LLVMTypeRef ret_type;
LLVMTypeRef vec_type;
LLVMTypeRef args[4];
LLVMValueRef func;
@@ -165,7 +164,6 @@ add_blend_test(LLVMModuleRef module,
LLVMBasicBlockRef block;
LLVMBuilderRef builder;
- ret_type = LLVMInt64Type();
vec_type = lp_build_vec_type(type);
args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
index 74b7393e4ec..74b7393e4ec 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index cee170ec834..2f41d620c8a 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -47,7 +47,6 @@
#include "lp_tile_image.h"
#include "lp_texture.h"
#include "lp_setup.h"
-#include "lp_tile_size.h"
#include "state_tracker/sw_winsys.h"
@@ -55,14 +54,18 @@
static INLINE boolean
resource_is_texture(const struct pipe_resource *resource)
{
- const unsigned tex_binds = (PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED |
- PIPE_BIND_DEPTH_STENCIL |
- PIPE_BIND_SAMPLER_VIEW);
- const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
-
- return (lpr->base.bind & tex_binds) ? TRUE : FALSE;
+ switch (resource->target) {
+ case PIPE_BUFFER:
+ return FALSE;
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_3D:
+ case PIPE_TEXTURE_CUBE:
+ return TRUE;
+ default:
+ assert(0);
+ return FALSE;
+ }
}
@@ -81,7 +84,7 @@ alloc_layout_array(unsigned num_slices, unsigned width, unsigned height)
assert(LP_TEX_LAYOUT_NONE == 0); /* calloc'ing LP_TEX_LAYOUT_NONE here */
return (enum lp_texture_layout *)
- calloc(num_slices * tx * ty, sizeof(enum lp_texture_layout));
+ CALLOC(num_slices * tx * ty, sizeof(enum lp_texture_layout));
}
@@ -189,20 +192,20 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
assert(lpr->base.bind);
- if (lpr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED)) {
- /* displayable surface */
- if (!llvmpipe_displaytarget_layout(screen, lpr))
- goto fail;
- assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
- }
- else if (lpr->base.bind & (PIPE_BIND_SAMPLER_VIEW |
- PIPE_BIND_DEPTH_STENCIL)) {
- /* texture map */
- if (!llvmpipe_texture_layout(screen, lpr))
- goto fail;
- assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
+ if (resource_is_texture(&lpr->base)) {
+ if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) {
+ /* displayable surface */
+ if (!llvmpipe_displaytarget_layout(screen, lpr))
+ goto fail;
+ assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
+ }
+ else {
+ /* texture map */
+ if (!llvmpipe_texture_layout(screen, lpr))
+ goto fail;
+ assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
+ }
+ assert(lpr->layout[0]);
}
else {
/* other data (vertex buffer, const buffer, etc) */
@@ -217,10 +220,6 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
goto fail;
}
- if (resource_is_texture(&lpr->base)) {
- assert(lpr->layout[0]);
- }
-
lpr->id = id_counter++;
return &lpr->base;
@@ -242,6 +241,13 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
/* display target */
struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpr->dt);
+
+ if (lpr->tiled[0].data) {
+ align_free(lpr->tiled[0].data);
+ lpr->tiled[0].data = NULL;
+ }
+
+ FREE(lpr->layout[0]);
}
else if (resource_is_texture(pt)) {
/* regular texture */
@@ -265,7 +271,7 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
/* free layout flag arrays */
for (level = 0; level < Elements(lpr->tiled); level++) {
- free(lpr->layout[level]);
+ FREE(lpr->layout[level]);
lpr->layout[level] = NULL;
}
}
@@ -389,10 +395,7 @@ llvmpipe_resource_data(struct pipe_resource *resource)
{
struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
- assert((lpr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT |
- PIPE_BIND_SHARED |
- PIPE_BIND_SAMPLER_VIEW)) == 0);
+ assert(!resource_is_texture(resource));
return lpr->data;
}
@@ -496,6 +499,27 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
assert(resource);
assert(sr.level <= resource->last_level);
+ /*
+ * Transfers, like other pipe operations, must happen in order, so flush the
+ * context if necessary.
+ */
+ if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+ boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
+ boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
+ if (!llvmpipe_flush_resource(pipe, resource,
+ sr.face, sr.level,
+ 0, /* flush_flags */
+ read_only,
+ TRUE, /* cpu_access */
+ do_not_block)) {
+ /*
+ * It would have blocked, but state tracker requested no to.
+ */
+ assert(do_not_block);
+ return NULL;
+ }
+ }
+
lpr = CALLOC_STRUCT(llvmpipe_transfer);
if (lpr) {
struct pipe_transfer *pt = &lpr->base;
@@ -566,19 +590,6 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
lpr = llvmpipe_resource(transfer->resource);
format = lpr->base.format;
- /*
- * Transfers, like other pipe operations, must happen in order, so flush the
- * context if necessary.
- */
- llvmpipe_flush_texture(pipe,
- transfer->resource,
- transfer->sr.face,
- transfer->sr.level,
- 0, /* flush_flags */
- !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
- TRUE, /* cpu_access */
- FALSE); /* do_not_flush */
-
map = llvmpipe_resource_map(transfer->resource,
transfer->sr.face,
transfer->sr.level,
@@ -994,14 +1005,16 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
lpr->base.format,
- lpr->row_stride[level]);
+ lpr->row_stride[level],
+ lpr->tiles_per_row[level]);
}
else {
lp_tiled_to_linear(other_data, target_data,
x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
lpr->base.format,
- lpr->row_stride[level]);
+ lpr->row_stride[level],
+ lpr->tiles_per_row[level]);
}
}
@@ -1090,7 +1103,8 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
if (convert) {
lp_tiled_to_linear(tiled_image, linear_image,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
- lpr->row_stride[level]);
+ lpr->row_stride[level],
+ lpr->tiles_per_row[level]);
}
if (new_layout != cur_layout)
@@ -1138,7 +1152,8 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
if (convert) {
lp_linear_to_tiled(linear_image, tiled_image,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
- lpr->row_stride[level]);
+ lpr->row_stride[level],
+ lpr->tiles_per_row[level]);
}
if (new_layout != cur_layout)
@@ -1152,6 +1167,27 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
}
+/**
+ * Return size of resource in bytes
+ */
+unsigned
+llvmpipe_resource_size(const struct pipe_resource *resource)
+{
+ const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
+ unsigned lvl, size = 0;
+
+ for (lvl = 0; lvl <= lpr->base.last_level; lvl++) {
+ if (lpr->linear[lvl].data)
+ size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR);
+
+ if (lpr->tiled[lvl].data)
+ size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED);
+ }
+
+ return size;
+}
+
+
void
llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
{
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 858975bcee0..a8d08d6247f 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -31,12 +31,7 @@
#include "pipe/p_state.h"
#include "util/u_debug.h"
-
-
-#define LP_MAX_TEXTURE_2D_LEVELS 12 /* 2K x 2K for now */
-#define LP_MAX_TEXTURE_3D_LEVELS 10 /* 512 x 512 x 512 for now */
-
-#define LP_MAX_TEXTURE_LEVELS LP_MAX_TEXTURE_2D_LEVELS
+#include "lp_limits.h"
enum lp_texture_usage
@@ -189,6 +184,10 @@ void *
llvmpipe_resource_data(struct pipe_resource *resource);
+unsigned
+llvmpipe_resource_size(const struct pipe_resource *resource);
+
+
ubyte *
llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
unsigned face_slice, unsigned level,
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.c b/src/gallium/drivers/llvmpipe/lp_tile_image.c
index 0852150ba72..2b63992dd70 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_image.c
+++ b/src/gallium/drivers/llvmpipe/lp_tile_image.c
@@ -122,14 +122,15 @@ tile_4_4_uint16(const uint16_t *src, uint16_t *dst, unsigned src_stride)
/**
* Convert a tiled image into a linear image.
- * \param src_stride source row stride in bytes (bytes per row of tiles)
* \param dst_stride dest row stride in bytes
*/
void
lp_tiled_to_linear(const void *src, void *dst,
unsigned x, unsigned y,
unsigned width, unsigned height,
- enum pipe_format format, unsigned dst_stride)
+ enum pipe_format format,
+ unsigned dst_stride,
+ unsigned tiles_per_row)
{
assert(x % TILE_SIZE == 0);
assert(y % TILE_SIZE == 0);
@@ -191,8 +192,6 @@ lp_tiled_to_linear(const void *src, void *dst,
const uint bpp = 4;
const uint tile_w = TILE_SIZE, tile_h = TILE_SIZE;
const uint bytes_per_tile = tile_w * tile_h * bpp;
- const uint src_stride = dst_stride * tile_w;
- const uint tiles_per_row = src_stride / bytes_per_tile;
uint i, j;
for (j = 0; j < height; j += tile_h) {
@@ -202,7 +201,7 @@ lp_tiled_to_linear(const void *src, void *dst,
uint byte_offset = tile_offset * bytes_per_tile;
const uint8_t *src_tile = (uint8_t *) src + byte_offset;
- lp_tile_write_4ub(format,
+ lp_tile_unswizzle_4ub(format,
src_tile,
dst, dst_stride,
ii, jj, tile_w, tile_h);
@@ -215,13 +214,14 @@ lp_tiled_to_linear(const void *src, void *dst,
/**
* Convert a linear image into a tiled image.
* \param src_stride source row stride in bytes
- * \param dst_stride dest row stride in bytes (bytes per row of tiles)
*/
void
lp_linear_to_tiled(const void *src, void *dst,
unsigned x, unsigned y,
unsigned width, unsigned height,
- enum pipe_format format, unsigned src_stride)
+ enum pipe_format format,
+ unsigned src_stride,
+ unsigned tiles_per_row)
{
assert(x % TILE_SIZE == 0);
assert(y % TILE_SIZE == 0);
@@ -281,8 +281,6 @@ lp_linear_to_tiled(const void *src, void *dst,
const uint bpp = 4;
const uint tile_w = TILE_SIZE, tile_h = TILE_SIZE;
const uint bytes_per_tile = tile_w * tile_h * bpp;
- const uint dst_stride = src_stride * tile_w;
- const uint tiles_per_row = dst_stride / bytes_per_tile;
uint i, j;
for (j = 0; j < height; j += TILE_SIZE) {
@@ -292,7 +290,7 @@ lp_linear_to_tiled(const void *src, void *dst,
uint byte_offset = tile_offset * bytes_per_tile;
uint8_t *dst_tile = (uint8_t *) dst + byte_offset;
- lp_tile_read_4ub(format,
+ lp_tile_swizzle_4ub(format,
dst_tile,
src, src_stride,
ii, jj, tile_w, tile_h);
@@ -320,10 +318,10 @@ test_tiled_linear_conversion(void *data,
/*unsigned tiled_stride = wt * TILE_SIZE * TILE_SIZE * 4;*/
lp_linear_to_tiled(data, tiled, 0, 0, width, height, format,
- stride);
+ stride, wt);
lp_tiled_to_linear(tiled, data, 0, 0, width, height, format,
- stride);
+ stride, wt);
free(tiled);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.h b/src/gallium/drivers/llvmpipe/lp_tile_image.h
index d74621925d5..8de8efc6c16 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_image.h
+++ b/src/gallium/drivers/llvmpipe/lp_tile_image.h
@@ -33,14 +33,18 @@ void
lp_tiled_to_linear(const void *src, void *dst,
unsigned x, unsigned y,
unsigned width, unsigned height,
- enum pipe_format format, unsigned dst_stride);
+ enum pipe_format format,
+ unsigned dst_stride,
+ unsigned tiles_per_row);
void
lp_linear_to_tiled(const void *src, void *dst,
unsigned x, unsigned y,
unsigned width, unsigned height,
- enum pipe_format format, unsigned src_stride);
+ enum pipe_format format,
+ unsigned src_stride,
+ unsigned tiles_per_row);
void
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.h b/src/gallium/drivers/llvmpipe/lp_tile_soa.h
index 9d6a88afec5..07f71b8411a 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_soa.h
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.h
@@ -30,7 +30,7 @@
#include "pipe/p_compiler.h"
#include "tgsi/tgsi_exec.h" /* for NUM_CHANNELS */
-#include "lp_tile_size.h"
+#include "lp_limits.h"
#ifdef __cplusplus
extern "C" {
@@ -51,7 +51,10 @@ tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH];
#define TILE_Y_STRIDE (TILE_VECTOR_HEIGHT * TILE_SIZE * NUM_CHANNELS) //1024
-extern int tile_write_count, tile_read_count;
+#ifdef DEBUG
+extern unsigned lp_tile_unswizzle_count;
+extern unsigned lp_tile_swizzle_count;
+#endif
/**
@@ -73,14 +76,14 @@ tile_pixel_offset(unsigned x, unsigned y, unsigned c)
void
-lp_tile_read_4ub(enum pipe_format format,
+lp_tile_swizzle_4ub(enum pipe_format format,
uint8_t *dst,
const void *src, unsigned src_stride,
unsigned x, unsigned y, unsigned w, unsigned h);
void
-lp_tile_write_4ub(enum pipe_format format,
+lp_tile_unswizzle_4ub(enum pipe_format format,
const uint8_t *src,
void *dst, unsigned dst_stride,
unsigned x, unsigned y, unsigned w, unsigned h);
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
index 65810b6f8ff..5ab63cbac67 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
@@ -58,7 +58,7 @@ def is_format_supported(format):
channel = format.channels[i]
if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT):
return False
- if channel.type == FLOAT and channel.size not in (32 ,64):
+ if channel.type == FLOAT and channel.size not in (16, 32 ,64):
return False
if format.colorspace not in ('rgb', 'srgb'):
@@ -75,7 +75,7 @@ def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
src_native_type = native_type(format)
print 'static void'
- print 'lp_tile_%s_read_%s(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, dst_suffix, dst_native_type)
+ print 'lp_tile_%s_swizzle_%s(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, dst_suffix, dst_native_type)
print '{'
print ' unsigned x, y;'
print ' const uint8_t *src_row = src + y0*src_stride;'
@@ -193,7 +193,7 @@ def pack_rgba(format, src_channel, r, g, b, a):
return expr
-def emit_unrolled_write_code(format, src_channel):
+def emit_unrolled_unswizzle_code(format, src_channel):
'''Emit code for writing a block based on unrolled loops.
This is considerably faster than the TILE_PIXEL-based code below.
'''
@@ -223,7 +223,7 @@ def emit_unrolled_write_code(format, src_channel):
print ' }'
-def emit_tile_pixel_write_code(format, src_channel):
+def emit_tile_pixel_unswizzle_code(format, src_channel):
'''Emit code for writing a block based on the TILE_PIXEL macro.'''
dst_native_type = native_type(format)
@@ -257,7 +257,7 @@ def emit_tile_pixel_write_code(format, src_channel):
value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
print ' *dst_pixel++ = %s;' % value
- else:
+ elif dst_channel.size:
print ' ++dst_pixel;'
else:
assert False
@@ -273,7 +273,7 @@ def generate_format_write(format, src_channel, src_native_type, src_suffix):
name = format.short_name()
print 'static void'
- print 'lp_tile_%s_write_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type)
+ print 'lp_tile_%s_unswizzle_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type)
print '{'
if format.layout == PLAIN \
and format.colorspace == 'rgb' \
@@ -282,14 +282,14 @@ def generate_format_write(format, src_channel, src_native_type, src_suffix):
and not format.is_mixed() \
and (format.channels[0].type == UNSIGNED \
or format.channels[1].type == UNSIGNED):
- emit_unrolled_write_code(format, src_channel)
+ emit_unrolled_unswizzle_code(format, src_channel)
else:
- emit_tile_pixel_write_code(format, src_channel)
+ emit_tile_pixel_unswizzle_code(format, src_channel)
print '}'
print
-def generate_read(formats, dst_channel, dst_native_type, dst_suffix):
+def generate_swizzle(formats, dst_channel, dst_native_type, dst_suffix):
'''Generate the dispatch function to read pixels from any format'''
for format in formats:
@@ -297,15 +297,17 @@ def generate_read(formats, dst_channel, dst_native_type, dst_suffix):
generate_format_read(format, dst_channel, dst_native_type, dst_suffix)
print 'void'
- print 'lp_tile_read_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type)
+ print 'lp_tile_swizzle_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type)
print '{'
print ' void (*func)(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % dst_native_type
- print ' tile_read_count += 1;'
+ print '#ifdef DEBUG'
+ print ' lp_tile_swizzle_count += 1;'
+ print '#endif'
print ' switch(format) {'
for format in formats:
if is_format_supported(format):
print ' case %s:' % format.name
- print ' func = &lp_tile_%s_read_%s;' % (format.short_name(), dst_suffix)
+ print ' func = &lp_tile_%s_swizzle_%s;' % (format.short_name(), dst_suffix)
print ' break;'
print ' default:'
print ' debug_printf("%s: unsupported format %s\\n", __FUNCTION__, util_format_name(format));'
@@ -316,7 +318,7 @@ def generate_read(formats, dst_channel, dst_native_type, dst_suffix):
print
-def generate_write(formats, src_channel, src_native_type, src_suffix):
+def generate_unswizzle(formats, src_channel, src_native_type, src_suffix):
'''Generate the dispatch function to write pixels to any format'''
for format in formats:
@@ -324,16 +326,18 @@ def generate_write(formats, src_channel, src_native_type, src_suffix):
generate_format_write(format, src_channel, src_native_type, src_suffix)
print 'void'
- print 'lp_tile_write_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type)
+ print 'lp_tile_unswizzle_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type)
print '{'
print ' void (*func)(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % src_native_type
- print ' tile_write_count += 1;'
+ print '#ifdef DEBUG'
+ print ' lp_tile_unswizzle_count += 1;'
+ print '#endif'
print ' switch(format) {'
for format in formats:
if is_format_supported(format):
print ' case %s:' % format.name
- print ' func = &lp_tile_%s_write_%s;' % (format.short_name(), src_suffix)
+ print ' func = &lp_tile_%s_unswizzle_%s;' % (format.short_name(), src_suffix)
print ' break;'
print ' default:'
print ' debug_printf("%s: unsupported format %s\\n", __FUNCTION__, util_format_name(format));'
@@ -360,7 +364,10 @@ def main():
print '#include "util/u_half.h"'
print '#include "lp_tile_soa.h"'
print
- print 'int tile_write_count=0, tile_read_count=0;'
+ print '#ifdef DEBUG'
+ print 'unsigned lp_tile_unswizzle_count = 0;'
+ print 'unsigned lp_tile_swizzle_count = 0;'
+ print '#endif'
print
print 'const unsigned char'
print 'tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH] = {'
@@ -388,8 +395,8 @@ def main():
native_type = 'uint8_t'
suffix = '4ub'
- generate_read(formats, channel, native_type, suffix)
- generate_write(formats, channel, native_type, suffix)
+ generate_swizzle(formats, channel, native_type, suffix)
+ generate_unswizzle(formats, channel, native_type, suffix)
if __name__ == '__main__':
diff --git a/src/gallium/drivers/llvmpipe/sp2lp.sh b/src/gallium/drivers/llvmpipe/sp2lp.sh
deleted file mode 100755
index c45a81ce3cf..00000000000
--- a/src/gallium/drivers/llvmpipe/sp2lp.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-#
-# Port changes from softpipe to llvmpipe. Invoke as
-#
-# sp2lp.sh <commit>
-#
-# Note that this will only affect llvmpipe -- you still need to actually
-# cherry-pick/merge the softpipe changes themselves if they affect directories
-# outside src/gallium/drivers/softpipe
-
-git format-patch \
- --keep-subject \
- --relative=src/gallium/drivers/softpipe \
- --src-prefix=a/src/gallium/drivers/llvmpipe/ \
- --dst-prefix=b/src/gallium/drivers/llvmpipe/ \
- --stdout "$1^1..$1" \
-| sed \
- -e 's/\<softpipe\>/llvmpipe/g' \
- -e 's/\<sp\>/lp/g' \
- -e 's/\<softpipe_/llvmpipe_/g' \
- -e 's/\<sp_/lp_/g' \
- -e 's/\<SP_/LP_/g' \
- -e 's/\<SOFTPIPE_/LLVMPIPE_/g' \
- -e 's/\<spt\>/lpt/g' \
- -e 's/\<sps\>/lps/g' \
- -e 's/\<spfs\>/lpfs/g' \
- -e 's/\<sptex\>/lptex/g' \
- -e 's/\<setup_\(point\|line\|tri\)\>/llvmpipe_\0/g' \
- -e 's/\<llvmpipe_cached_tile\>/llvmpipe_cached_tex_tile/g' \
- -e 's/_get_cached_tile_tex\>/_get_cached_tex_tile/g' \
- -e 's/\<TILE_SIZE\>/TEX_TILE_SIZE/g' \
- -e 's/\<tile_address\>/tex_tile_address/g' \
- -e 's/\<tile->data\.color\>/tile->color/g' \
-| patch -p1