summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r--src/gallium/drivers/softpipe/Makefile5
-rw-r--r--src/gallium/drivers/softpipe/SConscript2
-rw-r--r--src/gallium/drivers/softpipe/sp_clear.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c46
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h42
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c18
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c28
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_headers.h95
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c74
-rw-r--r--src/gallium/drivers/softpipe/sp_quad.h81
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_alpha_test.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_bufloop.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_colormask.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_coverage.c11
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_earlyz.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c26
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_occlusion.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_output.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_pipe.c (renamed from src/gallium/drivers/softpipe/sp_quad.c)0
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_pipe.h74
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_stencil.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_stipple.c27
-rw-r--r--src/gallium/drivers/softpipe/sp_query.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c40
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c991
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.h70
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c174
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h17
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c182
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h6
38 files changed, 1226 insertions, 874 deletions
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index 120bdfd9dd..516e3992fd 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -14,7 +14,7 @@ C_SOURCES = \
sp_draw_arrays.c \
sp_prim_setup.c \
sp_prim_vbuf.c \
- sp_quad.c \
+ sp_quad_pipe.c \
sp_quad_alpha_test.c \
sp_quad_blend.c \
sp_quad_colormask.c \
@@ -42,6 +42,3 @@ C_SOURCES = \
sp_surface.c
include ../../Makefile.template
-
-symlinks:
-
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index c1f7daa8ab..f8720638a7 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -17,7 +17,7 @@ softpipe = env.ConvenienceLibrary(
'sp_setup.c',
'sp_quad_alpha_test.c',
'sp_quad_blend.c',
- 'sp_quad.c',
+ 'sp_quad_pipe.c',
'sp_quad_colormask.c',
'sp_quad_coverage.c',
'sp_quad_depth_test.c',
diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c
index dfa46c9fb7..ad108ec446 100644
--- a/src/gallium/drivers/softpipe/sp_clear.c
+++ b/src/gallium/drivers/softpipe/sp_clear.c
@@ -85,7 +85,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps,
#endif
}
- for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
+ for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) {
unsigned cv;
if (ps->format != PIPE_FORMAT_A8R8G8B8_UNORM) {
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index cd1e6663d8..ff5d1b54a4 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2008 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
@@ -52,15 +53,15 @@
* Map any drawing surfaces which aren't already mapped
*/
void
-softpipe_map_surfaces(struct softpipe_context *sp)
+softpipe_map_transfers(struct softpipe_context *sp)
{
unsigned i;
- for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
+ for (i = 0; i < sp->framebuffer.nr_cbufs; i++) {
+ sp_tile_cache_map_transfers(sp->cbuf_cache[i]);
}
- sp_tile_cache_map_surfaces(sp->zsbuf_cache);
+ sp_tile_cache_map_transfers(sp->zsbuf_cache);
}
@@ -68,25 +69,25 @@ softpipe_map_surfaces(struct softpipe_context *sp)
* Unmap any mapped drawing surfaces
*/
void
-softpipe_unmap_surfaces(struct softpipe_context *sp)
+softpipe_unmap_transfers(struct softpipe_context *sp)
{
uint i;
- for (i = 0; i < sp->framebuffer.num_cbufs; i++)
+ for (i = 0; i < sp->framebuffer.nr_cbufs; i++)
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
sp_flush_tile_cache(sp, sp->zsbuf_cache);
- for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
- sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
+ for (i = 0; i < sp->framebuffer.nr_cbufs; i++) {
+ sp_tile_cache_unmap_transfers(sp->cbuf_cache[i]);
}
- sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
+ sp_tile_cache_unmap_transfers(sp->zsbuf_cache);
}
static void softpipe_destroy( struct pipe_context *pipe )
{
struct softpipe_context *softpipe = softpipe_context( pipe );
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *screen = pipe->screen;
uint i;
if (softpipe->draw)
@@ -115,7 +116,7 @@ static void softpipe_destroy( struct pipe_context *pipe )
for (i = 0; i < Elements(softpipe->constants); i++) {
if (softpipe->constants[i].buffer) {
- winsys_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
+ pipe_buffer_reference(screen, &softpipe->constants[i].buffer, NULL);
}
}
@@ -221,6 +222,24 @@ softpipe_create( struct pipe_screen *screen,
softpipe->quad[i].output = sp_quad_output_stage(softpipe);
}
+ /* vertex shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex;
+ softpipe->tgsi.vert_samplers[i].unit = i;
+ softpipe->tgsi.vert_samplers[i].sp = softpipe;
+ softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i];
+ softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i];
+ }
+
+ /* fragment shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment;
+ softpipe->tgsi.frag_samplers[i].unit = i;
+ softpipe->tgsi.frag_samplers[i].sp = softpipe;
+ softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i];
+ softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i];
+ }
+
/*
* Create drawing context and plug our rendering stage into it.
*/
@@ -228,6 +247,11 @@ softpipe_create( struct pipe_screen *screen,
if (!softpipe->draw)
goto fail;
+ draw_texture_samplers(softpipe->draw,
+ PIPE_MAX_SAMPLERS,
+ (struct tgsi_sampler **)
+ softpipe->tgsi.vert_samplers_list);
+
softpipe->setup = sp_draw_render_stage(softpipe);
if (!softpipe->setup)
goto fail;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 2b9a2a8ee5..59d6df8f2d 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -32,11 +32,11 @@
#define SP_CONTEXT_H
#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
#include "draw/draw_vertex.h"
-#include "sp_quad.h"
+#include "sp_quad_pipe.h"
+#include "sp_tex_sample.h"
/**
@@ -50,7 +50,6 @@
*/
#define SP_NUM_QUAD_THREADS 1
-struct softpipe_winsys;
struct softpipe_vbuf_render;
struct draw_context;
struct draw_stage;
@@ -62,15 +61,15 @@ struct sp_vertex_shader;
struct softpipe_context {
struct pipe_context pipe; /**< base class */
- /* The most recent drawing state as set by the driver:
- */
- const struct pipe_blend_state *blend;
+ /** Constant state objects */
+ const struct pipe_blend_state *blend;
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
- const struct pipe_depth_stencil_alpha_state *depth_stencil;
+ const struct pipe_depth_stencil_alpha_state *depth_stencil;
const struct pipe_rasterizer_state *rasterizer;
const struct sp_fragment_shader *fs;
const struct sp_vertex_shader *vs;
+ /** Other rendering state */
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
@@ -81,23 +80,20 @@ struct softpipe_context {
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- unsigned dirty;
unsigned num_samplers;
unsigned num_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers;
- boolean no_rast;
+ unsigned dirty; /**< Mask of SP_NEW_x flags */
/* Counter for occlusion queries. Note this supports overlapping
* queries.
*/
- uint64 occlusion_count;
+ uint64_t occlusion_count;
- /*
- * Mapped vertex buffers
- */
+ /** Mapped vertex buffers */
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
/** Mapped constant buffers */
@@ -107,16 +103,11 @@ struct softpipe_context {
struct vertex_info vertex_info;
struct vertex_info vertex_info_vbuf;
+ /** Which vertex shader output slot contains point size */
int psize_slot;
unsigned reduced_api_prim; /**< PIPE_PRIM_POINTS, _LINES or _TRIANGLES */
-#if 0
- /* Stipple derived state:
- */
- ubyte stipple_masks[16][16];
-#endif
-
/** Derived from scissor and surface bounds: */
struct pipe_scissor_state cliprect;
@@ -139,6 +130,14 @@ struct softpipe_context {
struct quad_stage *first; /**< points to one of the above stages */
} quad[SP_NUM_QUAD_THREADS];
+ /** TGSI exec things */
+ struct {
+ struct sp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
+ struct sp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
+ } tgsi;
+
/** The primitive drawing context */
struct draw_context *draw;
struct draw_stage *setup;
@@ -150,8 +149,9 @@ struct softpipe_context {
struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
- int use_sse : 1;
- int dump_fs : 1;
+ unsigned use_sse : 1;
+ unsigned dump_fs : 1;
+ unsigned no_rast : 1;
};
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 424bd56846..f117096bf7 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -33,7 +33,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "pipe/p_winsys.h"
+#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_inlines.h"
#include "sp_context.h"
@@ -47,16 +47,22 @@ static void
softpipe_map_constant_buffers(struct softpipe_context *sp)
{
struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
+ uint i, size;
+
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- if (sp->constants[i].size)
+ if (sp->constants[i].buffer && sp->constants[i].buffer->size)
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
}
+ if (sp->constants[PIPE_SHADER_VERTEX].buffer)
+ size = sp->constants[PIPE_SHADER_VERTEX].buffer->size;
+ else
+ size = 0;
+
draw_set_mapped_constant_buffer(sp->draw,
sp->mapped_constants[PIPE_SHADER_VERTEX],
- sp->constants[PIPE_SHADER_VERTEX].size);
+ size);
}
static void
@@ -73,7 +79,7 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp)
draw_set_mapped_constant_buffer(sp->draw, NULL, 0);
for (i = 0; i < 2; i++) {
- if (sp->constants[i].size)
+ if (sp->constants[i].buffer && sp->constants[i].buffer->size)
ws->buffer_unmap(ws, sp->constants[i].buffer);
sp->mapped_constants[i] = NULL;
}
@@ -128,7 +134,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe,
if (sp->dirty)
softpipe_update_derived( sp );
- softpipe_map_surfaces(sp);
+ softpipe_map_transfers(sp);
softpipe_map_constant_buffers(sp);
/*
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 401764bb43..035f4b963e 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -57,7 +57,7 @@ softpipe_flush( struct pipe_context *pipe,
}
if (flags & PIPE_FLUSH_RENDER_CACHE) {
- for (i = 0; i < softpipe->framebuffer.num_cbufs; i++)
+ for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
if (softpipe->cbuf_cache[i])
sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
@@ -70,7 +70,7 @@ softpipe_flush( struct pipe_context *pipe,
* that's called before swapbuffers because we don't always want
* to unmap surfaces when flushing.
*/
- softpipe_unmap_surfaces(softpipe);
+ softpipe_unmap_transfers(softpipe);
}
/* Enable to dump BMPs of the color/depth buffers each frame */
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 701ee4c72f..3c7ba565d6 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -29,7 +29,7 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_fs.h"
-#include "sp_headers.h"
+#include "sp_quad.h"
#include "pipe/p_state.h"
@@ -39,11 +39,19 @@
#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_parse.h"
-struct sp_exec_fragment_shader {
+struct sp_exec_fragment_shader
+{
struct sp_fragment_shader base;
};
+/** cast wrapper */
+static INLINE struct sp_exec_fragment_shader *
+sp_exec_fragment_shader(const struct sp_fragment_shader *base)
+{
+ return (struct sp_exec_fragment_shader *) base;
+}
+
/**
* Compute quad X,Y,Z,W for the four fragments in a quad.
@@ -84,12 +92,18 @@ sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
static void
exec_prepare( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
- struct tgsi_sampler *samplers )
+ struct tgsi_sampler **samplers )
{
- tgsi_exec_machine_bind_shader( machine,
- base->shader.tokens,
- PIPE_MAX_SAMPLERS,
- samplers );
+ /*
+ * Bind tokens/shader to the interpreter's machine state.
+ * Avoid redundant binding.
+ */
+ if (machine->Tokens != base->shader.tokens) {
+ tgsi_exec_machine_bind_shader( machine,
+ base->shader.tokens,
+ PIPE_MAX_SAMPLERS,
+ samplers );
+ }
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index 50eb2c07bc..7e22081132 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -29,7 +29,7 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_fs.h"
-#include "sp_headers.h"
+#include "sp_quad.h"
#include "pipe/p_state.h"
@@ -40,7 +40,7 @@
#include "tgsi/tgsi_sse2.h"
-#ifdef PIPE_ARCH_X86
+#if defined(PIPE_ARCH_X86)
#include "rtasm/rtasm_x86sse.h"
@@ -69,7 +69,7 @@ struct sp_sse_fragment_shader {
static void
fs_sse_prepare( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
- struct tgsi_sampler *samplers )
+ struct tgsi_sampler **samplers )
{
}
diff --git a/src/gallium/drivers/softpipe/sp_headers.h b/src/gallium/drivers/softpipe/sp_headers.h
deleted file mode 100644
index 4a42cb3c19..0000000000
--- a/src/gallium/drivers/softpipe/sp_headers.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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.
- *
- **************************************************************************/
-
-/* Authors: Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef SP_HEADERS_H
-#define SP_HEADERS_H
-
-#include "pipe/p_state.h"
-#include "tgsi/tgsi_exec.h"
-
-#define PRIM_POINT 1
-#define PRIM_LINE 2
-#define PRIM_TRI 3
-
-
-/* The rasterizer generates 2x2 quads of fragment and feeds them to
- * the current fp_machine (see below).
- * Remember that Y=0=top with Y increasing down the window.
- */
-#define QUAD_TOP_LEFT 0
-#define QUAD_TOP_RIGHT 1
-#define QUAD_BOTTOM_LEFT 2
-#define QUAD_BOTTOM_RIGHT 3
-
-#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT)
-#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT)
-#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT)
-#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT)
-#define MASK_ALL 0xf
-
-
-/**
- * Encodes everything we need to know about a 2x2 pixel block. Uses
- * "Channel-Serial" or "SoA" layout.
- */
-struct quad_header_input
-{
- int x0;
- int y0;
- float coverage[QUAD_SIZE]; /** fragment coverage for antialiasing */
- unsigned facing:1; /**< Front (0) or back (1) facing? */
- unsigned prim:2; /**< PRIM_POINT, LINE, TRI */
-};
-
-struct quad_header_inout
-{
- unsigned mask:4;
-};
-
-struct quad_header_output
-{
- /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */
- float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE];
- float depth[QUAD_SIZE];
-};
-
-struct quad_header {
- struct quad_header_input input;
- struct quad_header_inout inout;
- struct quad_header_output output;
-
- const struct tgsi_interp_coef *coef;
- const struct tgsi_interp_coef *posCoef;
-
- unsigned nr_attrs;
-};
-
-#endif /* SP_HEADERS_H */
-
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 425e13cd28..d56eed80a4 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -26,10 +26,10 @@
**************************************************************************/
/**
- * Post-transform vertex buffering. This is an optional part of the
- * softpipe rendering pipeline.
- * Probably not desired in general, but useful for testing/debuggin.
- * Enabled/Disabled with SP_VBUF env var.
+ * Interface between 'draw' module's output and the softpipe rasterizer/setup
+ * code. When the 'draw' module has finished filling a vertex buffer, the
+ * draw_arrays() functions below will be called. Loop over the vertices and
+ * call the point/line/tri setup functions.
*
* Authors
* Brian Paul
@@ -60,6 +60,7 @@ struct softpipe_vbuf_render
struct softpipe_context *softpipe;
uint prim;
uint vertex_size;
+ uint vertex_buffer_size;
void *vertex_buffer;
};
@@ -80,26 +81,44 @@ sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
}
-static void *
+static boolean
sp_vbuf_allocate_vertices(struct vbuf_render *vbr,
- ushort vertex_size, ushort nr_vertices)
+ ushort vertex_size, ushort nr_vertices)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
- assert(!cvbr->vertex_buffer);
- cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16);
+ unsigned size = vertex_size * nr_vertices;
+
+ if (cvbr->vertex_buffer_size < size) {
+ align_free(cvbr->vertex_buffer);
+ cvbr->vertex_buffer = align_malloc(size, 16);
+ cvbr->vertex_buffer_size = size;
+ }
+
cvbr->vertex_size = vertex_size;
- return cvbr->vertex_buffer;
+ return cvbr->vertex_buffer != NULL;
}
-
static void
-sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
- unsigned vertex_size, unsigned vertices_used)
+sp_vbuf_release_vertices(struct vbuf_render *vbr)
+{
+ /* keep the old allocation for next time */
+}
+
+static void *
+sp_vbuf_map_vertices(struct vbuf_render *vbr)
+{
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ return cvbr->vertex_buffer;
+}
+
+static void
+sp_vbuf_unmap_vertices(struct vbuf_render *vbr,
+ ushort min_index,
+ ushort max_index )
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
- align_free(vertices);
- assert(vertices == cvbr->vertex_buffer);
- cvbr->vertex_buffer = NULL;
+ assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
+ /* do nothing */
}
@@ -115,8 +134,6 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
setup_prepare( setup_ctx );
-
-
cvbr->prim = prim;
return TRUE;
@@ -131,21 +148,23 @@ 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)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
struct softpipe_context *softpipe = cvbr->softpipe;
- unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
- unsigned i;
+ const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
const void *vertex_buffer = cvbr->vertex_buffer;
+ unsigned i;
/* XXX: break this dependency - make setup_context live under
* softpipe, rename the old "setup" draw stage to something else.
*/
struct draw_stage *setup = softpipe->setup;
- struct setup_context *setup_ctx = sp_draw_setup_context(softpipe->setup);
-
+ struct setup_context *setup_ctx = sp_draw_setup_context(setup);
switch (cvbr->prim) {
case PIPE_PRIM_POINTS:
@@ -258,13 +277,16 @@ 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 draw_stage *setup = softpipe->setup;
- const void *vertex_buffer = NULL;
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
+ const void *vertex_buffer =
+ (void *) get_vert(cvbr->vertex_buffer, start, stride);
unsigned i;
- struct setup_context *setup_ctx = sp_draw_setup_context(setup);
- vertex_buffer = (void *)get_vert(cvbr->vertex_buffer, start, stride);
+ /* XXX: break this dependency - make setup_context live under
+ * softpipe, rename the old "setup" draw stage to something else.
+ */
+ struct draw_stage *setup = softpipe->setup;
+ struct setup_context *setup_ctx = sp_draw_setup_context(setup);
switch (cvbr->prim) {
case PIPE_PRIM_POINTS:
@@ -389,6 +411,8 @@ sp_init_vbuf(struct softpipe_context *sp)
sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info;
sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices;
+ sp->vbuf_render->base.map_vertices = sp_vbuf_map_vertices;
+ sp->vbuf_render->base.unmap_vertices = sp_vbuf_unmap_vertices;
sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;
sp->vbuf_render->base.draw = sp_vbuf_draw;
sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays;
diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h
index 08513cb95f..bd6c6cb912 100644
--- a/src/gallium/drivers/softpipe/sp_quad.h
+++ b/src/gallium/drivers/softpipe/sp_quad.h
@@ -31,39 +31,76 @@
#ifndef SP_QUAD_H
#define SP_QUAD_H
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_exec.h"
-struct softpipe_context;
-struct quad_header;
+#define QUAD_PRIM_POINT 1
+#define QUAD_PRIM_LINE 2
+#define QUAD_PRIM_TRI 3
-struct quad_stage {
- struct softpipe_context *softpipe;
- struct quad_stage *next;
+/* The rasterizer generates 2x2 quads of fragment and feeds them to
+ * the current fp_machine (see below).
+ * Remember that Y=0=top with Y increasing down the window.
+ */
+#define QUAD_TOP_LEFT 0
+#define QUAD_TOP_RIGHT 1
+#define QUAD_BOTTOM_LEFT 2
+#define QUAD_BOTTOM_RIGHT 3
+
+#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT)
+#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT)
+#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT)
+#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT)
+#define MASK_ALL 0xf
+
+
+/**
+ * Quad stage inputs (pos, coverage, front/back face, etc)
+ */
+struct quad_header_input
+{
+ int x0, y0; /**< quad window pos, always even */
+ float coverage[QUAD_SIZE]; /**< fragment coverage for antialiasing */
+ unsigned facing:1; /**< Front (0) or back (1) facing? */
+ unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */
+};
- void (*begin)(struct quad_stage *qs);
- /** the stage action */
- void (*run)(struct quad_stage *qs, struct quad_header *quad);
+/**
+ * Quad stage inputs/outputs.
+ */
+struct quad_header_inout
+{
+ unsigned mask:4;
+};
+
- void (*destroy)(struct quad_stage *qs);
+/**
+ * Quad stage outputs (color & depth).
+ */
+struct quad_header_output
+{
+ /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */
+ float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE];
+ float depth[QUAD_SIZE];
};
-struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_earlyz_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );
+/**
+ * Encodes everything we need to know about a 2x2 pixel block. Uses
+ * "Channel-Serial" or "SoA" layout.
+ */
+struct quad_header {
+ struct quad_header_input input;
+ struct quad_header_inout inout;
+ struct quad_header_output output;
-void sp_build_quad_pipeline(struct softpipe_context *sp);
+ const struct tgsi_interp_coef *coef;
+ const struct tgsi_interp_coef *posCoef;
-void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad);
+ unsigned nr_attrs;
+};
#endif /* SP_QUAD_H */
diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
index 5bebd141e9..0845bae0e6 100644
--- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
@@ -4,8 +4,8 @@
*/
#include "sp_context.h"
-#include "sp_headers.h"
#include "sp_quad.h"
+#include "sp_quad_pipe.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
@@ -14,7 +14,7 @@ static void
alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- const float ref = softpipe->depth_stencil->alpha.ref;
+ const float ref = softpipe->depth_stencil->alpha.ref_value;
unsigned passMask = 0x0, j;
const uint cbuf = 0; /* only output[0].alpha is tested */
const float *aaaa = quad->output.color[cbuf][3];
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index 6f64c6e584..e134e44337 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -34,10 +34,10 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
+#include "sp_quad.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
-#include "sp_quad.h"
+#include "sp_quad_pipe.h"
#define VEC4_COPY(DST, SRC) \
@@ -105,7 +105,7 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad)
uint cbuf;
/* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
float dest[4][QUAD_SIZE];
ubyte src[4][4], dst[4][4], res[4][4];
uint *src4 = (uint *) src;
@@ -239,7 +239,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
}
/* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
struct softpipe_cached_tile *tile
= sp_get_cached_tile(softpipe,
diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c
index 92e9af09c1..953d8516b9 100644
--- a/src/gallium/drivers/softpipe/sp_quad_bufloop.c
+++ b/src/gallium/drivers/softpipe/sp_quad_bufloop.c
@@ -1,9 +1,9 @@
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
-#include "sp_surface.h"
#include "sp_quad.h"
+#include "sp_surface.h"
+#include "sp_quad_pipe.h"
/**
@@ -17,7 +17,7 @@ cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
unsigned i;
assert(sizeof(quad->outputs.color) == sizeof(tmp));
- assert(softpipe->framebuffer.num_cbufs <= PIPE_MAX_COLOR_BUFS);
+ assert(softpipe->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS);
/* make copy of original colors since they can get modified
* by blending and masking.
@@ -28,7 +28,7 @@ cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
*/
memcpy(tmp, quad->outputs.color, sizeof(tmp));
- for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
+ for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
/* set current cbuffer */
#if 0 /* obsolete & going away */
softpipe->current_cbuf = i;
diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c
index f32bdfab78..dc90e5d5e9 100644
--- a/src/gallium/drivers/softpipe/sp_quad_colormask.c
+++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c
@@ -34,9 +34,9 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
-#include "sp_surface.h"
#include "sp_quad.h"
+#include "sp_surface.h"
+#include "sp_quad_pipe.h"
#include "sp_tile_cache.h"
@@ -51,7 +51,7 @@ colormask_quad(struct quad_stage *qs, struct quad_header *quad)
uint cbuf;
/* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
float dest[4][QUAD_SIZE];
struct softpipe_cached_tile *tile
= sp_get_cached_tile(softpipe,
diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c
index ee29aa7dfe..4aeee85870 100644
--- a/src/gallium/drivers/softpipe/sp_quad_coverage.c
+++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c
@@ -35,8 +35,8 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
#include "sp_quad.h"
+#include "sp_quad_pipe.h"
/**
@@ -46,14 +46,15 @@ static void
coverage_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
+ const uint prim = quad->input.prim;
- if ((softpipe->rasterizer->poly_smooth && quad->input.prim == PRIM_TRI) ||
- (softpipe->rasterizer->line_smooth && quad->input.prim == PRIM_LINE) ||
- (softpipe->rasterizer->point_smooth && quad->input.prim == PRIM_POINT)) {
+ if ((softpipe->rasterizer->poly_smooth && prim == QUAD_PRIM_TRI) ||
+ (softpipe->rasterizer->line_smooth && prim == QUAD_PRIM_LINE) ||
+ (softpipe->rasterizer->point_smooth && prim == QUAD_PRIM_POINT)) {
uint cbuf;
/* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
float (*quadColor)[4] = quad->output.color[cbuf];
unsigned j;
for (j = 0; j < QUAD_SIZE; j++) {
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 523bd3e080..d463930bae 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -32,9 +32,9 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
-#include "sp_surface.h"
#include "sp_quad.h"
+#include "sp_surface.h"
+#include "sp_quad_pipe.h"
#include "sp_tile_cache.h"
diff --git a/src/gallium/drivers/softpipe/sp_quad_earlyz.c b/src/gallium/drivers/softpipe/sp_quad_earlyz.c
index 6e2dde304e..496fd39ed1 100644
--- a/src/gallium/drivers/softpipe/sp_quad_earlyz.c
+++ b/src/gallium/drivers/softpipe/sp_quad_earlyz.c
@@ -31,8 +31,8 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
-#include "sp_headers.h"
#include "sp_quad.h"
+#include "sp_quad_pipe.h"
/**
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 1f0cb3e035..adca5df73d 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2008 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
@@ -42,16 +43,15 @@
#include "sp_context.h"
#include "sp_state.h"
-#include "sp_headers.h"
#include "sp_quad.h"
+#include "sp_quad_pipe.h"
#include "sp_texture.h"
#include "sp_tex_sample.h"
struct quad_shade_stage
{
- struct quad_stage stage;
- struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
+ struct quad_stage stage; /**< base class */
struct tgsi_exec_machine machine;
struct tgsi_exec_vector *inputs, *outputs;
};
@@ -147,18 +147,11 @@ static void shade_begin(struct quad_stage *qs)
{
struct quad_shade_stage *qss = quad_shade_stage(qs);
struct softpipe_context *softpipe = qs->softpipe;
- unsigned i;
- unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers);
-
- /* set TGSI sampler state that varies */
- for (i = 0; i < num; i++) {
- qss->samplers[i].state = softpipe->sampler[i];
- qss->samplers[i].texture = softpipe->texture[i];
- }
softpipe->fs->prepare( softpipe->fs,
&qss->machine,
- qss->samplers );
+ (struct tgsi_sampler **)
+ softpipe->tgsi.frag_samplers_list );
qs->next->begin(qs->next);
}
@@ -178,7 +171,6 @@ static void shade_destroy(struct quad_stage *qs)
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
{
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
- uint i;
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16);
@@ -191,14 +183,6 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
qss->stage.run = shade_quad;
qss->stage.destroy = shade_destroy;
- /* set TGSI sampler state that's constant */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- assert(softpipe->tex_cache[i]);
- qss->samplers[i].get_samples = sp_get_samples;
- qss->samplers[i].pipe = &softpipe->pipe;
- qss->samplers[i].cache = softpipe->tex_cache[i];
- }
-
tgsi_exec_machine_init( &qss->machine );
return &qss->stage;
diff --git a/src/gallium/drivers/softpipe/sp_quad_occlusion.c b/src/gallium/drivers/softpipe/sp_quad_occlusion.c
index 169bd82876..dfa7ff3b1d 100644
--- a/src/gallium/drivers/softpipe/sp_quad_occlusion.c
+++ b/src/gallium/drivers/softpipe/sp_quad_occlusion.c
@@ -35,9 +35,9 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
-#include "sp_surface.h"
#include "sp_quad.h"
+#include "sp_surface.h"
+#include "sp_quad_pipe.h"
static unsigned count_bits( unsigned val )
{
diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c
index b7aac7f84a..92d5f9f3c1 100644
--- a/src/gallium/drivers/softpipe/sp_quad_output.c
+++ b/src/gallium/drivers/softpipe/sp_quad_output.c
@@ -27,9 +27,9 @@
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_headers.h"
-#include "sp_surface.h"
#include "sp_quad.h"
+#include "sp_surface.h"
+#include "sp_quad_pipe.h"
#include "sp_tile_cache.h"
@@ -48,7 +48,7 @@ output_quad(struct quad_stage *qs, struct quad_header *quad)
uint cbuf;
/* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
struct softpipe_cached_tile *tile
= sp_get_cached_tile(softpipe,
softpipe->cbuf_cache[cbuf],
diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c
index 892ef87ee9..892ef87ee9 100644
--- a/src/gallium/drivers/softpipe/sp_quad.c
+++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c
diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.h b/src/gallium/drivers/softpipe/sp_quad_pipe.h
new file mode 100644
index 0000000000..0e40586ffc
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_quad_pipe.h
@@ -0,0 +1,74 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef SP_QUAD_PIPE_H
+#define SP_QUAD_PIPE_H
+
+
+struct softpipe_context;
+struct quad_header;
+
+
+/**
+ * Fragment processing is performed on 2x2 blocks of pixels called "quads".
+ * Quad processing is performed with a pipeline of stages represented by
+ * this type.
+ */
+struct quad_stage {
+ struct softpipe_context *softpipe;
+
+ struct quad_stage *next;
+
+ void (*begin)(struct quad_stage *qs);
+
+ /** the stage action */
+ void (*run)(struct quad_stage *qs, struct quad_header *quad);
+
+ void (*destroy)(struct quad_stage *qs);
+};
+
+
+struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_earlyz_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe );
+struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );
+
+void sp_build_quad_pipeline(struct softpipe_context *sp);
+
+void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad);
+
+#endif /* SP_QUAD_PIPE_H */
diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c
index abb5487748..5e9d447737 100644
--- a/src/gallium/drivers/softpipe/sp_quad_stencil.c
+++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c
@@ -5,10 +5,10 @@
#include "sp_context.h"
-#include "sp_headers.h"
+#include "sp_quad.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
-#include "sp_quad.h"
+#include "sp_quad_pipe.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
@@ -222,8 +222,8 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
zFailOp = softpipe->depth_stencil->stencil[face].zfail_op;
zPassOp = softpipe->depth_stencil->stencil[face].zpass_op;
ref = softpipe->depth_stencil->stencil[face].ref_value;
- wrtMask = softpipe->depth_stencil->stencil[face].write_mask;
- valMask = softpipe->depth_stencil->stencil[face].value_mask;
+ wrtMask = softpipe->depth_stencil->stencil[face].writemask;
+ valMask = softpipe->depth_stencil->stencil[face].valuemask;
assert(ps); /* shouldn't get here if there's no stencil buffer */
diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c
index ccf37f6be5..05e862f097 100644
--- a/src/gallium/drivers/softpipe/sp_quad_stipple.c
+++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c
@@ -4,8 +4,8 @@
*/
#include "sp_context.h"
-#include "sp_headers.h"
#include "sp_quad.h"
+#include "sp_quad_pipe.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
@@ -19,11 +19,13 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
static const uint bit31 = 1 << 31;
static const uint bit30 = 1 << 30;
- if (quad->input.prim == PRIM_TRI) {
+ if (quad->input.prim == QUAD_PRIM_TRI) {
struct softpipe_context *softpipe = qs->softpipe;
/* need to invert Y to index into OpenGL's stipple pattern */
int y0, y1;
uint stipple0, stipple1;
+ const int col0 = quad->input.x0 % 32;
+
if (softpipe->rasterizer->origin_lower_left) {
y0 = softpipe->framebuffer.height - 1 - quad->input.y0;
y1 = y0 - 1;
@@ -32,12 +34,11 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
y0 = quad->input.y0;
y1 = y0 + 1;
}
+
stipple0 = softpipe->poly_stipple.stipple[y0 % 32];
stipple1 = softpipe->poly_stipple.stipple[y1 % 32];
-#if 1
- {
- const int col0 = quad->input.x0 % 32;
+ /* turn off quad mask bits that fail the stipple test */
if ((stipple0 & (bit31 >> col0)) == 0)
quad->inout.mask &= ~MASK_TOP_LEFT;
@@ -49,19 +50,11 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
if ((stipple1 & (bit30 >> col0)) == 0)
quad->inout.mask &= ~MASK_BOTTOM_RIGHT;
- }
-#else
- /* We'd like to use this code, but we'd need to redefine
- * MASK_TOP_LEFT to be (1 << 1) and MASK_TOP_RIGHT to be (1 << 0),
- * and similarly for the BOTTOM bits. But that may have undesirable
- * side effects elsewhere.
- */
- const int col0 = 30 - (quad->input.x0 % 32);
- quad->inout.mask &= (((stipple0 >> col0) & 0x3) |
- (((stipple1 >> col0) & 0x3) << 2));
-#endif
- if (!quad->inout.mask)
+
+ if (!quad->inout.mask) {
+ /* all fragments failed stipple test, end of quad pipeline */
return;
+ }
}
qs->next->run(qs->next, quad);
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index 2106ee1d23..b0d8e01426 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -37,8 +37,8 @@
#include "sp_query.h"
struct softpipe_query {
- uint64 start;
- uint64 end;
+ uint64_t start;
+ uint64_t end;
};
@@ -87,7 +87,7 @@ static boolean
softpipe_get_query_result(struct pipe_context *pipe,
struct pipe_query *q,
boolean wait,
- uint64 *result )
+ uint64_t *result )
{
struct softpipe_query *sq = softpipe_query(q);
*result = sq->end - sq->start;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 9644dbd168..7380a6ae2b 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -27,7 +27,8 @@
#include "util/u_memory.h"
-#include "pipe/p_winsys.h"
+#include "util/u_simple_screen.h"
+#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
@@ -55,7 +56,9 @@ softpipe_get_param(struct pipe_screen *screen, int param)
{
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
+ return PIPE_MAX_SAMPLERS;
+ case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+ return PIPE_MAX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -172,6 +175,7 @@ softpipe_create_screen(struct pipe_winsys *winsys)
screen->base.is_format_supported = softpipe_is_format_supported;
softpipe_init_screen_texture_funcs(&screen->base);
+ u_simple_screen_init(&screen->base);
return &screen->base;
}
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index 13d8017393..0925653b5d 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -32,13 +32,12 @@
* \author Brian Paul
*/
-#include "sp_setup.h"
-
#include "sp_context.h"
-#include "sp_headers.h"
+#include "sp_prim_setup.h"
#include "sp_quad.h"
+#include "sp_quad_pipe.h"
+#include "sp_setup.h"
#include "sp_state.h"
-#include "sp_prim_setup.h"
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#include "draw/draw_vertex.h"
@@ -265,17 +264,20 @@ is_inf_or_nan(float x)
}
-static boolean cull_tri( struct setup_context *setup,
- float det )
+/**
+ * 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) {
/* 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)
+
+ if ((winding & setup->winding) == 0)
return FALSE;
}
@@ -968,7 +970,7 @@ void setup_tri( struct setup_context *setup,
setup_tri_coefficients( setup );
setup_tri_edges( setup );
- setup->quad.input.prim = PRIM_TRI;
+ setup->quad.input.prim = QUAD_PRIM_TRI;
setup->span.y = 0;
setup->span.y_flags = 0;
@@ -1009,7 +1011,7 @@ void setup_tri( struct setup_context *setup,
* for a line.
*/
static void
-line_linear_coeff(struct setup_context *setup,
+line_linear_coeff(const struct setup_context *setup,
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
{
@@ -1029,9 +1031,9 @@ line_linear_coeff(struct setup_context *setup,
* for a line.
*/
static void
-line_persp_coeff(struct setup_context *setup,
- struct tgsi_interp_coef *coef,
- uint vertSlot, uint i)
+line_persp_coeff(const struct setup_context *setup,
+ struct tgsi_interp_coef *coef,
+ uint vertSlot, uint i)
{
/* XXX double-check/verify this arithmetic */
const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3];
@@ -1206,7 +1208,7 @@ setup_line(struct setup_context *setup,
setup->quad.input.x0 = setup->quad.input.y0 = -1;
setup->quad.inout.mask = 0x0;
- setup->quad.input.prim = PRIM_LINE;
+ setup->quad.input.prim = QUAD_PRIM_LINE;
/* XXX temporary: set coverage to 1.0 so the line appears
* if AA mode happens to be enabled.
*/
@@ -1266,7 +1268,7 @@ setup_line(struct setup_context *setup,
static void
-point_persp_coeff(struct setup_context *setup,
+point_persp_coeff(const struct setup_context *setup,
const float (*vert)[4],
struct tgsi_interp_coef *coef,
uint vertSlot, uint i)
@@ -1361,7 +1363,7 @@ setup_point( struct setup_context *setup,
}
}
- setup->quad.input.prim = PRIM_POINT;
+ setup->quad.input.prim = QUAD_PRIM_POINT;
if (halfSize <= 0.5 && !round) {
/* special case for 1-pixel points */
@@ -1497,7 +1499,7 @@ void setup_prepare( struct setup_context *setup )
}
/* Mark surfaces as defined now */
- for (i = 0; i < sp->framebuffer.num_cbufs; i++){
+ for (i = 0; i < sp->framebuffer.nr_cbufs; i++){
if (sp->framebuffer.cbufs[i]) {
sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 476ef3dc8f..6f558e6da5 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -69,7 +69,7 @@ struct sp_fragment_shader {
void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
- struct tgsi_sampler *samplers);
+ struct tgsi_sampler **samplers);
/* Run the shader - this interface will get cleaned up in the
* future:
@@ -184,10 +184,10 @@ softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
void
-softpipe_map_surfaces(struct softpipe_context *sp);
+softpipe_map_transfers(struct softpipe_context *sp);
void
-softpipe_unmap_surfaces(struct softpipe_context *sp);
+softpipe_unmap_transfers(struct softpipe_context *sp);
void
softpipe_map_texture_surfaces(struct softpipe_context *sp);
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index e5b609cf6c..4d01a9dbe1 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -32,7 +32,7 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "pipe/p_inlines.h"
-#include "pipe/p_winsys.h"
+#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "tgsi/tgsi_dump.h"
@@ -146,16 +146,15 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
const struct pipe_constant_buffer *buf)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *screen = pipe->screen;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
/* note: reference counting */
- winsys_buffer_reference(ws,
+ pipe_buffer_reference(screen,
&softpipe->constants[shader].buffer,
buf ? buf->buffer : NULL);
- softpipe->constants[shader].size = buf ? buf->size : 0;
softpipe->dirty |= SP_NEW_CONSTANTS;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index b5376e522d..1493c65884 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -64,7 +64,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
}
}
- sp->framebuffer.num_cbufs = fb->num_cbufs;
+ sp->framebuffer.nr_cbufs = fb->nr_cbufs;
/* zbuf changing? */
if (sp->framebuffer.zsbuf != fb->zsbuf) {
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 49250ec084..adbd0cb7f0 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -2,6 +2,7 @@
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2008 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
@@ -33,17 +34,18 @@
*/
#include "sp_context.h"
-#include "sp_headers.h"
+#include "sp_quad.h"
#include "sp_surface.h"
+#include "sp_texture.h"
#include "sp_tex_sample.h"
#include "sp_tile_cache.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
-#include "tgsi/tgsi_exec.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+
/*
* Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
* see 1-pixel bands of improperly weighted linear-filtered textures.
@@ -57,7 +59,11 @@
/**
* Linear interpolation macro
*/
-#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) )
+static INLINE float
+lerp(float a, float v0, float v1)
+{
+ return v0 + a * (v1 - v0);
+}
/**
@@ -72,13 +78,28 @@ static INLINE float
lerp_2d(float a, float b,
float v00, float v10, float v01, float v11)
{
- const float temp0 = LERP(a, v00, v10);
- const float temp1 = LERP(a, v01, v11);
- return LERP(b, temp0, temp1);
+ const float temp0 = lerp(a, v00, v10);
+ const float temp1 = lerp(a, v01, v11);
+ return lerp(b, temp0, temp1);
}
/**
+ * As above, but 3D interpolation of 8 values.
+ */
+static INLINE float
+lerp_3d(float a, float b, float c,
+ float v000, float v100, float v010, float v110,
+ float v001, float v101, float v011, float v111)
+{
+ const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
+ const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
+ return lerp(c, temp0, temp1);
+}
+
+
+
+/**
* If A is a signed integer, A % B doesn't give the right value for A < 0
* (in terms of texture repeat). Just casting to unsigned fixes that.
*/
@@ -86,250 +107,275 @@ lerp_2d(float a, float b,
/**
- * Apply texture coord wrapping mode and return integer texture index.
+ * Apply texture coord wrapping mode and return integer texture indexes
+ * for a vector of four texcoords (S or T or P).
* \param wrapMode PIPE_TEX_WRAP_x
- * \param s the texcoord
+ * \param s the incoming texcoords
* \param size the texture image size
+ * \param icoord returns the integer texcoords
* \return integer texture index
*/
-static INLINE int
-nearest_texcoord(unsigned wrapMode, float s, unsigned size)
+static INLINE void
+nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
+ int icoord[4])
{
- int i;
+ uint ch;
switch (wrapMode) {
case PIPE_TEX_WRAP_REPEAT:
/* s limited to [0,1) */
/* i limited to [0,size-1] */
- i = util_ifloor(s * size);
- i = REMAINDER(i, size);
- return i;
+ for (ch = 0; ch < 4; ch++) {
+ int i = util_ifloor(s[ch] * size);
+ icoord[ch] = REMAINDER(i, size);
+ }
+ return;
case PIPE_TEX_WRAP_CLAMP:
/* s limited to [0,1] */
/* i limited to [0,size-1] */
- if (s <= 0.0F)
- i = 0;
- else if (s >= 1.0F)
- i = size - 1;
- else
- i = util_ifloor(s * size);
- return i;
+ for (ch = 0; ch < 4; ch++) {
+ if (s[ch] <= 0.0F)
+ icoord[ch] = 0;
+ else if (s[ch] >= 1.0F)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(s[ch] * size);
+ }
+ return;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
{
/* s limited to [min,max] */
/* i limited to [0, size-1] */
const float min = 1.0F / (2.0F * size);
const float max = 1.0F - min;
- if (s < min)
- i = 0;
- else if (s > max)
- i = size - 1;
- else
- i = util_ifloor(s * size);
+ for (ch = 0; ch < 4; ch++) {
+ if (s[ch] < min)
+ icoord[ch] = 0;
+ else if (s[ch] > max)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(s[ch] * size);
+ }
}
- return i;
+ return;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
{
/* s limited to [min,max] */
/* i limited to [-1, size] */
const float min = -1.0F / (2.0F * size);
const float max = 1.0F - min;
- if (s <= min)
- i = -1;
- else if (s >= max)
- i = size;
- else
- i = util_ifloor(s * size);
+ for (ch = 0; ch < 4; ch++) {
+ if (s[ch] <= min)
+ icoord[ch] = -1;
+ else if (s[ch] >= max)
+ icoord[ch] = size;
+ else
+ icoord[ch] = util_ifloor(s[ch] * size);
+ }
}
- return i;
+ return;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
{
const float min = 1.0F / (2.0F * size);
const float max = 1.0F - min;
- const int flr = util_ifloor(s);
- float u;
- if (flr & 1)
- u = 1.0F - (s - (float) flr);
- else
- u = s - (float) flr;
- if (u < min)
- i = 0;
- else if (u > max)
- i = size - 1;
- else
- i = util_ifloor(u * size);
+ for (ch = 0; ch < 4; ch++) {
+ const int flr = util_ifloor(s[ch]);
+ float u;
+ if (flr & 1)
+ u = 1.0F - (s[ch] - (float) flr);
+ else
+ u = s[ch] - (float) flr;
+ if (u < min)
+ icoord[ch] = 0;
+ else if (u > max)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(u * size);
+ }
}
- return i;
+ return;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
- {
+ for (ch = 0; ch < 4; ch++) {
/* s limited to [0,1] */
/* i limited to [0,size-1] */
- const float u = fabsf(s);
+ const float u = fabsf(s[ch]);
if (u <= 0.0F)
- i = 0;
+ icoord[ch] = 0;
else if (u >= 1.0F)
- i = size - 1;
+ icoord[ch] = size - 1;
else
- i = util_ifloor(u * size);
+ icoord[ch] = util_ifloor(u * size);
}
- return i;
+ return;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
{
/* s limited to [min,max] */
/* i limited to [0, size-1] */
const float min = 1.0F / (2.0F * size);
const float max = 1.0F - min;
- const float u = fabsf(s);
- if (u < min)
- i = 0;
- else if (u > max)
- i = size - 1;
- else
- i = util_ifloor(u * size);
+ for (ch = 0; ch < 4; ch++) {
+ const float u = fabsf(s[ch]);
+ if (u < min)
+ icoord[ch] = 0;
+ else if (u > max)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(u * size);
+ }
}
- return i;
+ return;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
{
/* s limited to [min,max] */
/* i limited to [0, size-1] */
const float min = -1.0F / (2.0F * size);
const float max = 1.0F - min;
- const float u = fabsf(s);
- if (u < min)
- i = -1;
- else if (u > max)
- i = size;
- else
- i = util_ifloor(u * size);
+ for (ch = 0; ch < 4; ch++) {
+ const float u = fabsf(s[ch]);
+ if (u < min)
+ icoord[ch] = -1;
+ else if (u > max)
+ icoord[ch] = size;
+ else
+ icoord[ch] = util_ifloor(u * size);
+ }
}
- return i;
+ return;
default:
assert(0);
- return 0;
}
}
/**
- * Used to compute texel locations for linear sampling.
+ * Used to compute texel locations for linear sampling for four texcoords.
* \param wrapMode PIPE_TEX_WRAP_x
- * \param s the texcoord
+ * \param s the texcoords
* \param size the texture image size
- * \param i0 returns first texture index
- * \param i1 returns second texture index (usually *i0 + 1)
- * \param a returns blend factor/weight between texture indexes
+ * \param icoord0 returns first texture indexes
+ * \param icoord1 returns second texture indexes (usually icoord0 + 1)
+ * \param w returns blend factor/weight between texture indexes
+ * \param icoord returns the computed integer texture coords
*/
static INLINE void
-linear_texcoord(unsigned wrapMode, float s, unsigned size,
- int *i0, int *i1, float *a)
+linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
{
- float u;
+ uint ch;
+
switch (wrapMode) {
case PIPE_TEX_WRAP_REPEAT:
- u = s * size - 0.5F;
- *i0 = REMAINDER(util_ifloor(u), size);
- *i1 = REMAINDER(*i0 + 1, size);
- break;
+ for (ch = 0; ch < 4; ch++) {
+ float u = s[ch] * size - 0.5F;
+ icoord0[ch] = REMAINDER(util_ifloor(u), size);
+ icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
+ w[ch] = FRAC(u);
+ }
+ break;;
case PIPE_TEX_WRAP_CLAMP:
- if (s <= 0.0F)
- u = 0.0F;
- else if (s >= 1.0F)
- u = (float) size;
- else
- u = s * size;
- u -= 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
- break;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], 0.0F, 1.0F);
+ u = u * size - 0.5f;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = FRAC(u);
+ }
+ break;;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- if (s <= 0.0F)
- u = 0.0F;
- else if (s >= 1.0F)
- u = (float) size;
- else
- u = s * size;
- u -= 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
- if (*i0 < 0)
- *i0 = 0;
- if (*i1 >= (int) size)
- *i1 = size - 1;
- break;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], 0.0F, 1.0F);
+ u = u * size - 0.5f;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord0[ch] < 0)
+ icoord0[ch] = 0;
+ if (icoord1[ch] >= (int) size)
+ icoord1[ch] = size - 1;
+ w[ch] = FRAC(u);
+ }
+ break;;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
{
const float min = -1.0F / (2.0F * size);
const float max = 1.0F - min;
- if (s <= min)
- u = min * size;
- else if (s >= max)
- u = max * size;
- else
- u = s * size;
- u -= 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], min, max);
+ u = u * size - 0.5f;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = FRAC(u);
+ }
}
- break;
+ break;;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
- {
- const int flr = util_ifloor(s);
+ for (ch = 0; ch < 4; ch++) {
+ const int flr = util_ifloor(s[ch]);
+ float u;
if (flr & 1)
- u = 1.0F - (s - (float) flr);
+ u = 1.0F - (s[ch] - (float) flr);
else
- u = s - (float) flr;
- u = (u * size) - 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
- if (*i0 < 0)
- *i0 = 0;
- if (*i1 >= (int) size)
- *i1 = size - 1;
+ u = s[ch] - (float) flr;
+ u = u * size - 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord0[ch] < 0)
+ icoord0[ch] = 0;
+ if (icoord1[ch] >= (int) size)
+ icoord1[ch] = size - 1;
+ w[ch] = FRAC(u);
}
- break;
+ break;;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
- u = fabsf(s);
- if (u >= 1.0F)
- u = (float) size;
- else
- u *= size;
- u -= 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
- break;
+ for (ch = 0; ch < 4; ch++) {
+ float u = fabsf(s[ch]);
+ if (u >= 1.0F)
+ u = (float) size;
+ else
+ u *= size;
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = FRAC(u);
+ }
+ break;;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- u = fabsf(s);
- if (u >= 1.0F)
- u = (float) size;
- else
- u *= size;
- u -= 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
- if (*i0 < 0)
- *i0 = 0;
- if (*i1 >= (int) size)
- *i1 = size - 1;
- break;
+ for (ch = 0; ch < 4; ch++) {
+ float u = fabsf(s[ch]);
+ if (u >= 1.0F)
+ u = (float) size;
+ else
+ u *= size;
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord0[ch] < 0)
+ icoord0[ch] = 0;
+ if (icoord1[ch] >= (int) size)
+ icoord1[ch] = size - 1;
+ w[ch] = FRAC(u);
+ }
+ break;;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
{
const float min = -1.0F / (2.0F * size);
const float max = 1.0F - min;
- u = fabsf(s);
- if (u <= min)
- u = min * size;
- else if (u >= max)
- u = max * size;
- else
- u *= size;
- u -= 0.5F;
- *i0 = util_ifloor(u);
- *i1 = *i0 + 1;
+ for (ch = 0; ch < 4; ch++) {
+ float u = fabsf(s[ch]);
+ if (u <= min)
+ u = min * size;
+ else if (u >= max)
+ u = max * size;
+ else
+ u *= size;
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = FRAC(u);
+ }
}
- break;
+ break;;
default:
assert(0);
}
- *a = FRAC(u);
}
@@ -337,21 +383,27 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size,
* For RECT textures / unnormalized texcoords
* Only a subset of wrap modes supported.
*/
-static INLINE int
-nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size)
+static INLINE void
+nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
+ int icoord[4])
{
- int i;
+ uint ch;
switch (wrapMode) {
case PIPE_TEX_WRAP_CLAMP:
- i = util_ifloor(s);
- return CLAMP(i, 0, (int) size-1);
+ for (ch = 0; ch < 4; ch++) {
+ int i = util_ifloor(s[ch]);
+ icoord[ch]= CLAMP(i, 0, (int) size-1);
+ }
+ return;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
/* fall-through */
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- return util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
+ for (ch = 0; ch < 4; ch++) {
+ icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
+ }
+ return;
default:
assert(0);
- return 0;
}
}
@@ -361,30 +413,36 @@ nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size)
* Only a subset of wrap modes supported.
*/
static INLINE void
-linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size,
- int *i0, int *i1, float *a)
+linear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
{
+ uint ch;
switch (wrapMode) {
case PIPE_TEX_WRAP_CLAMP:
- /* Not exactly what the spec says, but it matches NVIDIA output */
- s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f);
- *i0 = util_ifloor(s);
- *i1 = *i0 + 1;
- break;
+ for (ch = 0; ch < 4; ch++) {
+ /* Not exactly what the spec says, but it matches NVIDIA output */
+ float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = FRAC(u);
+ }
+ return;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
/* fall-through */
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- s = CLAMP(s, 0.5F, (float) size - 0.5F);
- s -= 0.5F;
- *i0 = util_ifloor(s);
- *i1 = *i0 + 1;
- if (*i1 > (int) size - 1)
- *i1 = size - 1;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord1[ch] > (int) size - 1)
+ icoord1[ch] = size - 1;
+ w[ch] = FRAC(u);
+ }
break;
default:
assert(0);
}
- *a = FRAC(s);
}
@@ -463,7 +521,8 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
* This is only done for fragment shaders, not vertex shaders.
*/
static float
-compute_lambda(struct tgsi_sampler *sampler,
+compute_lambda(const struct pipe_texture *tex,
+ const struct pipe_sampler_state *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
@@ -471,7 +530,7 @@ compute_lambda(struct tgsi_sampler *sampler,
{
float rho, lambda;
- assert(sampler->state->normalized_coords);
+ assert(sampler->normalized_coords);
assert(s);
{
@@ -479,7 +538,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT];
dsdx = fabsf(dsdx);
dsdy = fabsf(dsdy);
- rho = MAX2(dsdx, dsdy) * sampler->texture->width[0];
+ rho = MAX2(dsdx, dsdy) * tex->width[0];
}
if (t) {
float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
@@ -487,7 +546,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float max;
dtdx = fabsf(dtdx);
dtdy = fabsf(dtdy);
- max = MAX2(dtdx, dtdy) * sampler->texture->height[0];
+ max = MAX2(dtdx, dtdy) * tex->height[0];
rho = MAX2(rho, max);
}
if (p) {
@@ -496,13 +555,13 @@ compute_lambda(struct tgsi_sampler *sampler,
float max;
dpdx = fabsf(dpdx);
dpdy = fabsf(dpdy);
- max = MAX2(dpdx, dpdy) * sampler->texture->depth[0];
+ max = MAX2(dpdx, dpdy) * tex->depth[0];
rho = MAX2(rho, max);
}
lambda = util_fast_log2(rho);
- lambda += lodbias + sampler->state->lod_bias;
- lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
+ lambda += lodbias + sampler->lod_bias;
+ lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
return lambda;
}
@@ -514,68 +573,74 @@ compute_lambda(struct tgsi_sampler *sampler,
* 2. Determine if we're minifying or magnifying
* 3. If minifying, choose mipmap levels
* 4. Return image filter to use within mipmap images
+ * \param level0 Returns first mipmap level to sample from
+ * \param level1 Returns second mipmap level to sample from
+ * \param levelBlend Returns blend factor between levels, in [0,1]
+ * \param imgFilter Returns either the min or mag filter, depending on lambda
*/
static void
-choose_mipmap_levels(struct tgsi_sampler *sampler,
+choose_mipmap_levels(const struct pipe_texture *texture,
+ const struct pipe_sampler_state *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
unsigned *level0, unsigned *level1, float *levelBlend,
unsigned *imgFilter)
{
- if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
+ if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
/* no mipmap selection needed */
- *level0 = *level1 = CLAMP((int) sampler->state->min_lod,
- 0, (int) sampler->texture->last_level);
+ *level0 = *level1 = CLAMP((int) sampler->min_lod,
+ 0, (int) texture->last_level);
- if (sampler->state->min_img_filter != sampler->state->mag_img_filter) {
+ if (sampler->min_img_filter != sampler->mag_img_filter) {
/* non-mipmapped texture, but still need to determine if doing
* minification or magnification.
*/
- float lambda = compute_lambda(sampler, s, t, p, lodbias);
+ float lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
if (lambda <= 0.0) {
- *imgFilter = sampler->state->mag_img_filter;
+ *imgFilter = sampler->mag_img_filter;
}
else {
- *imgFilter = sampler->state->min_img_filter;
+ *imgFilter = sampler->min_img_filter;
}
}
else {
- *imgFilter = sampler->state->mag_img_filter;
+ *imgFilter = sampler->mag_img_filter;
}
}
else {
float lambda;
- if (1)
+ if (computeLambda)
/* fragment shader */
- lambda = compute_lambda(sampler, s, t, p, lodbias);
+ lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
else
/* vertex shader */
lambda = lodbias; /* not really a bias, but absolute LOD */
if (lambda <= 0.0) { /* XXX threshold depends on the filter */
/* magnifying */
- *imgFilter = sampler->state->mag_img_filter;
+ *imgFilter = sampler->mag_img_filter;
*level0 = *level1 = 0;
}
else {
/* minifying */
- *imgFilter = sampler->state->min_img_filter;
+ *imgFilter = sampler->min_img_filter;
/* choose mipmap level(s) and compute the blend factor between them */
- if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
+ if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
/* Nearest mipmap level */
const int lvl = (int) (lambda + 0.5);
*level0 =
- *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
+ *level1 = CLAMP(lvl, 0, (int) texture->last_level);
}
else {
/* Linear interpolation between mipmap levels */
const int lvl = (int) lambda;
- *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
- *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
+ *level0 = CLAMP(lvl, 0, (int) texture->last_level);
+ *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level);
*levelBlend = FRAC(lambda); /* blending weight between levels */
}
}
@@ -598,23 +663,29 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
* sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1...
*/
static void
-get_texel(struct tgsi_sampler *sampler,
+get_texel(const struct tgsi_sampler *tgsi_sampler,
unsigned face, unsigned level, int x, int y, int z,
float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
{
- if (x < 0 || x >= (int) sampler->texture->width[level] ||
- y < 0 || y >= (int) sampler->texture->height[level] ||
- z < 0 || z >= (int) sampler->texture->depth[level]) {
- rgba[0][j] = sampler->state->border_color[0];
- rgba[1][j] = sampler->state->border_color[1];
- rgba[2][j] = sampler->state->border_color[2];
- rgba[3][j] = sampler->state->border_color[3];
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ struct softpipe_context *sp = samp->sp;
+ const uint unit = samp->unit;
+ const struct pipe_texture *texture = sp->texture[unit];
+ const struct pipe_sampler_state *sampler = sp->sampler[unit];
+
+ if (x < 0 || x >= (int) texture->width[level] ||
+ y < 0 || y >= (int) texture->height[level] ||
+ z < 0 || z >= (int) texture->depth[level]) {
+ rgba[0][j] = sampler->border_color[0];
+ rgba[1][j] = sampler->border_color[1];
+ rgba[2][j] = sampler->border_color[2];
+ rgba[3][j] = sampler->border_color[3];
}
else {
const int tx = x % TILE_SIZE;
const int ty = y % TILE_SIZE;
const struct softpipe_cached_tile *tile
- = sp_get_cached_tile_tex(sampler->pipe, sampler->cache,
+ = sp_get_cached_tile_tex(sp, samp->cache,
x, y, z, face, level);
rgba[0][j] = tile->data.color[ty][tx][0];
rgba[1][j] = tile->data.color[ty][tx][1];
@@ -624,7 +695,7 @@ get_texel(struct tgsi_sampler *sampler,
{
debug_printf("Get texel %f %f %f %f from %s\n",
rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
- pf_name(sampler->texture->format));
+ pf_name(texture->format));
}
}
}
@@ -682,103 +753,124 @@ shadow_compare(uint compare_func,
* Could probably extend for 3D...
*/
static void
-sp_get_samples_2d_common(struct tgsi_sampler *sampler,
+sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE],
const unsigned faces[4])
{
- const uint compare_func = sampler->state->compare_func;
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ const struct softpipe_context *sp = samp->sp;
+ const uint unit = samp->unit;
+ const struct pipe_texture *texture = sp->texture[unit];
+ const struct pipe_sampler_state *sampler = sp->sampler[unit];
+ const uint compare_func = sampler->compare_func;
unsigned level0, level1, j, imgFilter;
int width, height;
float levelBlend;
- choose_mipmap_levels(sampler, s, t, p, lodbias,
+ choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
- assert(sampler->state->normalized_coords);
+ assert(sampler->normalized_coords);
- width = sampler->texture->width[level0];
- height = sampler->texture->height[level0];
+ width = texture->width[level0];
+ height = texture->height[level0];
assert(width > 0);
switch (imgFilter) {
case PIPE_TEX_FILTER_NEAREST:
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
- int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
- get_texel(sampler, faces[j], level0, x, y, 0, rgba, j);
- if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(compare_func, rgba, p, j);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- unsigned c;
- x = x / 2;
- y = y / 2;
- get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j);
- if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
- shadow_compare(compare_func, rgba2, p, j);
+ {
+ int x[4], y[4];
+ nearest_texcoord_4(sampler->wrap_s, s, width, x);
+ nearest_texcoord_4(sampler->wrap_t, t, height, y);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
+ if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ shadow_compare(compare_func, rgba, p, j);
}
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
+ if (level0 != level1) {
+ /* get texels from second mipmap level and blend */
+ float rgba2[4][4];
+ unsigned c;
+ x[j] /= 2;
+ y[j] /= 2;
+ get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
+ rgba2, j);
+ if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
+ shadow_compare(compare_func, rgba2, p, j);
+ }
+
+ for (c = 0; c < NUM_CHANNELS; c++) {
+ rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
+ }
}
}
}
break;
case PIPE_TEX_FILTER_LINEAR:
case PIPE_TEX_FILTER_ANISO:
- for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4], a, b;
- int x0, y0, x1, y1, c;
- linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &a);
- linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
- get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0);
- get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1);
- get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2);
- get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3);
- if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(compare_func, tx, p, 0);
- shadow_compare(compare_func, tx, p, 1);
- shadow_compare(compare_func, tx, p, 2);
- shadow_compare(compare_func, tx, p, 3);
- }
-
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- x0 = x0 / 2;
- y0 = y0 / 2;
- x1 = x1 / 2;
- y1 = y1 / 2;
- get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0);
- get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1);
- get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2);
- get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3);
- if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
+ {
+ int x0[4], y0[4], x1[4], y1[4];
+ float xw[4], yw[4]; /* weights */
+
+ linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
+ linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ float tx[4][4]; /* texels */
+ int c;
+ get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
+ get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
+ get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
+ get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
+ if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
shadow_compare(compare_func, tx, p, 0);
shadow_compare(compare_func, tx, p, 1);
shadow_compare(compare_func, tx, p, 2);
shadow_compare(compare_func, tx, p, 3);
}
+ /* interpolate R, G, B, A */
for (c = 0; c < 4; c++) {
- rgba2[c][j] = lerp_2d(a, b,
- tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
+ rgba[c][j] = lerp_2d(xw[j], yw[j],
+ tx[c][0], tx[c][1],
+ tx[c][2], tx[c][3]);
}
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
+ if (level0 != level1) {
+ /* get texels from second mipmap level and blend */
+ float rgba2[4][4];
+ x0[j] /= 2;
+ y0[j] /= 2;
+ x1[j] /= 2;
+ y1[j] /= 2;
+ get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
+ get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
+ get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
+ get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
+ if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
+ shadow_compare(compare_func, tx, p, 0);
+ shadow_compare(compare_func, tx, p, 1);
+ shadow_compare(compare_func, tx, p, 2);
+ shadow_compare(compare_func, tx, p, 3);
+ }
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba2[c][j] = lerp_2d(xw[j], yw[j],
+ tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
+ }
+
+ for (c = 0; c < NUM_CHANNELS; c++) {
+ rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
+ }
}
}
}
@@ -789,55 +881,65 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
}
-static void
-sp_get_samples_1d(struct tgsi_sampler *sampler,
+static INLINE void
+sp_get_samples_1d(const struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
static const unsigned faces[4] = {0, 0, 0, 0};
static const float tzero[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, s, tzero, NULL,
+ computeLambda, lodbias, rgba, faces);
}
-static void
-sp_get_samples_2d(struct tgsi_sampler *sampler,
+static INLINE void
+sp_get_samples_2d(const struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
static const unsigned faces[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, s, t, p,
+ computeLambda, lodbias, rgba, faces);
}
-static void
-sp_get_samples_3d(struct tgsi_sampler *sampler,
+static INLINE void
+sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ const struct softpipe_context *sp = samp->sp;
+ const uint unit = samp->unit;
+ const struct pipe_texture *texture = sp->texture[unit];
+ const struct pipe_sampler_state *sampler = sp->sampler[unit];
/* get/map pipe_surfaces corresponding to 3D tex slices */
unsigned level0, level1, j, imgFilter;
int width, height, depth;
float levelBlend;
const uint face = 0;
- choose_mipmap_levels(sampler, s, t, p, lodbias,
+ choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
- assert(sampler->state->normalized_coords);
+ assert(sampler->normalized_coords);
- width = sampler->texture->width[level0];
- height = sampler->texture->height[level0];
- depth = sampler->texture->depth[level0];
+ width = texture->width[level0];
+ height = texture->height[level0];
+ depth = texture->depth[level0];
assert(width > 0);
assert(height > 0);
@@ -845,89 +947,89 @@ sp_get_samples_3d(struct tgsi_sampler *sampler,
switch (imgFilter) {
case PIPE_TEX_FILTER_NEAREST:
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = nearest_texcoord(sampler->state->wrap_s, s[j], width);
- int y = nearest_texcoord(sampler->state->wrap_t, t[j], height);
- int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth);
- get_texel(sampler, face, level0, x, y, z, rgba, j);
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- unsigned c;
- x /= 2;
- y /= 2;
- z /= 2;
- get_texel(sampler, face, level1, x, y, z, rgba2, j);
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]);
+ {
+ int x[4], y[4], z[4];
+ nearest_texcoord_4(sampler->wrap_s, s, width, x);
+ nearest_texcoord_4(sampler->wrap_t, t, height, y);
+ nearest_texcoord_4(sampler->wrap_r, p, depth, z);
+ for (j = 0; j < QUAD_SIZE; j++) {
+ get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
+ if (level0 != level1) {
+ /* get texels from second mipmap level and blend */
+ float rgba2[4][4];
+ unsigned c;
+ x[j] /= 2;
+ y[j] /= 2;
+ z[j] /= 2;
+ get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
+ for (c = 0; c < NUM_CHANNELS; c++) {
+ rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
+ }
}
}
}
break;
case PIPE_TEX_FILTER_LINEAR:
case PIPE_TEX_FILTER_ANISO:
- for (j = 0; j < QUAD_SIZE; j++) {
- float texel0[4][4], texel1[4][4];
- float xw, yw, zw; /* interpolation weights */
- int x0, x1, y0, y1, z0, z1, c;
- linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &xw);
- linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw);
- linear_texcoord(sampler->state->wrap_r, p[j], depth, &z0, &z1, &zw);
- get_texel(sampler, face, level0, x0, y0, z0, texel0, 0);
- get_texel(sampler, face, level0, x1, y0, z0, texel0, 1);
- get_texel(sampler, face, level0, x0, y1, z0, texel0, 2);
- get_texel(sampler, face, level0, x1, y1, z0, texel0, 3);
- get_texel(sampler, face, level0, x0, y0, z1, texel1, 0);
- get_texel(sampler, face, level0, x1, y0, z1, texel1, 1);
- get_texel(sampler, face, level0, x0, y1, z1, texel1, 2);
- get_texel(sampler, face, level0, x1, y1, z1, texel1, 3);
-
- /* 3D lerp */
- for (c = 0; c < 4; c++) {
- float ctemp0[4][4], ctemp1[4][4];
- ctemp0[c][j] = lerp_2d(xw, yw,
- texel0[c][0], texel0[c][1],
- texel0[c][2], texel0[c][3]);
- ctemp1[c][j] = lerp_2d(xw, yw,
- texel1[c][0], texel1[c][1],
- texel1[c][2], texel1[c][3]);
- rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- x0 /= 2;
- y0 /= 2;
- z0 /= 2;
- x1 /= 2;
- y1 /= 2;
- z1 /= 2;
- get_texel(sampler, face, level1, x0, y0, z0, texel0, 0);
- get_texel(sampler, face, level1, x1, y0, z0, texel0, 1);
- get_texel(sampler, face, level1, x0, y1, z0, texel0, 2);
- get_texel(sampler, face, level1, x1, y1, z0, texel0, 3);
- get_texel(sampler, face, level1, x0, y0, z1, texel1, 0);
- get_texel(sampler, face, level1, x1, y0, z1, texel1, 1);
- get_texel(sampler, face, level1, x0, y1, z1, texel1, 2);
- get_texel(sampler, face, level1, x1, y1, z1, texel1, 3);
-
- /* 3D lerp */
+ {
+ int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
+ float xw[4], yw[4], zw[4]; /* interpolation weights */
+ linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
+ linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
+ linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int c;
+ float tx0[4][4], tx1[4][4];
+ get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
+ get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
+ get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
+ get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
+ get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
+ get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
+ get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
+ get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
+
+ /* interpolate R, G, B, A */
for (c = 0; c < 4; c++) {
- float ctemp0[4][4], ctemp1[4][4];
- ctemp0[c][j] = lerp_2d(xw, yw,
- texel0[c][0], texel0[c][1],
- texel0[c][2], texel0[c][3]);
- ctemp1[c][j] = lerp_2d(xw, yw,
- texel1[c][0], texel1[c][1],
- texel1[c][2], texel1[c][3]);
- rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]);
+ rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
+ tx0[c][0], tx0[c][1],
+ tx0[c][2], tx0[c][3],
+ tx1[c][0], tx1[c][1],
+ tx1[c][2], tx1[c][3]);
}
- /* blend mipmap levels */
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]);
+ if (level0 != level1) {
+ /* get texels from second mipmap level and blend */
+ float rgba2[4][4];
+ x0[j] /= 2;
+ y0[j] /= 2;
+ z0[j] /= 2;
+ x1[j] /= 2;
+ y1[j] /= 2;
+ z1[j] /= 2;
+ get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
+ get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
+ get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
+ get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
+ get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
+ get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
+ get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
+ get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
+ tx0[c][0], tx0[c][1],
+ tx0[c][2], tx0[c][3],
+ tx1[c][0], tx1[c][1],
+ tx1[c][2], tx1[c][3]);
+ }
+
+ /* blend mipmap levels */
+ for (c = 0; c < NUM_CHANNELS; c++) {
+ rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
+ }
}
}
}
@@ -939,10 +1041,11 @@ sp_get_samples_3d(struct tgsi_sampler *sampler,
static void
-sp_get_samples_cube(struct tgsi_sampler *sampler,
+sp_get_samples_cube(const struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
@@ -951,67 +1054,80 @@ sp_get_samples_cube(struct tgsi_sampler *sampler,
for (j = 0; j < QUAD_SIZE; j++) {
faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
}
- sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
+ sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
+ computeLambda, lodbias, rgba, faces);
}
static void
-sp_get_samples_rect(struct tgsi_sampler *sampler,
+sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
- static const uint face = 0;
- const uint compare_func = sampler->state->compare_func;
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ const struct softpipe_context *sp = samp->sp;
+ const uint unit = samp->unit;
+ const struct pipe_texture *texture = sp->texture[unit];
+ const struct pipe_sampler_state *sampler = sp->sampler[unit];
+ const uint face = 0;
+ const uint compare_func = sampler->compare_func;
unsigned level0, level1, j, imgFilter;
int width, height;
float levelBlend;
- choose_mipmap_levels(sampler, s, t, p, lodbias,
+ choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
/* texture RECTS cannot be mipmapped */
assert(level0 == level1);
- width = sampler->texture->width[level0];
- height = sampler->texture->height[level0];
+ width = texture->width[level0];
+ height = texture->height[level0];
assert(width > 0);
switch (imgFilter) {
case PIPE_TEX_FILTER_NEAREST:
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width);
- int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height);
- get_texel(sampler, face, level0, x, y, 0, rgba, j);
- if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(compare_func, rgba, p, j);
+ {
+ int x[4], y[4];
+ nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x);
+ nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y);
+ for (j = 0; j < QUAD_SIZE; j++) {
+ get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);
+ if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ shadow_compare(compare_func, rgba, p, j);
+ }
}
}
break;
case PIPE_TEX_FILTER_LINEAR:
case PIPE_TEX_FILTER_ANISO:
- for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4], a, b;
- int x0, y0, x1, y1, c;
- linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width, &x0, &x1, &a);
- linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b);
- get_texel(sampler, face, level0, x0, y0, 0, tx, 0);
- get_texel(sampler, face, level0, x1, y0, 0, tx, 1);
- get_texel(sampler, face, level0, x0, y1, 0, tx, 2);
- get_texel(sampler, face, level0, x1, y1, 0, tx, 3);
- if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(compare_func, tx, p, 0);
- shadow_compare(compare_func, tx, p, 1);
- shadow_compare(compare_func, tx, p, 2);
- shadow_compare(compare_func, tx, p, 3);
- }
-
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
+ {
+ int x0[4], y0[4], x1[4], y1[4];
+ float xw[4], yw[4]; /* weights */
+ linear_texcoord_unnorm_4(sampler->wrap_s, s, width, x0, x1, xw);
+ linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw);
+ for (j = 0; j < QUAD_SIZE; j++) {
+ float tx[4][4]; /* texels */
+ int c;
+ get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0);
+ get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1);
+ get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);
+ get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);
+ if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ shadow_compare(compare_func, tx, p, 0);
+ shadow_compare(compare_func, tx, p, 1);
+ shadow_compare(compare_func, tx, p, 2);
+ shadow_compare(compare_func, tx, p, 3);
+ }
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_2d(xw[j], yw[j],
+ tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
+ }
}
}
break;
@@ -1021,49 +1137,45 @@ sp_get_samples_rect(struct tgsi_sampler *sampler,
}
-
-
/**
- * Called via tgsi_sampler::get_samples()
- * Use the sampler's state setting to get a filtered RGBA value
- * from the sampler's texture.
- *
- * XXX we can implement many versions of this function, each
- * tightly coded for a specific combination of sampler state
- * (nearest + repeat), (bilinear mipmap + clamp), etc.
- *
- * The update_samplers() function in st_atom_sampler.c could create
- * a new tgsi_sampler object for each state combo it finds....
+ * Common code for vertex/fragment program texture sampling.
*/
-void
-sp_get_samples(struct tgsi_sampler *sampler,
+static INLINE void
+sp_get_samples(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
+ boolean computeLambda,
float lodbias,
float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- if (!sampler->texture)
+ const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
+ const struct softpipe_context *sp = samp->sp;
+ const uint unit = samp->unit;
+ const struct pipe_texture *texture = sp->texture[unit];
+ const struct pipe_sampler_state *sampler = sp->sampler[unit];
+
+ if (!texture)
return;
- switch (sampler->texture->target) {
+ switch (texture->target) {
case PIPE_TEXTURE_1D:
- assert(sampler->state->normalized_coords);
- sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
+ assert(sampler->normalized_coords);
+ sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
case PIPE_TEXTURE_2D:
- if (sampler->state->normalized_coords)
- sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
+ if (sampler->normalized_coords)
+ sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
else
- sp_get_samples_rect(sampler, s, t, p, lodbias, rgba);
+ sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
case PIPE_TEXTURE_3D:
- assert(sampler->state->normalized_coords);
- sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
+ assert(sampler->normalized_coords);
+ sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
case PIPE_TEXTURE_CUBE:
- assert(sampler->state->normalized_coords);
- sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
+ assert(sampler->normalized_coords);
+ sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
break;
default:
assert(0);
@@ -1084,3 +1196,34 @@ sp_get_samples(struct tgsi_sampler *sampler,
#endif
}
+
+/**
+ * Called via tgsi_sampler::get_samples() when running a fragment shader.
+ * Get four filtered RGBA values from the sampler's texture.
+ */
+void
+sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba);
+}
+
+
+/**
+ * Called via tgsi_sampler::get_samples() when running a vertex shader.
+ * Get four filtered RGBA values from the sampler's texture.
+ */
+void
+sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba);
+}
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index 404bfd0c36..40d8eb2c2a 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -1,17 +1,73 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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.
+ *
+ **************************************************************************/
+
#ifndef SP_TEX_SAMPLE_H
#define SP_TEX_SAMPLE_H
-struct tgsi_sampler;
+#include "tgsi/tgsi_exec.h"
+
+
+/**
+ * Subclass of tgsi_sampler
+ */
+struct sp_shader_sampler
+{
+ struct tgsi_sampler base; /**< base class */
+
+ uint unit;
+ struct softpipe_context *sp;
+ struct softpipe_tile_cache *cache;
+};
+
+static INLINE const struct sp_shader_sampler *
+sp_shader_sampler(const struct tgsi_sampler *sampler)
+{
+ return (const struct sp_shader_sampler *) sampler;
+}
+
+
+extern void
+sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
+
extern void
-sp_get_samples(struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE]);
+sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
#endif /* SP_TEX_SAMPLE_H */
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index a64dc89f43..28a9784b16 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -33,7 +33,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-#include "pipe/p_winsys.h"
+#include "pipe/internal/p_winsys_screen.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -94,49 +94,23 @@ softpipe_texture_layout(struct pipe_screen *screen,
return spt->buffer != NULL;
}
-/* Hack it up to use the old winsys->surface_alloc_storage()
- * method for now:
- */
static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
struct softpipe_texture * spt)
{
struct pipe_winsys *ws = screen->winsys;
- struct pipe_surface surf;
- unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
- int ret;
-
-
- memset(&surf, 0, sizeof(surf));
-
- ret =ws->surface_alloc_storage( ws,
- &surf,
- spt->base.width[0],
- spt->base.height[0],
- spt->base.format,
- flags,
- spt->base.tex_usage);
- if(ret != 0)
- return FALSE;
-
- if (!surf.buffer) {
- /* allocation failed */
- return FALSE;
- }
+ unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ_WRITE);
- /* Now extract the goodies:
- */
spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
- spt->stride[0] = surf.stride;
- /* Transfer the reference:
- */
- spt->buffer = surf.buffer;
- surf.buffer = NULL;
+ spt->buffer = ws->surface_buffer_create( ws,
+ spt->base.width[0],
+ spt->base.height[0],
+ spt->base.format,
+ usage,
+ &spt->stride[0]);
return spt->buffer != NULL;
}
@@ -231,28 +205,21 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
unsigned face, unsigned level, unsigned zslice,
unsigned usage)
{
- struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps;
assert(level <= pt->last_level);
ps = CALLOC_STRUCT(pipe_surface);
- ps->refcount = 1;
if (ps) {
- assert(ps->refcount);
+ ps->refcount = 1;
pipe_texture_reference(&ps->texture, pt);
- pipe_buffer_reference(screen, &ps->buffer, spt->buffer);
ps->format = pt->format;
- ps->block = pt->block;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->nblocksx = pt->nblocksx[level];
- ps->nblocksy = pt->nblocksy[level];
- ps->stride = spt->stride[level];
ps->offset = spt->level_offset[level];
ps->usage = usage;
-
+
/* Because we are softpipe, anything that the state tracker
* thought was going to be done with the GPU will actually get
* done with the CPU. Let's adjust the flags to take that into
@@ -278,8 +245,7 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
- ps->nblocksy *
- ps->stride;
+ pt->nblocksy[level] * spt->stride[level];
}
else {
assert(face == 0);
@@ -299,37 +265,108 @@ softpipe_tex_surface_release(struct pipe_screen *screen,
* needed post-processing to put them into hardware layout, this is
* where it would happen. For softpipe, nothing to do.
*/
- assert ((*s)->texture);
+ assert(surf->texture);
if (--surf->refcount == 0) {
- pipe_texture_reference(&surf->texture, NULL);
- pipe_buffer_reference(screen, &surf->buffer, NULL);
+ pipe_texture_reference(&surf->texture, NULL);
FREE(surf);
}
*s = NULL;
}
+static struct pipe_transfer *
+softpipe_get_tex_transfer(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ struct softpipe_texture *sptex = softpipe_texture(texture);
+ struct softpipe_transfer *spt;
+ struct pipe_transfer *pt;
+
+ assert(texture);
+ assert(level <= texture->last_level);
+
+ spt = CALLOC_STRUCT(softpipe_transfer);
+ pt = &spt->base;
+ if (spt) {
+ pt->refcount = 1;
+ pipe_texture_reference(&pt->texture, texture);
+ pt->format = texture->format;
+ pt->block = texture->block;
+ pt->x = x;
+ pt->y = y;
+ pt->width = w;
+ pt->height = h;
+ pt->nblocksx = texture->nblocksx[level];
+ pt->nblocksy = texture->nblocksy[level];
+ pt->stride = sptex->stride[level];
+ spt->offset = sptex->level_offset[level];
+ pt->usage = usage;
+ pt->face = face;
+ pt->level = level;
+ pt->zslice = zslice;
+
+ if (texture->target == PIPE_TEXTURE_CUBE ||
+ texture->target == PIPE_TEXTURE_3D) {
+ spt->offset += ((texture->target == PIPE_TEXTURE_CUBE) ? face :
+ zslice) * pt->nblocksy * pt->stride;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+ }
+ return pt;
+}
+
+
+static void
+softpipe_tex_transfer_release(struct pipe_screen *screen,
+ struct pipe_transfer **t)
+{
+ struct softpipe_transfer *transfer = softpipe_transfer(*t);
+ /* Effectively do the texture_update work here - if texture images
+ * needed post-processing to put them into hardware layout, this is
+ * where it would happen. For softpipe, nothing to do.
+ */
+ assert (transfer->base.texture);
+ if (--transfer->base.refcount == 0) {
+ pipe_texture_reference(&transfer->base.texture, NULL);
+ FREE(transfer);
+ }
+ *t = NULL;
+}
+
+
static void *
-softpipe_surface_map( struct pipe_screen *screen,
- struct pipe_surface *surface,
- unsigned flags )
+softpipe_transfer_map( struct pipe_screen *screen,
+ struct pipe_transfer *transfer )
{
ubyte *map;
+ struct softpipe_texture *spt;
+ unsigned flags = 0;
- if (flags & ~surface->usage) {
- assert(0);
- return NULL;
+ assert(transfer->texture);
+ spt = softpipe_texture(transfer->texture);
+
+ if (transfer->usage != PIPE_TRANSFER_READ) {
+ flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
+ }
+
+ if (transfer->usage != PIPE_TRANSFER_WRITE) {
+ flags |= PIPE_BUFFER_USAGE_CPU_READ;
}
- map = pipe_buffer_map( screen, surface->buffer, flags );
+ map = pipe_buffer_map(screen, spt->buffer, flags);
if (map == NULL)
return NULL;
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (surface->texture &&
- (flags & PIPE_BUFFER_USAGE_CPU_WRITE))
+ if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ)
{
/* Do something to notify sharing contexts of a texture change.
* In softpipe, that would mean flushing the texture cache.
@@ -337,15 +374,22 @@ softpipe_surface_map( struct pipe_screen *screen,
softpipe_screen(screen)->timestamp++;
}
- return map + surface->offset;
+ return map + softpipe_transfer(transfer)->offset +
+ transfer->y / transfer->block.height * transfer->stride +
+ transfer->x / transfer->block.width * transfer->block.size;
}
static void
-softpipe_surface_unmap(struct pipe_screen *screen,
- struct pipe_surface *surface)
+softpipe_transfer_unmap(struct pipe_screen *screen,
+ struct pipe_transfer *transfer)
{
- pipe_buffer_unmap( screen, surface->buffer );
+ struct softpipe_texture *spt;
+
+ assert(transfer->texture);
+ spt = softpipe_texture(transfer->texture);
+
+ pipe_buffer_unmap( screen, spt->buffer );
}
@@ -365,6 +409,8 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
screen->get_tex_surface = softpipe_get_tex_surface;
screen->tex_surface_release = softpipe_tex_surface_release;
- screen->surface_map = softpipe_surface_map;
- screen->surface_unmap = softpipe_surface_unmap;
+ screen->get_tex_transfer = softpipe_get_tex_transfer;
+ screen->tex_transfer_release = softpipe_tex_transfer_release;
+ screen->transfer_map = softpipe_transfer_map;
+ screen->transfer_unmap = softpipe_transfer_unmap;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index bf437a7c61..893aa7d11d 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -42,7 +42,7 @@ struct softpipe_texture
struct pipe_texture base;
unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned long stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
/* The data is held here:
*/
@@ -51,14 +51,27 @@ struct softpipe_texture
boolean modified;
};
+struct softpipe_transfer
+{
+ struct pipe_transfer base;
+
+ unsigned long offset;
+};
+
-/** cast wrapper */
+/** cast wrappers */
static INLINE struct softpipe_texture *
softpipe_texture(struct pipe_texture *pt)
{
return (struct softpipe_texture *) pt;
}
+static INLINE struct softpipe_transfer *
+softpipe_transfer(struct pipe_transfer *pt)
+{
+ return (struct softpipe_transfer *) pt;
+}
+
extern void
softpipe_init_texture_funcs( struct softpipe_context *softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index b50c984513..593360aab0 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -26,7 +26,7 @@
**************************************************************************/
/**
- * Framebuffer/surface tile caching.
+ * Texture tile caching.
*
* Author:
* Brian Paul
@@ -40,7 +40,7 @@
#include "sp_texture.h"
#include "sp_tile_cache.h"
-#define NUM_ENTRIES 32
+#define NUM_ENTRIES 50
/** XXX move these */
@@ -52,7 +52,8 @@ struct softpipe_tile_cache
{
struct pipe_screen *screen;
struct pipe_surface *surface; /**< the surface we're caching */
- void *surface_map;
+ struct pipe_transfer *transfer;
+ void *transfer_map;
struct pipe_texture *texture; /**< if caching a texture */
struct softpipe_cached_tile entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
@@ -60,8 +61,8 @@ struct softpipe_tile_cache
uint clear_val;
boolean depth_stencil; /** Is the surface a depth/stencil format? */
- struct pipe_surface *tex_surf;
- void *tex_surf_map;
+ struct pipe_transfer *tex_trans;
+ void *tex_trans_map;
int tex_face, tex_level, tex_z;
struct softpipe_cached_tile tile; /**< scratch tile for clears */
@@ -131,16 +132,19 @@ sp_create_tile_cache( struct pipe_screen *screen )
void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
{
+ struct pipe_screen *screen;
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
/*assert(tc->entries[pos].x < 0);*/
}
- if (tc->surface) {
- pipe_surface_reference(&tc->surface, NULL);
+ if (tc->transfer) {
+ screen = tc->transfer->texture->screen;
+ screen->tex_transfer_release(screen, &tc->transfer);
}
- if (tc->tex_surf) {
- pipe_surface_reference(&tc->tex_surf, NULL);
+ if (tc->tex_trans) {
+ screen = tc->tex_trans->texture->screen;
+ screen->tex_transfer_release(screen, &tc->tex_trans);
}
FREE( tc );
@@ -156,18 +160,29 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
{
assert(!tc->texture);
- if (tc->surface_map) {
- tc->screen->surface_unmap(tc->screen, tc->surface);
- tc->surface_map = NULL;
+ if (tc->transfer) {
+ struct pipe_screen *screen = tc->transfer->texture->screen;
+
+ if (ps == tc->surface)
+ return;
+
+ if (tc->transfer_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->transfer_map = NULL;
+ }
+
+ screen->tex_transfer_release(screen, &tc->transfer);
}
- pipe_surface_reference(&tc->surface, ps);
+ tc->surface = ps;
+
+ if (ps) {
+ struct pipe_screen *screen = ps->texture->screen;
- if (tc->surface) {
- if (tc->surface_map) /* XXX: this is always NULL!? */
- tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
- PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
+ ps->level, ps->zslice,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, ps->width, ps->height);
tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
ps->format == PIPE_FORMAT_X8Z24_UNORM ||
@@ -181,7 +196,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
/**
- * Return the surface being cached.
+ * Return the transfer being cached.
*/
struct pipe_surface *
sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
@@ -191,30 +206,27 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
void
-sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc)
+sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
{
- if (tc->surface && !tc->surface_map)
- tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ);
-
- if (tc->tex_surf && !tc->tex_surf_map)
- tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ if (tc->transfer && !tc->transfer_map)
+ tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
+
+ if (tc->tex_trans && !tc->tex_trans_map)
+ tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
}
void
-sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
+sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
{
- if (tc->surface_map) {
- tc->screen->surface_unmap(tc->screen, tc->surface);
- tc->surface_map = NULL;
+ if (tc->transfer_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->transfer_map = NULL;
}
- if (tc->tex_surf_map) {
- tc->screen->surface_unmap(tc->screen, tc->tex_surf);
- tc->tex_surf_map = NULL;
+ if (tc->tex_trans_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
}
}
@@ -229,15 +241,20 @@ sp_tile_cache_set_texture(struct pipe_context *pipe,
{
uint i;
- assert(!tc->surface);
+ assert(!tc->transfer);
pipe_texture_reference(&tc->texture, texture);
- if (tc->tex_surf_map) {
- tc->screen->surface_unmap(tc->screen, tc->tex_surf);
- tc->tex_surf_map = NULL;
+ if (tc->transfer) {
+ struct pipe_screen *screen = tc->transfer->texture->screen;
+
+ if (tc->tex_trans_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
+ }
+
+ screen->tex_transfer_release(screen, &tc->tex_trans);
}
- pipe_surface_reference(&tc->tex_surf, NULL);
/* mark as entries as invalid/empty */
/* XXX we should try to avoid this when the teximage hasn't changed */
@@ -328,20 +345,20 @@ static void
sp_tile_cache_flush_clear(struct pipe_context *pipe,
struct softpipe_tile_cache *tc)
{
- struct pipe_surface *ps = tc->surface;
- const uint w = tc->surface->width;
- const uint h = tc->surface->height;
+ struct pipe_transfer *pt = tc->transfer;
+ const uint w = tc->transfer->width;
+ const uint h = tc->transfer->height;
uint x, y;
uint numCleared = 0;
/* clear the scratch tile to the clear value */
- clear_tile(&tc->tile, ps->format, tc->clear_val);
+ clear_tile(&tc->tile, pt->format, tc->clear_val);
/* push the tile to all positions marked as clear */
for (y = 0; y < h; y += TILE_SIZE) {
for (x = 0; x < w; x += TILE_SIZE) {
if (is_clear_flag_set(tc->clear_flags, x, y)) {
- pipe_put_tile_raw(ps,
+ pipe_put_tile_raw(pt,
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
@@ -359,28 +376,28 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe,
/**
- * Flush the tile cache: write all dirty tiles back to the surface.
+ * Flush the tile cache: write all dirty tiles back to the transfer.
* any tiles "flagged" as cleared will be "really" cleared.
*/
void
sp_flush_tile_cache(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc)
{
- struct pipe_surface *ps = tc->surface;
+ struct pipe_transfer *pt = tc->transfer;
int inuse = 0, pos;
- if (ps && ps->buffer) {
- /* caching a drawing surface */
+ if (pt) {
+ /* caching a drawing transfer */
for (pos = 0; pos < NUM_ENTRIES; pos++) {
struct softpipe_cached_tile *tile = tc->entries + pos;
if (tile->x >= 0) {
if (tc->depth_stencil) {
- pipe_put_tile_raw(ps,
+ pipe_put_tile_raw(pt,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_put_tile_rgba(ps,
+ pipe_put_tile_rgba(pt,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
@@ -415,7 +432,7 @@ struct softpipe_cached_tile *
sp_get_cached_tile(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc, int x, int y)
{
- struct pipe_surface *ps = tc->surface;
+ struct pipe_transfer *pt = tc->transfer;
/* tile pos in framebuffer: */
const int tile_x = x & ~(TILE_SIZE - 1);
@@ -431,12 +448,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
if (tile->x != -1) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
- pipe_put_tile_raw(ps,
+ pipe_put_tile_raw(pt,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_put_tile_rgba(ps,
+ pipe_put_tile_rgba(pt,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
@@ -448,22 +465,22 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
if (is_clear_flag_set(tc->clear_flags, x, y)) {
/* don't get tile from framebuffer, just clear it */
if (tc->depth_stencil) {
- clear_tile(tile, ps->format, tc->clear_val);
+ clear_tile(tile, pt->format, tc->clear_val);
}
else {
- clear_tile_rgba(tile, ps->format, tc->clear_color);
+ clear_tile_rgba(tile, pt->format, tc->clear_color);
}
clear_clear_flag(tc->clear_flags, x, y);
}
else {
- /* get new tile data from surface */
+ /* get new tile data from transfer */
if (tc->depth_stencil) {
- pipe_get_tile_raw(ps,
+ pipe_get_tile_raw(pt,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_get_tile_rgba(ps,
+ pipe_get_tile_rgba(pt,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
@@ -484,7 +501,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
static INLINE uint
tex_cache_pos(int x, int y, int z, int face, int level)
{
- uint entry = x + y * 5 + z * 4 + face + level;
+ uint entry = x + y * 9 + z * 3 + face + level * 7;
return entry % NUM_ENTRIES;
}
@@ -494,11 +511,11 @@ tex_cache_pos(int x, int y, int z, int face, int level)
* Tiles are read-only and indexed with more params.
*/
const struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct pipe_context *pipe,
+sp_get_cached_tile_tex(struct softpipe_context *sp,
struct softpipe_tile_cache *tc, int x, int y, int z,
int face, int level)
{
- struct pipe_screen *screen = pipe->screen;
+ struct pipe_screen *screen = sp->pipe.screen;
/* tile pos in framebuffer: */
const int tile_x = x & ~(TILE_SIZE - 1);
const int tile_y = y & ~(TILE_SIZE - 1);
@@ -510,8 +527,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
if (tc->texture) {
struct softpipe_texture *spt = softpipe_texture(tc->texture);
if (spt->modified) {
- /* texture was modified, force a cache reload */
- tile->x = -1;
+ /* texture was modified, invalidate all cached tiles */
+ uint p;
+ for (p = 0; p < NUM_ENTRIES; p++) {
+ tile = tc->entries + p;
+ tile->x = -1;
+ }
spt->modified = FALSE;
}
}
@@ -523,28 +544,37 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
level != tile->level) {
/* cache miss */
- /* check if we need to get a new surface */
- if (!tc->tex_surf ||
+#if 0
+ printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos,
+ x/TILE_SIZE, y/TILE_SIZE, z, face, level);
+#endif
+ /* check if we need to get a new transfer */
+ if (!tc->tex_trans ||
tc->tex_face != face ||
tc->tex_level != level ||
tc->tex_z != z) {
- /* get new surface (view into texture) */
+ /* get new transfer (view into texture) */
+
+ if (tc->transfer) {
+ if (tc->tex_trans_map)
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
- if (tc->tex_surf_map)
- tc->screen->surface_unmap(tc->screen, tc->tex_surf);
+ screen->tex_transfer_release(screen, &tc->tex_trans);
+ }
- tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z,
- PIPE_BUFFER_USAGE_CPU_READ);
- tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z,
+ PIPE_TRANSFER_READ, 0, 0,
+ tc->texture->width[level],
+ tc->texture->height[level]);
+ tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
tc->tex_face = face;
tc->tex_level = level;
tc->tex_z = z;
}
- /* get tile from the surface (view into texture) */
- pipe_get_tile_rgba(tc->tex_surf,
+ /* get tile from the transfer (view into texture) */
+ pipe_get_tile_rgba(tc->tex_trans,
tile_x, tile_y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
tile->x = tile_x;
@@ -571,7 +601,7 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue)
tc->clear_val = clearValue;
- switch (tc->surface->format) {
+ switch (tc->transfer->format) {
case PIPE_FORMAT_R8G8B8A8_UNORM:
r = (clearValue >> 24) & 0xff;
g = (clearValue >> 16) & 0xff;
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index bc96c941f6..9ac3fdda94 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -74,10 +74,10 @@ extern struct pipe_surface *
sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc);
+sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc);
+sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc);
extern void
sp_tile_cache_set_texture(struct pipe_context *pipe,
@@ -96,7 +96,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc, int x, int y);
extern const struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct pipe_context *pipe,
+sp_get_cached_tile_tex(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc, int x, int y, int z,
int face, int level);