summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/Makefile7
-rw-r--r--src/gallium/drivers/cell/common.h36
-rw-r--r--src/gallium/drivers/cell/ppu/Makefile21
-rw-r--r--src/gallium/drivers/cell/ppu/cell_clear.c1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c164
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h6
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c7
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.c14
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.h4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c325
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.h (renamed from src/gallium/drivers/cell/ppu/cell_state_sampler.c)59
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c166
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.h (renamed from src/gallium/drivers/cell/ppu/cell_state_surface.c)46
-rw-r--r--src/gallium/drivers/cell/ppu/cell_spu.c10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state.h111
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_blend.c109
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_clip.c84
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c18
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_rasterizer.c106
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c (renamed from src/gallium/drivers/cell/ppu/cell_state_fs.c)31
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c63
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h19
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_fetch.c2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c22
-rw-r--r--src/gallium/drivers/cell/spu/Makefile1
-rw-r--r--src/gallium/drivers/cell/spu/spu_dcache.c125
-rw-r--r--src/gallium/drivers/cell/spu/spu_dcache.h34
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c64
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c22
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h8
-rw-r--r--src/gallium/drivers/cell/spu/spu_texture.c184
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_fetch.c76
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.c68
-rw-r--r--src/gallium/drivers/cell/spu/spu_vertex_shader.h5
-rw-r--r--src/gallium/drivers/failover/Makefile9
-rw-r--r--src/gallium/drivers/failover/SConscript13
-rw-r--r--src/gallium/drivers/failover/fo_context.c14
-rw-r--r--src/gallium/drivers/i915simple/Makefile11
-rw-r--r--src/gallium/drivers/i915simple/SConscript2
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c163
-rw-r--r--src/gallium/drivers/i915simple/i915_context.h54
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_flush.c3
-rw-r--r--src/gallium/drivers/i915simple/i915_fpc.h29
-rw-r--r--src/gallium/drivers/i915simple/i915_fpc_emit.c163
-rw-r--r--src/gallium/drivers/i915simple/i915_fpc_translate.c204
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_emit.c40
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_vbuf.c9
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c250
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.h (renamed from src/gallium/drivers/i965simple/brw_strings.c)69
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c44
-rw-r--r--src/gallium/drivers/i915simple/i915_state_derived.c110
-rw-r--r--src/gallium/drivers/i915simple/i915_state_emit.c39
-rw-r--r--src/gallium/drivers/i915simple/i915_state_immediate.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_state_inlines.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_surface.c45
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c100
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.h38
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h15
-rw-r--r--src/gallium/drivers/i965simple/Makefile24
-rw-r--r--src/gallium/drivers/i965simple/SConscript2
-rw-r--r--src/gallium/drivers/i965simple/brw_context.c153
-rw-r--r--src/gallium/drivers/i965simple/brw_context.h21
-rw-r--r--src/gallium/drivers/i965simple/brw_draw_upload.c2
-rw-r--r--src/gallium/drivers/i965simple/brw_screen.c235
-rw-r--r--src/gallium/drivers/i965simple/brw_screen.h (renamed from src/gallium/drivers/i915simple/i915_strings.c)79
-rw-r--r--src/gallium/drivers/i965simple/brw_sf.c2
-rw-r--r--src/gallium/drivers/i965simple/brw_shader_info.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_state.c18
-rw-r--r--src/gallium/drivers/i965simple/brw_state.h7
-rw-r--r--src/gallium/drivers/i965simple/brw_surface.c44
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c93
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.h41
-rw-r--r--src/gallium/drivers/i965simple/brw_vs.c4
-rw-r--r--src/gallium/drivers/i965simple/brw_vs.h2
-rw-r--r--src/gallium/drivers/i965simple/brw_vs_emit.c6
-rw-r--r--src/gallium/drivers/i965simple/brw_winsys.h4
-rw-r--r--src/gallium/drivers/i965simple/brw_wm.c4
-rw-r--r--src/gallium/drivers/i965simple/brw_wm_decl.c20
-rw-r--r--src/gallium/drivers/i965simple/brw_wm_state.c4
-rw-r--r--src/gallium/drivers/nouveau/nouveau_class.h4
-rw-r--r--src/gallium/drivers/nouveau/nouveau_stateobj.h23
-rw-r--r--src/gallium/drivers/nouveau/nouveau_winsys.h18
-rw-r--r--src/gallium/drivers/nv30/Makefile1
-rw-r--r--src/gallium/drivers/nv30/nv30_context.c87
-rw-r--r--src/gallium/drivers/nv30/nv30_context.h2
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c47
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c153
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.h19
-rw-r--r--src/gallium/drivers/nv30/nv30_surface.c72
-rw-r--r--src/gallium/drivers/nv40/Makefile9
-rw-r--r--src/gallium/drivers/nv40/nv40_context.c251
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h162
-rw-r--r--src/gallium/drivers/nv40/nv40_fragprog.c132
-rw-r--r--src/gallium/drivers/nv40/nv40_fragtex.c48
-rw-r--r--src/gallium/drivers/nv40/nv40_miptree.c57
-rw-r--r--src/gallium/drivers/nv40/nv40_query.c10
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c279
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.h36
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c297
-rw-r--r--src/gallium/drivers/nv40/nv40_state.h2
-rw-r--r--src/gallium/drivers/nv40/nv40_state_blend.c40
-rw-r--r--src/gallium/drivers/nv40/nv40_state_clip.c18
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c137
-rw-r--r--src/gallium/drivers/nv40/nv40_state_fb.c155
-rw-r--r--src/gallium/drivers/nv40/nv40_state_rasterizer.c17
-rw-r--r--src/gallium/drivers/nv40/nv40_state_scissor.c34
-rw-r--r--src/gallium/drivers/nv40/nv40_state_stipple.c39
-rw-r--r--src/gallium/drivers/nv40/nv40_state_viewport.c29
-rw-r--r--src/gallium/drivers/nv40/nv40_state_zsa.c17
-rw-r--r--src/gallium/drivers/nv40/nv40_surface.c72
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c253
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c60
-rw-r--r--src/gallium/drivers/nv50/Makefile1
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c92
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c29
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c119
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h19
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c10
-rw-r--r--src/gallium/drivers/softpipe/Makefile10
-rw-r--r--src/gallium/drivers/softpipe/SConscript4
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c120
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h9
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c39
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_llvm.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c40
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_setup.c67
-rw-r--r--src/gallium/drivers/softpipe/sp_quad.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c165
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h10
-rw-r--r--src/gallium/drivers/softpipe/sp_state_clip.c20
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c50
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c190
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c74
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h18
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c53
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h3
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.h8
143 files changed, 4688 insertions, 3311 deletions
diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile
index 58df6c5009..6161cb6ff8 100644
--- a/src/gallium/drivers/Makefile
+++ b/src/gallium/drivers/Makefile
@@ -2,12 +2,7 @@ TOP = ../../..
include $(TOP)/configs/current
-ifeq ($(CONFIG_NAME), linux-cell)
-CELL_DIR = cell
-endif
-
-SUBDIRS = softpipe i915simple i965simple nv30 nv40 nv50 \
- failover pipebuffer $(CELL_DIR)
+SUBDIRS = $(GALLIUM_DRIVER_DIRS)
default: subdirs
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index 74b131fbef..9a4004535e 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -87,10 +87,13 @@
#define CELL_CMD_STATE_TEXTURE 13
#define CELL_CMD_STATE_VERTEX_INFO 14
#define CELL_CMD_STATE_VIEWPORT 15
-#define CELL_CMD_STATE_VS_ARRAY_INFO 16
-#define CELL_CMD_STATE_BLEND 17
-#define CELL_CMD_VS_EXECUTE 18
-#define CELL_CMD_STATE_ATTRIB_FETCH 19
+#define CELL_CMD_STATE_UNIFORMS 16
+#define CELL_CMD_STATE_VS_ARRAY_INFO 17
+#define CELL_CMD_STATE_BIND_VS 18
+#define CELL_CMD_STATE_BLEND 19
+#define CELL_CMD_STATE_ATTRIB_FETCH 20
+#define CELL_CMD_VS_EXECUTE 21
+#define CELL_CMD_FLUSH_BUFFER_RANGE 22
#define CELL_NUM_BUFFERS 4
@@ -134,7 +137,7 @@ struct cell_array_info
uint pitch; /**< Byte pitch from one entry to the next. */
uint size;
uint function_offset;
-} ALIGN16_ATTRIB;
+};
struct cell_attribute_fetch_code {
@@ -142,32 +145,37 @@ struct cell_attribute_fetch_code {
uint size;
};
+
+struct cell_buffer_range {
+ uint64_t base;
+ unsigned size;
+};
+
+
struct cell_shader_info
{
- unsigned num_outputs;
-
uint64_t declarations;
- unsigned num_declarations;
uint64_t instructions;
- unsigned num_instructions;
- uint64_t uniforms;
uint64_t immediates;
+
+ unsigned num_outputs;
+ unsigned num_declarations;
+ unsigned num_instructions;
unsigned num_immediates;
-} ALIGN16_ATTRIB;
+};
#define SPU_VERTS_PER_BATCH 64
struct cell_command_vs
{
uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */
- struct cell_shader_info shader;
+ uint64_t vOut[SPU_VERTS_PER_BATCH];
unsigned num_elts;
unsigned elts[SPU_VERTS_PER_BATCH];
- uint64_t vOut[SPU_VERTS_PER_BATCH];
float plane[12][4];
unsigned nr_planes;
unsigned nr_attrs;
-} ALIGN16_ATTRIB;
+};
struct cell_command_render
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile
index 196ab777f5..d38fa6ce07 100644
--- a/src/gallium/drivers/cell/ppu/Makefile
+++ b/src/gallium/drivers/cell/ppu/Makefile
@@ -1,6 +1,6 @@
# Gallium3D Cell driver: PPU code
-# This makefile builds the g3dcell.a library which gets pulled into
+# This makefile builds the libcell.a library which gets pulled into
# the main libGL.so library
@@ -8,10 +8,14 @@ TOP = ../../../../..
include $(TOP)/configs/linux-cell
-#PROG = gl4
+# This is the "top-level" cell PPU driver code, will get pulled into libGL.so
+# by the winsys Makefile.
+CELL_LIB = ../libcell.a
-CELL_LIB = libcell.a
+# This is the SPU code. We'd like to be able to put this into the libcell.a
+# archive with the PPU code, but nesting .a libs doesn't seem to work.
+# So, it's pulled into libGL.so in gallium/winsys/xlib/Makefile
SPU_CODE_MODULE = ../spu/g3d_spu.a
@@ -21,14 +25,11 @@ SOURCES = \
cell_context.c \
cell_draw_arrays.c \
cell_flush.c \
- cell_state_blend.c \
- cell_state_clip.c \
cell_state_derived.c \
cell_state_emit.c \
- cell_state_fs.c \
- cell_state_rasterizer.c \
- cell_state_sampler.c \
- cell_state_surface.c \
+ cell_state_shader.c \
+ cell_pipe_state.c \
+ cell_screen.c \
cell_state_vertex.c \
cell_spu.c \
cell_surface.c \
@@ -56,7 +57,7 @@ default: $(CELL_LIB)
$(CELL_LIB): $(OBJECTS) $(SPU_CODE_MODULE)
-# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE)
+# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE) # doesn't work
ar -ru $(CELL_LIB) $(OBJECTS)
#$(PROG): $(PPU_OBJECTS)
diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c
index e588a30d5b..3ffe09add6 100644
--- a/src/gallium/drivers/cell/ppu/cell_clear.c
+++ b/src/gallium/drivers/cell/ppu/cell_clear.c
@@ -41,6 +41,7 @@
#include "cell_batch.h"
#include "cell_flush.h"
#include "cell_spu.h"
+#include "cell_state.h"
void
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index e1eb22f468..ccbbd1d331 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -37,9 +37,12 @@
#include "pipe/p_format.h"
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
-#include "cell/common.h"
+#include "pipe/p_screen.h"
+
#include "draw/draw_context.h"
#include "draw/draw_private.h"
+
+#include "cell/common.h"
#include "cell_clear.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
@@ -48,104 +51,12 @@
#include "cell_state.h"
#include "cell_surface.h"
#include "cell_spu.h"
+#include "cell_pipe_state.h"
#include "cell_texture.h"
#include "cell_vbuf.h"
-static boolean
-cell_is_format_supported( struct pipe_context *pipe,
- enum pipe_format format, uint type )
-{
- /*struct cell_context *cell = cell_context( pipe );*/
-
- switch (type) {
- case PIPE_TEXTURE:
- /* cell supports all texture formats, XXX for now anyway */
- return TRUE;
- case PIPE_SURFACE:
- /* cell supports all (off-screen) surface formats, XXX for now */
- return TRUE;
- default:
- assert(0);
- return FALSE;
- }
-}
-
-
-static int cell_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
- case PIPE_CAP_NPOT_TEXTURES:
- return 1;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 1;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 0;
- case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 1;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 12; /* max 2Kx2K */
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 12; /* max 2Kx2K */
- default:
- return 0;
- }
-}
-
-static float cell_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 255.0; /* arbitrary */
-
- case PIPE_CAP_MAX_POINT_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 255.0; /* arbitrary */
-
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 0.0;
-
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 16.0; /* arbitrary */
-
- default:
- return 0;
- }
-}
-
-
-static const char *
-cell_get_name( struct pipe_context *pipe )
-{
- return "Cell";
-}
-
-static const char *
-cell_get_vendor( struct pipe_context *pipe )
-{
- return "Tungsten Graphics, Inc.";
-}
-
-
-
static void
cell_destroy_context( struct pipe_context *pipe )
{
@@ -173,7 +84,8 @@ cell_draw_create(struct cell_context *cell)
struct pipe_context *
-cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws)
+cell_create_context(struct pipe_screen *screen,
+ struct cell_winsys *cws)
{
struct cell_context *cell;
uint spu, buf;
@@ -186,52 +98,11 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws)
memset(cell, 0, sizeof(*cell));
cell->winsys = cws;
- cell->pipe.winsys = winsys;
+ cell->pipe.winsys = screen->winsys;
+ cell->pipe.screen = screen;
cell->pipe.destroy = cell_destroy_context;
- /* queries */
- cell->pipe.is_format_supported = cell_is_format_supported;
- cell->pipe.get_name = cell_get_name;
- cell->pipe.get_vendor = cell_get_vendor;
- cell->pipe.get_param = cell_get_param;
- cell->pipe.get_paramf = cell_get_paramf;
-
-
/* state setters */
- cell->pipe.create_blend_state = cell_create_blend_state;
- cell->pipe.bind_blend_state = cell_bind_blend_state;
- cell->pipe.delete_blend_state = cell_delete_blend_state;
-
- cell->pipe.create_sampler_state = cell_create_sampler_state;
- cell->pipe.bind_sampler_state = cell_bind_sampler_state;
- cell->pipe.delete_sampler_state = cell_delete_sampler_state;
-
- cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state;
- cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state;
- cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state;
-
- cell->pipe.create_rasterizer_state = cell_create_rasterizer_state;
- cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state;
- cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state;
-
- cell->pipe.create_fs_state = cell_create_fs_state;
- cell->pipe.bind_fs_state = cell_bind_fs_state;
- cell->pipe.delete_fs_state = cell_delete_fs_state;
-
- cell->pipe.create_vs_state = cell_create_vs_state;
- cell->pipe.bind_vs_state = cell_bind_vs_state;
- cell->pipe.delete_vs_state = cell_delete_vs_state;
-
- cell->pipe.set_blend_color = cell_set_blend_color;
- cell->pipe.set_clip_state = cell_set_clip_state;
- cell->pipe.set_constant_buffer = cell_set_constant_buffer;
-
- cell->pipe.set_framebuffer_state = cell_set_framebuffer_state;
-
- cell->pipe.set_polygon_stipple = cell_set_polygon_stipple;
- cell->pipe.set_scissor_state = cell_set_scissor_state;
- cell->pipe.set_viewport_state = cell_set_viewport_state;
-
cell->pipe.set_vertex_buffer = cell_set_vertex_buffer;
cell->pipe.set_vertex_element = cell_set_vertex_element;
@@ -241,30 +112,33 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws)
cell->pipe.clear = cell_clear_surface;
cell->pipe.flush = cell_flush;
- /* textures */
- cell->pipe.texture_create = cell_texture_create;
- cell->pipe.texture_release = cell_texture_release;
- cell->pipe.get_tex_surface = cell_get_tex_surface;
-
- cell->pipe.set_sampler_texture = cell_set_sampler_texture;
-
#if 0
cell->pipe.begin_query = cell_begin_query;
cell->pipe.end_query = cell_end_query;
cell->pipe.wait_query = cell_wait_query;
#endif
+ cell_init_state_functions(cell);
+ cell_init_shader_functions(cell);
cell_init_surface_functions(cell);
+ cell_init_texture_functions(cell);
cell->draw = cell_draw_create(cell);
cell_init_vbuf(cell);
draw_set_rasterize_stage(cell->draw, cell->vbuf);
+ /* convert all points/lines to tris for the time being */
+ draw_wide_point_threshold(cell->draw, 0.0);
+ draw_wide_line_threshold(cell->draw, 0.0);
+
/*
* SPU stuff
*/
cell->num_spus = 6;
+ /* XXX is this in SDK 3.0 only?
+ cell->num_spus = spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
+ */
cell_start_spus(cell);
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index 91f8e542a2..bf27289f3f 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -36,7 +36,7 @@
#include "draw/draw_vbuf.h"
#include "cell_winsys.h"
#include "cell/common.h"
-#include "ppc/rtasm/spe_asm.h"
+#include "rtasm/rtasm_ppc_spe.h"
struct cell_vbuf_render;
@@ -128,12 +128,14 @@ cell_context(struct pipe_context *pipe)
extern struct pipe_context *
-cell_create_context(struct pipe_winsys *ws, struct cell_winsys *cws);
+cell_create_context(struct pipe_screen *screen, struct cell_winsys *cws);
extern void
cell_vertex_shader_queue_flush(struct draw_context *draw);
+/* XXX find a better home for this */
+extern void cell_update_vertex_fetch(struct draw_context *draw);
#endif /* CELL_CONTEXT_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index f12613649b..c839fb4d12 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -38,6 +38,7 @@
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_state.h"
+#include "cell_flush.h"
#include "draw/draw_context.h"
@@ -49,9 +50,12 @@ cell_map_constant_buffers(struct cell_context *sp)
struct pipe_winsys *ws = sp->pipe.winsys;
uint i;
for (i = 0; i < 2; i++) {
- if (sp->constants[i].size)
+ if (sp->constants[i].size) {
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
+ cell_flush_buffer_range(sp, sp->mapped_constants[i],
+ sp->constants[i].buffer->size);
+ }
}
draw_set_mapped_constant_buffer(sp->draw,
@@ -124,6 +128,7 @@ cell_draw_elements(struct pipe_context *pipe,
void *buf = pipe->winsys->buffer_map(pipe->winsys,
sp->vertex_buffer[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
+ cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c
index 20f27531fc..66a5627d84 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.c
+++ b/src/gallium/drivers/cell/ppu/cell_flush.c
@@ -82,3 +82,17 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags)
flushing = FALSE;
}
+
+
+void
+cell_flush_buffer_range(struct cell_context *cell, void *ptr,
+ unsigned size)
+{
+ uint64_t batch[1 + (ROUNDUP8(sizeof(struct cell_buffer_range)) / 8)];
+ struct cell_buffer_range *br = (struct cell_buffer_range *) & batch[1];
+
+ batch[0] = CELL_CMD_FLUSH_BUFFER_RANGE;
+ br->base = (uintptr_t) ptr;
+ br->size = size;
+ cell_batch_append(cell, batch, sizeof(batch));
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h
index eda351b1cb..7f940ae76b 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.h
+++ b/src/gallium/drivers/cell/ppu/cell_flush.h
@@ -35,4 +35,8 @@ cell_flush(struct pipe_context *pipe, unsigned flags);
extern void
cell_flush_int(struct pipe_context *pipe, unsigned flags);
+extern void
+cell_flush_buffer_range(struct cell_context *cell, void *ptr,
+ unsigned size);
+
#endif
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
new file mode 100644
index 0000000000..075e0a0c47
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -0,0 +1,325 @@
+/**************************************************************************
+ *
+ * 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>
+ * Brian Paul
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "draw/draw_context.h"
+#include "cell_context.h"
+#include "cell_state.h"
+#include "cell_texture.h"
+
+
+
+static void *
+cell_create_blend_state(struct pipe_context *pipe,
+ const struct pipe_blend_state *blend)
+{
+ return mem_dup(blend, sizeof(*blend));
+}
+
+
+static void
+cell_bind_blend_state(struct pipe_context *pipe, void *blend)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ draw_flush(cell->draw);
+
+ cell->blend = (const struct pipe_blend_state *)blend;
+
+ cell->dirty |= CELL_NEW_BLEND;
+}
+
+
+static void
+cell_delete_blend_state(struct pipe_context *pipe, void *blend)
+{
+ FREE(blend);
+}
+
+
+static void
+cell_set_blend_color(struct pipe_context *pipe,
+ const struct pipe_blend_color *blend_color)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ draw_flush(cell->draw);
+
+ cell->blend_color = *blend_color;
+
+ cell->dirty |= CELL_NEW_BLEND;
+}
+
+
+
+
+static void *
+cell_create_depth_stencil_alpha_state(struct pipe_context *pipe,
+ const struct pipe_depth_stencil_alpha_state *depth_stencil)
+{
+ return mem_dup(depth_stencil, sizeof(*depth_stencil));
+}
+
+
+static void
+cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
+ void *depth_stencil)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ draw_flush(cell->draw);
+
+ cell->depth_stencil
+ = (const struct pipe_depth_stencil_alpha_state *) depth_stencil;
+
+ cell->dirty |= CELL_NEW_DEPTH_STENCIL;
+}
+
+
+static void
+cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth)
+{
+ FREE(depth);
+}
+
+
+static void cell_set_clip_state( struct pipe_context *pipe,
+ const struct pipe_clip_state *clip )
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ /* pass the clip state to the draw module */
+ draw_set_clip_state(cell->draw, clip);
+}
+
+
+
+/* Called when driver state tracker notices changes to the viewport
+ * matrix:
+ */
+static void
+cell_set_viewport_state( struct pipe_context *pipe,
+ const struct pipe_viewport_state *viewport )
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ cell->viewport = *viewport; /* struct copy */
+ cell->dirty |= CELL_NEW_VIEWPORT;
+
+ /* pass the viewport info to the draw module */
+ draw_set_viewport_state(cell->draw, viewport);
+
+ /* Using tnl/ and vf/ modules is temporary while getting started.
+ * Full pipe will have vertex shader, vertex fetch of its own.
+ */
+}
+
+
+static void
+cell_set_scissor_state( struct pipe_context *pipe,
+ const struct pipe_scissor_state *scissor )
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ memcpy( &cell->scissor, scissor, sizeof(*scissor) );
+ cell->dirty |= CELL_NEW_SCISSOR;
+}
+
+
+static void
+cell_set_polygon_stipple( struct pipe_context *pipe,
+ const struct pipe_poly_stipple *stipple )
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) );
+ cell->dirty |= CELL_NEW_STIPPLE;
+}
+
+
+
+static void *
+cell_create_rasterizer_state(struct pipe_context *pipe,
+ const struct pipe_rasterizer_state *setup)
+{
+ struct pipe_rasterizer_state *state
+ = MALLOC(sizeof(struct pipe_rasterizer_state));
+ memcpy(state, setup, sizeof(struct pipe_rasterizer_state));
+ return state;
+}
+
+
+static void
+cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ /* pass-through to draw module */
+ draw_set_rasterizer_state(cell->draw, setup);
+
+ cell->rasterizer = (struct pipe_rasterizer_state *)setup;
+
+ cell->dirty |= CELL_NEW_RASTERIZER;
+}
+
+
+static void
+cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer)
+{
+ FREE(rasterizer);
+}
+
+
+
+static void *
+cell_create_sampler_state(struct pipe_context *pipe,
+ const struct pipe_sampler_state *sampler)
+{
+ return mem_dup(sampler, sizeof(*sampler));
+}
+
+
+static void
+cell_bind_sampler_state(struct pipe_context *pipe,
+ unsigned unit, void *sampler)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ draw_flush(cell->draw);
+
+ assert(unit < PIPE_MAX_SAMPLERS);
+ cell->sampler[unit] = (struct pipe_sampler_state *)sampler;
+
+ cell->dirty |= CELL_NEW_SAMPLER;
+}
+
+
+static void
+cell_delete_sampler_state(struct pipe_context *pipe,
+ void *sampler)
+{
+ FREE( sampler );
+}
+
+
+
+static void
+cell_set_sampler_texture(struct pipe_context *pipe,
+ unsigned sampler,
+ struct pipe_texture *texture)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ draw_flush(cell->draw);
+
+ pipe_texture_reference((struct pipe_texture **) &cell->texture[sampler],
+ texture);
+
+ cell_update_texture_mapping(cell);
+
+ cell->dirty |= CELL_NEW_TEXTURE;
+}
+
+
+
+static void
+cell_set_framebuffer_state(struct pipe_context *pipe,
+ const struct pipe_framebuffer_state *fb)
+{
+ struct cell_context *cell = cell_context(pipe);
+
+ if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) {
+ struct pipe_surface *csurf = fb->cbufs[0];
+ struct pipe_surface *zsurf = fb->zsbuf;
+ uint i;
+
+ /* unmap old surfaces */
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) {
+ pipe_surface_unmap(cell->framebuffer.cbufs[i]);
+ cell->cbuf_map[i] = NULL;
+ }
+ }
+
+ if (cell->framebuffer.zsbuf && cell->zsbuf_map) {
+ pipe_surface_unmap(cell->framebuffer.zsbuf);
+ cell->zsbuf_map = NULL;
+ }
+
+ /* update my state */
+ cell->framebuffer = *fb;
+
+ /* map new surfaces */
+ if (csurf)
+ cell->cbuf_map[0] = pipe_surface_map(csurf);
+
+ if (zsurf)
+ cell->zsbuf_map = pipe_surface_map(zsurf);
+
+ cell->dirty |= CELL_NEW_FRAMEBUFFER;
+ }
+}
+
+
+
+void
+cell_init_state_functions(struct cell_context *cell)
+{
+ cell->pipe.create_blend_state = cell_create_blend_state;
+ cell->pipe.bind_blend_state = cell_bind_blend_state;
+ cell->pipe.delete_blend_state = cell_delete_blend_state;
+
+ cell->pipe.create_sampler_state = cell_create_sampler_state;
+ cell->pipe.bind_sampler_state = cell_bind_sampler_state;
+ cell->pipe.delete_sampler_state = cell_delete_sampler_state;
+
+ cell->pipe.set_sampler_texture = cell_set_sampler_texture;
+
+ cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state;
+ cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state;
+ cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state;
+
+ cell->pipe.create_rasterizer_state = cell_create_rasterizer_state;
+ cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state;
+ cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state;
+
+ cell->pipe.set_blend_color = cell_set_blend_color;
+ cell->pipe.set_clip_state = cell_set_clip_state;
+
+ cell->pipe.set_framebuffer_state = cell_set_framebuffer_state;
+
+ cell->pipe.set_polygon_stipple = cell_set_polygon_stipple;
+ cell->pipe.set_scissor_state = cell_set_scissor_state;
+ cell->pipe.set_viewport_state = cell_set_viewport_state;
+}
+
diff --git a/src/gallium/drivers/cell/ppu/cell_state_sampler.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.h
index a33421a4ad..1889bd52ff 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_sampler.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,60 +25,15 @@
*
**************************************************************************/
-/* Authors:
- * Brian Paul
- */
-#include "pipe/p_util.h"
-#include "draw/draw_context.h"
-#include "cell_context.h"
-#include "cell_state.h"
-#include "cell_texture.h"
+#ifndef CELL_PIPE_STATE_H
+#define CELL_PIPE_STATE_H
-void *
-cell_create_sampler_state(struct pipe_context *pipe,
- const struct pipe_sampler_state *sampler)
-{
- return mem_dup(sampler, sizeof(*sampler));
-}
+struct cell_context;
-void
-cell_bind_sampler_state(struct pipe_context *pipe,
- unsigned unit, void *sampler)
-{
- struct cell_context *cell = cell_context(pipe);
+extern void
+cell_init_state_functions(struct cell_context *cell);
- draw_flush(cell->draw);
- assert(unit < PIPE_MAX_SAMPLERS);
- cell->sampler[unit] = (struct pipe_sampler_state *)sampler;
-
- cell->dirty |= CELL_NEW_SAMPLER;
-}
-
-
-void
-cell_delete_sampler_state(struct pipe_context *pipe,
- void *sampler)
-{
- FREE( sampler );
-}
-
-
-
-void
-cell_set_sampler_texture(struct pipe_context *pipe,
- unsigned sampler,
- struct pipe_texture *texture)
-{
- struct cell_context *cell = cell_context(pipe);
-
- draw_flush(cell->draw);
-
- cell->texture[sampler] = texture;
-
- cell_update_texture_mapping(cell);
-
- cell->dirty |= CELL_NEW_TEXTURE;
-}
+#endif /* CELL_PIPE_STATE_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
new file mode 100644
index 0000000000..124670df25
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -0,0 +1,166 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
+#include "cell_screen.h"
+#include "cell_texture.h"
+#include "cell_winsys.h"
+
+
+static const char *
+cell_get_vendor(struct pipe_screen *screen)
+{
+ return "Tungsten Graphics, Inc.";
+}
+
+
+static const char *
+cell_get_name(struct pipe_screen *screen)
+{
+ return "Cell";
+}
+
+
+static int
+cell_get_param(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 8;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 1;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 0;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 1;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 12; /* max 2Kx2K */
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 8; /* max 128x128x128 */
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 12; /* max 2Kx2K */
+ default:
+ return 0;
+ }
+}
+
+
+static float
+cell_get_paramf(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 255.0; /* arbitrary */
+
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 255.0; /* arbitrary */
+
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 0.0;
+
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0; /* arbitrary */
+
+ default:
+ return 0;
+ }
+}
+
+
+static boolean
+cell_is_format_supported( struct pipe_screen *screen,
+ enum pipe_format format, uint type )
+{
+ switch (type) {
+ case PIPE_TEXTURE:
+ /* cell supports all texture formats, XXX for now anyway */
+ return TRUE;
+ case PIPE_SURFACE:
+ /* cell supports all (off-screen) surface formats, XXX for now */
+ return TRUE;
+ default:
+ assert(0);
+ return FALSE;
+ }
+}
+
+
+static void
+cell_destroy_screen( struct pipe_screen *screen )
+{
+ FREE(screen);
+}
+
+
+/**
+ * Create a new pipe_screen object
+ * Note: we're not presently subclassing pipe_screen (no cell_screen) but
+ * that would be the place to put SPU thread/context info...
+ */
+struct pipe_screen *
+cell_create_screen(struct pipe_winsys *winsys)
+{
+ struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+
+ if (!screen)
+ return NULL;
+
+ screen->winsys = winsys;
+
+ screen->destroy = cell_destroy_screen;
+
+ screen->get_name = cell_get_name;
+ screen->get_vendor = cell_get_vendor;
+ screen->get_param = cell_get_param;
+ screen->get_paramf = cell_get_paramf;
+ screen->is_format_supported = cell_is_format_supported;
+
+ cell_init_screen_texture_funcs(screen);
+
+ return screen;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_surface.c b/src/gallium/drivers/cell/ppu/cell_screen.h
index 287610b76b..c7e15889d6 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_surface.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,46 +26,16 @@
**************************************************************************/
-#include "pipe/p_inlines.h"
-#include "cell_context.h"
-#include "cell_state.h"
+#ifndef CELL_SCREEN_H
+#define CELL_SCREEN_H
-void
-cell_set_framebuffer_state(struct pipe_context *pipe,
- const struct pipe_framebuffer_state *fb)
-{
- struct cell_context *cell = cell_context(pipe);
+struct pipe_screen;
+struct pipe_winsys;
- if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) {
- struct pipe_surface *csurf = fb->cbufs[0];
- struct pipe_surface *zsurf = fb->zsbuf;
- uint i;
- /* unmap old surfaces */
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
- if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) {
- pipe_surface_unmap(cell->framebuffer.cbufs[i]);
- cell->cbuf_map[i] = NULL;
- }
- }
+extern struct pipe_screen *
+cell_create_screen(struct pipe_winsys *winsys);
- if (cell->framebuffer.zsbuf && cell->zsbuf_map) {
- pipe_surface_unmap(cell->framebuffer.zsbuf);
- cell->zsbuf_map = NULL;
- }
-
- /* update my state */
- cell->framebuffer = *fb;
-
- /* map new surfaces */
- if (csurf)
- cell->cbuf_map[0] = pipe_surface_map(csurf);
-
- if (zsurf)
- cell->zsbuf_map = pipe_surface_map(zsurf);
-
- cell->dirty |= CELL_NEW_FRAMEBUFFER;
- }
-}
+#endif /* CELL_SCREEN_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_spu.c b/src/gallium/drivers/cell/ppu/cell_spu.c
index 419e74dc40..973c0b1aa1 100644
--- a/src/gallium/drivers/cell/ppu/cell_spu.c
+++ b/src/gallium/drivers/cell/ppu/cell_spu.c
@@ -97,8 +97,18 @@ static void *cell_thread_function(void *arg)
void
cell_start_spus(struct cell_context *cell)
{
+ static boolean one_time_init = FALSE;
uint i, j;
+
+ if (one_time_init) {
+ fprintf(stderr, "PPU: Multiple rendering contexts not yet supported "
+ "on Cell.\n");
+ abort();
+ }
+
+ one_time_init = TRUE;
+
assert(cell->num_spus <= MAX_SPUS);
ASSERT_ALIGN16(&cell_global.command[0]);
diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h
index 3a71ba14fa..31ce505e21 100644
--- a/src/gallium/drivers/cell/ppu/cell_state.h
+++ b/src/gallium/drivers/cell/ppu/cell_state.h
@@ -1,3 +1,29 @@
+/**************************************************************************
+ *
+ * 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 CELL_STATE_H
@@ -22,82 +48,6 @@
#define CELL_NEW_VERTEX_INFO 0x8000
-
-extern void
-cell_set_framebuffer_state( struct pipe_context *,
- const struct pipe_framebuffer_state * );
-
-
-
-extern void *
-cell_create_blend_state(struct pipe_context *, const struct pipe_blend_state *);
-extern void cell_bind_blend_state(struct pipe_context *, void *);
-extern void cell_delete_blend_state(struct pipe_context *, void *);
-
-extern void cell_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color );
-
-
-void *
-cell_create_sampler_state(struct pipe_context *,
- const struct pipe_sampler_state *);
-
-extern void
-cell_bind_sampler_state(struct pipe_context *, unsigned, void *);
-
-extern void
-cell_delete_sampler_state(struct pipe_context *, void *);
-
-
-extern void *
-cell_create_depth_stencil_alpha_state(struct pipe_context *,
- const struct pipe_depth_stencil_alpha_state *);
-
-extern void
-cell_bind_depth_stencil_alpha_state(struct pipe_context *, void *);
-
-extern void
-cell_delete_depth_stencil_alpha_state(struct pipe_context *, void *);
-
-
-void *cell_create_fs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void cell_bind_fs_state(struct pipe_context *, void *);
-void cell_delete_fs_state(struct pipe_context *, void *);
-void *cell_create_vs_state(struct pipe_context *,
- const struct pipe_shader_state *);
-void cell_bind_vs_state(struct pipe_context *, void *);
-void cell_delete_vs_state(struct pipe_context *, void *);
-
-
-void *
-cell_create_rasterizer_state(struct pipe_context *,
- const struct pipe_rasterizer_state *);
-void cell_bind_rasterizer_state(struct pipe_context *, void *);
-void cell_delete_rasterizer_state(struct pipe_context *, void *);
-
-
-void cell_set_clip_state( struct pipe_context *,
- const struct pipe_clip_state * );
-
-void cell_set_constant_buffer(struct pipe_context *pipe,
- uint shader, uint index,
- const struct pipe_constant_buffer *buf);
-
-void cell_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
-
-void
-cell_set_sampler_texture(struct pipe_context *pipe,
- unsigned sampler,
- struct pipe_texture *texture);
-
-void cell_set_scissor_state( struct pipe_context *,
- const struct pipe_scissor_state * );
-
-void cell_set_texture_state( struct pipe_context *,
- unsigned unit, struct pipe_texture * );
-
void cell_set_vertex_element(struct pipe_context *,
unsigned index,
const struct pipe_vertex_element *);
@@ -106,10 +56,11 @@ void cell_set_vertex_buffer(struct pipe_context *,
unsigned index,
const struct pipe_vertex_buffer *);
-void cell_set_viewport_state( struct pipe_context *,
- const struct pipe_viewport_state * );
+void cell_update_derived( struct cell_context *softpipe );
-void cell_update_derived( struct cell_context *softpipe );
+void
+cell_init_shader_functions(struct cell_context *cell);
+
+#endif /* CELL_STATE_H */
-#endif
diff --git a/src/gallium/drivers/cell/ppu/cell_state_blend.c b/src/gallium/drivers/cell/ppu/cell_state_blend.c
deleted file mode 100644
index b6d6d71f0c..0000000000
--- a/src/gallium/drivers/cell/ppu/cell_state_blend.c
+++ /dev/null
@@ -1,109 +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>
- */
-
-#include "pipe/p_util.h"
-#include "draw/draw_context.h"
-#include "cell_context.h"
-#include "cell_state.h"
-
-
-
-void *
-cell_create_blend_state(struct pipe_context *pipe,
- const struct pipe_blend_state *blend)
-{
- return mem_dup(blend, sizeof(*blend));
-}
-
-
-void
-cell_bind_blend_state(struct pipe_context *pipe, void *blend)
-{
- struct cell_context *cell = cell_context(pipe);
-
- draw_flush(cell->draw);
-
- cell->blend = (const struct pipe_blend_state *)blend;
-
- cell->dirty |= CELL_NEW_BLEND;
-}
-
-
-void
-cell_delete_blend_state(struct pipe_context *pipe, void *blend)
-{
- FREE(blend);
-}
-
-
-void
-cell_set_blend_color(struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color)
-{
- struct cell_context *cell = cell_context(pipe);
-
- draw_flush(cell->draw);
-
- cell->blend_color = *blend_color;
-
- cell->dirty |= CELL_NEW_BLEND;
-}
-
-
-
-
-void *
-cell_create_depth_stencil_alpha_state(struct pipe_context *pipe,
- const struct pipe_depth_stencil_alpha_state *depth_stencil)
-{
- return mem_dup(depth_stencil, sizeof(*depth_stencil));
-}
-
-
-void
-cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
- void *depth_stencil)
-{
- struct cell_context *cell = cell_context(pipe);
-
- draw_flush(cell->draw);
-
- cell->depth_stencil
- = (const struct pipe_depth_stencil_alpha_state *) depth_stencil;
-
- cell->dirty |= CELL_NEW_DEPTH_STENCIL;
-}
-
-
-void
-cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth)
-{
- FREE(depth);
-}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_clip.c b/src/gallium/drivers/cell/ppu/cell_state_clip.c
deleted file mode 100644
index 0482f87e88..0000000000
--- a/src/gallium/drivers/cell/ppu/cell_state_clip.c
+++ /dev/null
@@ -1,84 +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>
- */
-
-#include "cell_context.h"
-#include "cell_state.h"
-#include "draw/draw_context.h"
-
-
-void cell_set_clip_state( struct pipe_context *pipe,
- const struct pipe_clip_state *clip )
-{
- struct cell_context *cell = cell_context(pipe);
-
- /* pass the clip state to the draw module */
- draw_set_clip_state(cell->draw, clip);
-}
-
-
-
-/* Called when driver state tracker notices changes to the viewport
- * matrix:
- */
-void cell_set_viewport_state( struct pipe_context *pipe,
- const struct pipe_viewport_state *viewport )
-{
- struct cell_context *cell = cell_context(pipe);
-
- cell->viewport = *viewport; /* struct copy */
- cell->dirty |= CELL_NEW_VIEWPORT;
-
- /* pass the viewport info to the draw module */
- draw_set_viewport_state(cell->draw, viewport);
-
- /* Using tnl/ and vf/ modules is temporary while getting started.
- * Full pipe will have vertex shader, vertex fetch of its own.
- */
-}
-
-
-void cell_set_scissor_state( struct pipe_context *pipe,
- const struct pipe_scissor_state *scissor )
-{
- struct cell_context *cell = cell_context(pipe);
-
- memcpy( &cell->scissor, scissor, sizeof(*scissor) );
- cell->dirty |= CELL_NEW_SCISSOR;
-}
-
-
-void cell_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
-{
- struct cell_context *cell = cell_context(pipe);
-
- memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) );
- cell->dirty |= CELL_NEW_STIPPLE;
-}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 5d2a786449..49c0d130c5 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -31,6 +31,8 @@
#include "cell_state_emit.h"
#include "cell_batch.h"
#include "cell_texture.h"
+#include "draw/draw_context.h"
+#include "draw/draw_private.h"
static void
@@ -100,4 +102,20 @@ cell_emit_state(struct cell_context *cell)
emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO,
&cell->vertex_info, sizeof(struct vertex_info));
}
+
+ if (cell->dirty & CELL_NEW_VS) {
+ const struct draw_context *const draw = cell->draw;
+ struct cell_shader_info info;
+
+ info.num_outputs = draw->num_vs_outputs;
+ info.declarations = (uintptr_t) draw->machine.Declarations;
+ info.num_declarations = draw->machine.NumDeclarations;
+ info.instructions = (uintptr_t) draw->machine.Instructions;
+ info.num_instructions = draw->machine.NumInstructions;
+ info.immediates = (uintptr_t) draw->machine.Imms;
+ info.num_immediates = draw->machine.ImmLimit / 4;
+
+ emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS,
+ & info, sizeof(info));
+ }
}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c
deleted file mode 100644
index 7eca5b5765..0000000000
--- a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c
+++ /dev/null
@@ -1,106 +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.
- *
- **************************************************************************/
-
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-#include "draw/draw_context.h"
-#include "cell_context.h"
-#include "cell_state.h"
-
-
-
-struct spu_rasterizer_state
-{
- unsigned flatshade:1;
-#if 0
- unsigned light_twoside:1;
- unsigned front_winding:2; /**< PIPE_WINDING_x */
- unsigned cull_mode:2; /**< PIPE_WINDING_x */
- unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */
- unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */
- unsigned offset_cw:1;
- unsigned offset_ccw:1;
-#endif
- unsigned scissor:1;
- unsigned poly_smooth:1;
- unsigned poly_stipple_enable:1;
- unsigned point_smooth:1;
-#if 0
- unsigned point_sprite:1;
- unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
-#endif
- unsigned multisample:1; /* XXX maybe more ms state in future */
- unsigned line_smooth:1;
- unsigned line_stipple_enable:1;
- unsigned line_stipple_factor:8; /**< [1..256] actually */
- unsigned line_stipple_pattern:16;
-#if 0
- unsigned bypass_clipping:1;
-#endif
- unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */
-
- float line_width;
- float point_size; /**< used when no per-vertex size */
-#if 0
- float offset_units;
- float offset_scale;
- ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
-#endif
-};
-
-
-
-void *
-cell_create_rasterizer_state(struct pipe_context *pipe,
- const struct pipe_rasterizer_state *setup)
-{
- struct pipe_rasterizer_state *state
- = MALLOC(sizeof(struct pipe_rasterizer_state));
- memcpy(state, setup, sizeof(struct pipe_rasterizer_state));
- return state;
-}
-
-
-void
-cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup)
-{
- struct cell_context *cell = cell_context(pipe);
-
- /* pass-through to draw module */
- draw_set_rasterizer_state(cell->draw, setup);
-
- cell->rasterizer = (struct pipe_rasterizer_state *)setup;
-
- cell->dirty |= CELL_NEW_RASTERIZER;
-}
-
-
-void
-cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer)
-{
- FREE(rasterizer);
-}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c
index b2ed699a5b..935501441b 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_fs.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -32,7 +32,7 @@
#include "draw/draw_context.h"
#if 0
#include "pipe/p_shader_tokens.h"
-#include "llvm/gallivm.h"
+#include "gallivm/gallivm.h"
#include "tgsi/util/tgsi_dump.h"
#include "tgsi/exec/tgsi_sse2.h"
#endif
@@ -41,7 +41,7 @@
#include "cell_state.h"
-void *
+static void *
cell_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -80,7 +80,7 @@ cell_create_fs_state(struct pipe_context *pipe,
}
-void
+static void
cell_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct cell_context *cell = cell_context(pipe);
@@ -91,7 +91,7 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs)
}
-void
+static void
cell_delete_fs_state(struct pipe_context *pipe, void *fs)
{
struct cell_fragment_shader_state *state =
@@ -101,7 +101,7 @@ cell_delete_fs_state(struct pipe_context *pipe, void *fs)
}
-void *
+static void *
cell_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@@ -124,7 +124,7 @@ cell_create_vs_state(struct pipe_context *pipe,
}
-void
+static void
cell_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct cell_context *cell = cell_context(pipe);
@@ -137,7 +137,7 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs)
}
-void
+static void
cell_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct cell_context *cell = cell_context(pipe);
@@ -150,7 +150,7 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs)
}
-void
+static void
cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
@@ -169,3 +169,18 @@ cell_set_constant_buffer(struct pipe_context *pipe,
cell->dirty |= CELL_NEW_CONSTANTS;
}
+
+
+void
+cell_init_shader_functions(struct cell_context *cell)
+{
+ cell->pipe.create_fs_state = cell_create_fs_state;
+ cell->pipe.bind_fs_state = cell_bind_fs_state;
+ cell->pipe.delete_fs_state = cell_delete_fs_state;
+
+ cell->pipe.create_vs_state = cell_create_vs_state;
+ cell->pipe.bind_vs_state = cell_bind_vs_state;
+ cell->pipe.delete_vs_state = cell_delete_vs_state;
+
+ cell->pipe.set_constant_buffer = cell_set_constant_buffer;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index c8ef36002f..e235421107 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -79,20 +79,24 @@ cell_texture_layout(struct cell_texture * spt)
}
-struct pipe_texture *
-cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat)
+static struct pipe_texture *
+cell_texture_create_screen(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
+ struct pipe_winsys *ws = screen->winsys;
struct cell_texture *spt = CALLOC_STRUCT(cell_texture);
if (!spt)
return NULL;
spt->base = *templat;
+ spt->base.refcount = 1;
+ spt->base.screen = screen;
cell_texture_layout(spt);
- spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- spt->buffer_size);
+ spt->buffer = ws->buffer_create(ws, 32,
+ PIPE_BUFFER_USAGE_PIXEL,
+ spt->buffer_size);
if (!spt->buffer) {
FREE(spt);
@@ -103,8 +107,9 @@ cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templa
}
-void
-cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+static void
+cell_texture_release_screen(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -120,7 +125,7 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
- pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL);
+ pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
FREE(spt);
}
@@ -128,22 +133,28 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
}
-/**
- * Called via pipe->get_tex_surface()
- */
-struct pipe_surface *
-cell_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+static void
+cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture)
+{
+ /* XXX TO DO: re-tile the texture data ... */
+
+}
+
+
+static struct pipe_surface *
+cell_get_tex_surface_screen(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
{
+ struct pipe_winsys *ws = screen->winsys;
struct cell_texture *spt = cell_texture(pt);
struct pipe_surface *ps;
- ps = pipe->winsys->surface_alloc(pipe->winsys);
+ ps = ws->surface_alloc(ws);
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
- pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
+ pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
@@ -198,6 +209,7 @@ static void
cell_tile_texture(struct cell_context *cell,
struct cell_texture *texture)
{
+ struct pipe_screen *screen = cell->pipe.screen;
uint face = 0, level = 0, zslice = 0;
struct pipe_surface *surf;
const uint w = texture->base.width[0], h = texture->base.height[0];
@@ -209,7 +221,7 @@ cell_tile_texture(struct cell_context *cell,
assert(w % TILE_SIZE == 0);
assert(h % TILE_SIZE == 0);
- surf = cell_get_tex_surface(&cell->pipe, &texture->base, face, level, zslice);
+ surf = screen->get_tex_surface(screen, &texture->base, face, level, zslice);
ASSERT(surf);
src = (const uint *) pipe_surface_map(surf);
@@ -250,3 +262,18 @@ cell_update_texture_mapping(struct cell_context *cell)
cell->tex_map = pipe_surface_map(cell->tex_surf);
#endif
}
+
+
+void
+cell_init_texture_functions(struct cell_context *cell)
+{
+ cell->pipe.texture_update = cell_texture_update;
+}
+
+void
+cell_init_screen_texture_funcs(struct pipe_screen *screen)
+{
+ screen->texture_create = cell_texture_create_screen;
+ screen->texture_release = cell_texture_release_screen;
+ screen->get_tex_surface = cell_get_tex_surface_screen;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h
index 0264fed88e..fcee069d05 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.h
+++ b/src/gallium/drivers/cell/ppu/cell_texture.h
@@ -29,7 +29,7 @@
#define CELL_TEXTURE_H
-struct pipe_context;
+struct cell_context;
struct pipe_texture;
@@ -60,21 +60,16 @@ cell_texture(struct pipe_texture *pt)
-extern struct pipe_texture *
-cell_texture_create(struct pipe_context *pipe,
- const struct pipe_texture *templat);
-
extern void
-cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+cell_update_texture_mapping(struct cell_context *cell);
-extern struct pipe_surface *
-cell_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice);
+
+extern void
+cell_init_texture_functions(struct cell_context *cell);
extern void
-cell_update_texture_mapping(struct cell_context *cell);
+cell_init_screen_texture_funcs(struct pipe_screen *screen);
-#endif /* CELL_TEXTURE */
+#endif /* CELL_TEXTURE_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
index f10689a959..9cf74bab47 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c
@@ -31,7 +31,7 @@
#include "../auxiliary/draw/draw_private.h"
#include "cell_context.h"
-#include "ppc/rtasm/spe_asm.h"
+#include "rtasm/rtasm_ppc_spe.h"
typedef uint64_t register_mask;
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
index 6a1d3bc20a..f5c27852c1 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
@@ -35,6 +35,7 @@
#include "cell_context.h"
#include "cell_draw_arrays.h"
+#include "cell_flush.h"
#include "cell_spu.h"
#include "cell_batch.h"
@@ -100,17 +101,17 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
(void) memcpy(&batch[1], &draw->viewport,
sizeof(struct pipe_viewport_state));
+ {
+ uint64_t uniforms = (uintptr_t) draw->user.constants;
+
+ batch = cell_batch_alloc(cell, 2 *sizeof(batch[0]));
+ batch[0] = CELL_CMD_STATE_UNIFORMS;
+ batch[1] = uniforms;
+ }
+
cell_batch_flush(cell);
vs->opcode = CELL_CMD_VS_EXECUTE;
- vs->shader.num_outputs = draw->num_vs_outputs;
- vs->shader.declarations = (uintptr_t) draw->machine.Declarations;
- vs->shader.num_declarations = draw->machine.NumDeclarations;
- vs->shader.instructions = (uintptr_t) draw->machine.Instructions;
- vs->shader.num_instructions = draw->machine.NumInstructions;
- vs->shader.uniforms = (uintptr_t) draw->user.constants;
- vs->shader.immediates = (uintptr_t) draw->machine.Imms;
- vs->shader.num_immediates = draw->machine.ImmLimit / 4;
vs->nr_attrs = draw->vertex_fetch.nr_attrs;
(void) memcpy(vs->plane, draw->plane, sizeof(draw->plane));
@@ -121,12 +122,12 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
for (j = 0; j < n; j++) {
vs->elts[j] = draw->vs.queue[i + j].elt;
- vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].dest;
+ vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].vertex;
}
for (/* empty */; j < SPU_VERTS_PER_BATCH; j++) {
vs->elts[j] = vs->elts[0];
- vs->vOut[j] = vs->vOut[0];
+ vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].vertex;
}
vs->num_elts = n;
@@ -135,5 +136,6 @@ cell_vertex_shader_queue_flush(struct draw_context *draw)
cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT);
}
+ draw->vs.post_nr = draw->vs.queue_nr;
draw->vs.queue_nr = 0;
}
diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile
index 30ef2450ec..c071de1900 100644
--- a/src/gallium/drivers/cell/spu/Makefile
+++ b/src/gallium/drivers/cell/spu/Makefile
@@ -18,6 +18,7 @@ PROG_SPU_EMBED_O = $(PROG)_spu-embed.o
SOURCES = \
spu_main.c \
spu_blend.c \
+ spu_dcache.c \
spu_render.c \
spu_texture.c \
spu_tile.c \
diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c
new file mode 100644
index 0000000000..a1701d80d1
--- /dev/null
+++ b/src/gallium/drivers/cell/spu/spu_dcache.c
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright IBM Corporation 2008
+ * 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
+ * on 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
+ * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "cell/common.h"
+#include "spu_main.h"
+#include "spu_dcache.h"
+
+#define CACHELINE_LOG2SIZE 7
+#define LINE_SIZE (1U << 7)
+#define ALIGN_MASK (~(LINE_SIZE - 1))
+
+#define CACHE_NAME data
+#define CACHED_TYPE qword
+#define CACHE_TYPE CACHE_TYPE_RO
+#define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0)
+#define CACHE_LOG2NNWAY 2
+#define CACHE_LOG2NSETS 6
+#include <cache-api.h>
+
+/* Yes folks, this is ugly.
+ */
+#undef CACHE_NWAY
+#undef CACHE_NSETS
+#define CACHE_NAME data
+#define CACHE_NWAY 4
+#define CACHE_NSETS (1U << 6)
+
+
+/**
+ * Fetch between arbitrary number of bytes from an unaligned address
+ *
+ * \param dst Destination data buffer
+ * \param ea Main memory effective address of source data
+ * \param size Number of bytes to read
+ *
+ * \warning
+ * As is hinted by the type of the \c dst pointer, this function writes
+ * multiples of 16-bytes.
+ */
+void
+spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size)
+{
+ const int shift = ea & 0x0f;
+ const unsigned read_size = ROUNDUP16(size + shift);
+ const unsigned last_read = ROUNDUP16(ea + size);
+ const qword *const last_write = dst + (ROUNDUP16(size) / 16);
+ unsigned i;
+
+
+ if (shift == 0) {
+ /* Data is already aligned. Fetch directly into the destination buffer.
+ */
+ for (i = 0; i < size; i += 16) {
+ *(dst++) = cache_rd(data, ea + i);
+ }
+ } else {
+ qword hi;
+
+
+ /* Please exercise extreme caution when modifying this code. This code
+ * must not read past the end of the page containing the source data,
+ * and it must not write more than ((size + 15) / 16) qwords to the
+ * destination buffer.
+ */
+ ea &= ~0x0f;
+ hi = cache_rd(data, ea);
+ for (i = 16; i < read_size; i += 16) {
+ qword lo = cache_rd(data, ea + i);
+
+ *(dst++) = si_or((qword) spu_slqwbyte(hi, shift),
+ (qword) spu_rlmaskqwbyte(lo, shift - 16));
+ hi = lo;
+ }
+
+ if (dst != last_write) {
+ *(dst++) = si_or((qword) spu_slqwbyte(hi, shift), si_il(0));
+ }
+ }
+
+ ASSERT((ea + i) == last_read);
+ ASSERT(dst == last_write);
+}
+
+
+/**
+ * Notify the cache that a range of main memory may have been modified
+ */
+void
+spu_dcache_mark_dirty(unsigned ea, unsigned size)
+{
+ unsigned i;
+ const unsigned aligned_start = (ea & ALIGN_MASK);
+ const unsigned aligned_end = (ea + size + (LINE_SIZE - 1))
+ & ALIGN_MASK;
+
+
+ for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) {
+ const unsigned entry = __cache_dir[i];
+ const unsigned addr = entry & ~0x0f;
+
+ __cache_dir[i] = ((addr >= aligned_start) && (addr < aligned_end))
+ ? (entry & ~CACHELINE_VALID) : entry;
+ }
+}
diff --git a/src/gallium/drivers/cell/spu/spu_dcache.h b/src/gallium/drivers/cell/spu/spu_dcache.h
new file mode 100644
index 0000000000..7a06b8c25a
--- /dev/null
+++ b/src/gallium/drivers/cell/spu/spu_dcache.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright IBM Corporation 2008
+ * 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
+ * on 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
+ * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR 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 SPU_DCACHE_H
+#define SPU_DCACHE_H
+
+extern void
+spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size);
+
+extern void
+spu_dcache_mark_dirty(unsigned ea, unsigned size);
+
+#endif /* SPU_DCACHE_H */
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index 109540b1f7..1560c0f157 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -50,8 +50,6 @@
* Brian Paul
*/
-#include <libmisc.h>
-#include <spu_mfcio.h>
#include <transpose_matrix4x4.h>
#include <simdmath/ceilf4.h>
#include <simdmath/cosf4.h>
@@ -72,6 +70,8 @@
#include "spu_exec.h"
#include "spu_main.h"
#include "spu_vertex_shader.h"
+#include "spu_dcache.h"
+#include "cell/common.h"
#define TILE_TOP_LEFT 0
#define TILE_TOP_RIGHT 1
@@ -146,17 +146,14 @@ spu_exec_machine_init(struct spu_exec_machine *mach,
struct spu_sampler *samplers,
unsigned processor)
{
- qword zero;
- qword not_zero;
- uint i;
+ const qword zero = si_il(0);
+ const qword not_zero = si_il(~0);
+ (void) numSamplers;
mach->Samplers = samplers;
mach->Processor = processor;
mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS];
- zero = si_xor(zero, zero);
- not_zero = si_xori(zero, 0xff);
-
/* Setup constants. */
mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q = zero;
mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].q = not_zero;
@@ -356,19 +353,17 @@ fetch_src_file_channel(
case TGSI_EXTSWIZZLE_W:
switch( file ) {
case TGSI_FILE_CONSTANT: {
- unsigned char buffer[32] ALIGN16_ATTRIB;
unsigned i;
for (i = 0; i < 4; i++) {
const float *ptr = mach->Consts[index->i[i]];
- const uint64_t addr = (uint64_t)(uintptr_t) ptr;
- const unsigned size = ((addr & 0x0f) == 0) ? 16 : 32;
+ float tmp[4];
- mfc_get(buffer, addr & ~0x0f, size, TAG_VERTEX_BUFFER, 0, 0);
- wait_on_mask(1 << TAG_VERTEX_BUFFER);
+ spu_dcache_fetch_unaligned((qword *) tmp,
+ (uintptr_t)(ptr + swizzle),
+ sizeof(float));
- (void) memcpy(& chan->f[i], &buffer[(addr & 0x0f)
- + (sizeof(float) * swizzle)], sizeof(float));
+ chan->f[i] = tmp[0];
}
break;
}
@@ -663,9 +658,10 @@ fetch_texel( struct spu_sampler *sampler,
qword rgba[4];
qword out[4];
- sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, (float *) rgba);
+ sampler->get_samples(sampler, s->f, t->f, p->f, lodbias,
+ (float (*)[4]) rgba);
- _transpose_matrix4x4(out, rgba);
+ _transpose_matrix4x4((vec_float4 *) out, (vec_float4 *) rgba);
r->q = out[0];
g->q = out[1];
b->q = out[2];
@@ -1903,32 +1899,28 @@ spu_exec_machine_run( struct spu_exec_machine *mach )
/* execute declarations (interpolants) */
if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) {
for (i = 0; i < mach->NumDeclarations; i++) {
- uint8_t buffer[sizeof(struct tgsi_full_declaration) + 32] ALIGN16_ATTRIB;
- struct tgsi_full_declaration decl;
- unsigned long decl_addr = (unsigned long) (mach->Declarations+i);
- unsigned size = ((sizeof(decl) + (decl_addr & 0x0f) + 0x0f) & ~0x0f);
+ union {
+ struct tgsi_full_declaration decl;
+ qword buffer[ROUNDUP16(sizeof(struct tgsi_full_declaration)) / 16];
+ } d ALIGN16_ATTRIB;
+ unsigned ea = (unsigned) (mach->Declarations + pc);
- mfc_get(buffer, decl_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0);
- wait_on_mask(1 << TAG_INSTRUCTION_FETCH);
+ spu_dcache_fetch_unaligned(d.buffer, ea, sizeof(d.decl));
- memcpy(& decl, buffer + (decl_addr & 0x0f), sizeof(decl));
- exec_declaration( mach, &decl );
+ exec_declaration( mach, &d.decl );
}
}
/* execute instructions, until pc is set to -1 */
while (pc != -1) {
- uint8_t buffer[sizeof(struct tgsi_full_instruction) + 32] ALIGN16_ATTRIB;
- struct tgsi_full_instruction inst;
- unsigned long inst_addr = (unsigned long) (mach->Instructions + pc);
- unsigned size = ((sizeof(inst) + (inst_addr & 0x0f) + 0x0f) & ~0x0f);
-
- assert(pc < mach->NumInstructions);
- mfc_get(buffer, inst_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0);
- wait_on_mask(1 << TAG_INSTRUCTION_FETCH);
-
- memcpy(& inst, buffer + (inst_addr & 0x0f), sizeof(inst));
- exec_instruction( mach, & inst, &pc );
+ union {
+ struct tgsi_full_instruction inst;
+ qword buffer[ROUNDUP16(sizeof(struct tgsi_full_instruction)) / 16];
+ } i ALIGN16_ATTRIB;
+ unsigned ea = (unsigned) (mach->Instructions + pc);
+
+ spu_dcache_fetch_unaligned(i.buffer, ea, sizeof(i.inst));
+ exec_instruction( mach, & i.inst, &pc );
}
#if 0
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index fcbf0f841e..59300028d4 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -38,6 +38,7 @@
#include "spu_tile.h"
//#include "spu_test.h"
#include "spu_vertex_shader.h"
+#include "spu_dcache.h"
#include "cell/common.h"
#include "pipe/p_defines.h"
@@ -285,6 +286,8 @@ cmd_state_texture(const struct cell_command_texture *texture)
{ spu.texture.width, spu.texture.height, 0.0, 0.0};
spu.tex_size_mask = (vector unsigned int)
{ spu.texture.width - 1, spu.texture.height - 1, 0, 0 };
+ spu.tex_size_x_mask = spu_splats(spu.texture.width - 1);
+ spu.tex_size_y_mask = spu_splats(spu.texture.height - 1);
}
@@ -433,10 +436,19 @@ cmd_batch(uint opcode)
sizeof(struct pipe_viewport_state));
pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8);
break;
+ case CELL_CMD_STATE_UNIFORMS:
+ draw.constants = (const float (*)[4]) (uintptr_t) buffer[pos + 1];
+ pos += 2;
+ break;
case CELL_CMD_STATE_VS_ARRAY_INFO:
cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]);
pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
break;
+ case CELL_CMD_STATE_BIND_VS:
+ spu_bind_vertex_shader(&draw,
+ (struct cell_shader_info *) &buffer[pos+1]);
+ pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
+ break;
case CELL_CMD_STATE_ATTRIB_FETCH: {
struct cell_attribute_fetch_code *code =
(struct cell_attribute_fetch_code *) &buffer[pos+1];
@@ -453,6 +465,14 @@ cmd_batch(uint opcode)
pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
break;
}
+ case CELL_CMD_FLUSH_BUFFER_RANGE: {
+ struct cell_buffer_range *br = (struct cell_buffer_range *)
+ &buffer[pos+1];
+
+ spu_dcache_mark_dirty((unsigned) br->base, br->size);
+ pos += (1 + ROUNDUP8(sizeof(struct cell_buffer_range)) / 8);
+ break;
+ }
default:
printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]);
ASSERT(0);
@@ -566,7 +586,7 @@ main(main_param_t speid, main_param_t argp)
one_time_init();
if (Debug)
- printf("SPU: main() speid=%lu\n", speid);
+ printf("SPU: main() speid=%lu\n", (unsigned long) speid);
mfc_get(&spu.init, /* dest */
(unsigned int) argp, /* src */
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index 5c95d112ac..a13edd1702 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -107,6 +107,8 @@ struct spu_global
vector float tex_size;
vector unsigned int tex_size_mask; /**< == int(size - 1) */
+ vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
+ vector unsigned int tex_size_y_mask; /**< == int(size - 1) */
vector float (*sample_texture)(vector float texcoord);
@@ -130,8 +132,10 @@ extern boolean Debug;
#define TAG_INDEX_BUFFER 16
#define TAG_BATCH_BUFFER 17
#define TAG_MISC 18
-#define TAG_TEXTURE_TILE 19
-#define TAG_INSTRUCTION_FETCH 20
+#define TAG_DCACHE0 20
+#define TAG_DCACHE1 21
+#define TAG_DCACHE2 22
+#define TAG_DCACHE3 23
diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c
index 3962aaa4a9..67eb08196a 100644
--- a/src/gallium/drivers/cell/spu/spu_texture.c
+++ b/src/gallium/drivers/cell/spu/spu_texture.c
@@ -31,19 +31,7 @@
#include "spu_texture.h"
#include "spu_tile.h"
#include "spu_colorpack.h"
-
-
-/**
- * Number of texture tiles to cache.
- * Note that this will probably be the largest consumer of SPU local store/
- * memory for this driver!
- */
-#define CACHE_SIZE 16
-
-static tile_t tex_tiles[CACHE_SIZE] ALIGN16_ATTRIB;
-
-static vector unsigned int tex_tile_xy[CACHE_SIZE];
-
+#include "spu_dcache.h"
/**
@@ -52,78 +40,60 @@ static vector unsigned int tex_tile_xy[CACHE_SIZE];
void
invalidate_tex_cache(void)
{
- /* XXX memset? */
- uint i;
- for (i = 0; i < CACHE_SIZE; i++) {
- tex_tile_xy[i] = ((vector unsigned int) { ~0U, ~0U, ~0U, ~0U });
- }
+ spu_dcache_mark_dirty((unsigned) spu.texture.start,
+ 4 * spu.texture.width * spu.texture.height);
}
-/**
- * Return the cache pos/index which corresponds to tile (tx,ty)
- */
-static INLINE uint
-cache_pos(vector unsigned int txty)
+static uint
+get_texel(vec_uint4 coordinate)
{
- uint pos = (spu_extract(txty,0) + spu_extract(txty,1) * 4) % CACHE_SIZE;
- return pos;
+ vec_uint4 tmp;
+ unsigned x = spu_extract(coordinate, 0);
+ unsigned y = spu_extract(coordinate, 1);
+ const unsigned tiles_per_row = spu.texture.width / TILE_SIZE;
+ unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row)
+ + (x / TILE_SIZE));
+ unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE)
+ + (x % TILE_SIZE));
+
+ spu_dcache_fetch_unaligned((qword *) & tmp,
+ spu.texture.start + tile_offset + texel_offset,
+ 4);
+ return spu_extract(tmp, 0);
}
-/**
- * Make sure the tile for texel (i,j) is present, return its position/index
- * in the cache.
- */
-static uint
-get_tex_tile(vector unsigned int ij)
+static void
+get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
{
- /* tile address: tx,ty */
- const vector unsigned int txty = spu_rlmask(ij, -5); /* divide by 32 */
- const uint pos = cache_pos(txty);
-
- if ((spu_extract(tex_tile_xy[pos], 0) != spu_extract(txty, 0)) ||
- (spu_extract(tex_tile_xy[pos], 1) != spu_extract(txty, 1))) {
-
- /* texture cache miss, fetch tile from main memory */
- const uint tiles_per_row = spu.texture.width / TILE_SIZE;
- const uint bytes_per_tile = sizeof(tile_t);
- const void *src = (const ubyte *) spu.texture.start
- + (spu_extract(txty,1) * tiles_per_row + spu_extract(txty,0)) * bytes_per_tile;
-
- printf("SPU %u: tex cache miss at %d, %d pos=%u old=%d,%d\n",
- spu.init.id,
- spu_extract(txty,0),
- spu_extract(txty,1),
- pos,
- spu_extract(tex_tile_xy[pos],0),
- spu_extract(tex_tile_xy[pos],1));
-
- ASSERT_ALIGN16(tex_tiles[pos].ui);
- ASSERT_ALIGN16(src);
-
- mfc_get(tex_tiles[pos].ui, /* dest */
- (unsigned int) src,
- bytes_per_tile, /* size */
- TAG_TEXTURE_TILE,
- 0, /* tid */
- 0 /* rid */);
-
- wait_on_mask(1 << TAG_TEXTURE_TILE);
-
- tex_tile_xy[pos] = txty;
- }
- else {
-#if 0
- printf("SPU %u: tex cache HIT at %d, %d\n",
- spu.init.id, tx, ty);
-#endif
- }
-
- return pos;
+ const unsigned texture_ea = (uintptr_t) spu.texture.start;
+ vec_uint4 tile_x = spu_rlmask(x, -5);
+ vec_uint4 tile_y = spu_rlmask(y, -5);
+ const qword offset_x = si_andi((qword) x, 0x1f);
+ const qword offset_y = si_andi((qword) y, 0x1f);
+
+ const qword tiles_per_row = (qword) spu_splats(spu.texture.width / TILE_SIZE);
+ const qword tile_size = (qword) spu_splats(sizeof(tile_t));
+
+ qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x);
+ tile_offset = si_mpy((qword) tile_offset, tile_size);
+
+ qword texel_offset = si_a(si_mpyui(offset_y, 32), offset_x);
+ texel_offset = si_mpyui(texel_offset, 4);
+
+ vec_uint4 offset = (vec_uint4) si_a(tile_offset, texel_offset);
+
+ spu_dcache_fetch_unaligned((qword *) & texels[0],
+ texture_ea + spu_extract(offset, 0), 4);
+ spu_dcache_fetch_unaligned((qword *) & texels[1],
+ texture_ea + spu_extract(offset, 1), 4);
+ spu_dcache_fetch_unaligned((qword *) & texels[2],
+ texture_ea + spu_extract(offset, 2), 4);
+ spu_dcache_fetch_unaligned((qword *) & texels[3],
+ texture_ea + spu_extract(offset, 3), 4);
}
-
/**
* Get texture sample at texcoord.
* XXX this is extremely primitive for now.
@@ -134,9 +104,7 @@ sample_texture_nearest(vector float texcoord)
vector float tc = spu_mul(texcoord, spu.tex_size);
vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */
itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */
- vector unsigned int ij = spu_and(itc, TILE_SIZE-1); /* intra tile addr */
- uint pos = get_tex_tile(itc);
- uint texel = tex_tiles[pos].ui[spu_extract(ij, 1)][spu_extract(ij, 0)];
+ uint texel = get_texel(itc);
return spu_unpack_A8R8G8B8(texel);
}
@@ -144,49 +112,33 @@ sample_texture_nearest(vector float texcoord)
vector float
sample_texture_bilinear(vector float texcoord)
{
- static const vector unsigned int offset10 = {1, 0, 0, 0};
- static const vector unsigned int offset01 = {0, 1, 0, 0};
+ static const vec_uint4 offset_x = {0, 0, 1, 1};
+ static const vec_uint4 offset_y = {0, 1, 0, 1};
vector float tc = spu_mul(texcoord, spu.tex_size);
tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */
/* integer texcoords S,T: */
- vector unsigned int itc00 = spu_convtu(tc, 0); /* convert to int */
- vector unsigned int itc01 = spu_add(itc00, offset01);
- vector unsigned int itc10 = spu_add(itc00, offset10);
- vector unsigned int itc11 = spu_add(itc10, offset01);
-
- /* mask (GL_REPEAT) */
- itc00 = spu_and(itc00, spu.tex_size_mask);
- itc01 = spu_and(itc01, spu.tex_size_mask);
- itc10 = spu_and(itc10, spu.tex_size_mask);
- itc11 = spu_and(itc11, spu.tex_size_mask);
-
- /* intra tile addr */
- vector unsigned int ij00 = spu_and(itc00, TILE_SIZE-1);
- vector unsigned int ij01 = spu_and(itc01, TILE_SIZE-1);
- vector unsigned int ij10 = spu_and(itc10, TILE_SIZE-1);
- vector unsigned int ij11 = spu_and(itc11, TILE_SIZE-1);
-
- /* get tile cache positions */
- uint pos00 = get_tex_tile(itc00);
- uint pos01, pos10, pos11;
- if ((spu_extract(ij00, 0) < TILE_SIZE-1) &&
- (spu_extract(ij00, 1) < TILE_SIZE-1)) {
- /* all texels are in the same tile */
- pos01 = pos10 = pos11 = pos00;
- }
- else {
- pos01 = get_tex_tile(itc01);
- pos10 = get_tex_tile(itc10);
- pos11 = get_tex_tile(itc11);
- }
-
- /* get texels from tiles and convert to float[4] */
- vector float texel00 = spu_unpack_A8R8G8B8(tex_tiles[pos00].ui[spu_extract(ij00, 1)][spu_extract(ij00, 0)]);
- vector float texel01 = spu_unpack_A8R8G8B8(tex_tiles[pos01].ui[spu_extract(ij01, 1)][spu_extract(ij01, 0)]);
- vector float texel10 = spu_unpack_A8R8G8B8(tex_tiles[pos10].ui[spu_extract(ij10, 1)][spu_extract(ij10, 0)]);
- vector float texel11 = spu_unpack_A8R8G8B8(tex_tiles[pos11].ui[spu_extract(ij11, 1)][spu_extract(ij11, 0)]);
+ vec_uint4 itc = spu_convtu(tc, 0); /* convert to int */
+
+ vec_uint4 texels[4];
+
+ vec_uint4 x = spu_splats(spu_extract(itc, 0));
+ vec_uint4 y = spu_splats(spu_extract(itc, 1));
+
+ x = spu_add(x, offset_x);
+ y = spu_add(y, offset_y);
+
+ x = spu_and(x, spu.tex_size_x_mask);
+ y = spu_and(y, spu.tex_size_y_mask);
+
+ get_four_texels(x, y, texels);
+
+ vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0));
+ vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0));
+ vector float texel10 = spu_unpack_A8R8G8B8(spu_extract(texels[2], 0));
+ vector float texel11 = spu_unpack_A8R8G8B8(spu_extract(texels[3], 0));
+
/* Compute weighting factors in [0,1]
* Multiply texcoord by 1024, AND with 1023, convert back to float.
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c
index 55c6c28717..219fd90cc0 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c
+++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c
@@ -32,39 +32,19 @@
* Ian Romanick <idr@us.ibm.com>
*/
-#include <spu_mfcio.h>
-
#include "pipe/p_util.h"
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
#include "spu_exec.h"
#include "spu_vertex_shader.h"
#include "spu_main.h"
-
-#define CACHE_NAME attribute
-#define CACHED_TYPE qword
-#define CACHE_TYPE CACHE_TYPE_RO
-#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER
-#define CACHE_LOG2NNWAY 2
-#define CACHE_LOG2NSETS 6
-#include <cache-api.h>
-
-/* Yes folks, this is ugly.
- */
-#undef CACHE_NWAY
-#undef CACHE_NSETS
-#define CACHE_NAME attribute
-#define CACHE_NWAY 4
-#define CACHE_NSETS (1U << 6)
-
-
-#define DRAW_DBG 0
+#include "spu_dcache.h"
typedef void (*spu_fetch_func)(qword *out, const qword *in,
const qword *shuffle_data);
-static const qword fetch_shuffle_data[] = {
+static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = {
/* Shuffle used by CVT_64_FLOAT
*/
{
@@ -103,44 +83,6 @@ static const qword fetch_shuffle_data[] = {
/**
- * Fetch between 1 and 32 bytes from an unaligned address
- */
-static INLINE void
-fetch_unaligned(qword *dst, unsigned ea, unsigned size)
-{
- qword tmp[4];
- const int shift = ea & 0x0f;
- const unsigned aligned_start_ea = ea & ~0x0f;
- const unsigned aligned_end_ea = (ea + size) & ~0x0f;
- const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1;
- unsigned i;
-
-
- if (shift == 0) {
- /* Data is already aligned. Fetch directly into the destination buffer.
- */
- for (i = 0; i < num_entries; i++) {
- dst[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16));
- }
- } else {
- /* Fetch data from the cache to the local buffer.
- */
- for (i = 0; i < num_entries; i++) {
- tmp[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16));
- }
-
-
- /* Fix the alignment of the data and write to the destination buffer.
- */
- for (i = 0; i < ((size + 15) / 16); i++) {
- dst[i] = si_or((qword) spu_slqwbyte(tmp[i], shift),
- (qword) spu_rlmaskqwbyte(tmp[i + 1], shift - 16));
- }
- }
-}
-
-
-/**
* Fetch vertex attributes for 'count' vertices.
*/
static void generic_vertex_fetch(struct spu_vs_context *draw,
@@ -169,7 +111,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
unsigned idx;
const unsigned bytes_per_entry = draw->vertex_fetch.size[attr];
const unsigned quads_per_entry = (bytes_per_entry + 15) / 16;
- qword in[2 * 4];
+ qword in[2 * 4] ALIGN16_ATTRIB;
/* Fetch four attributes for four vertices.
@@ -182,7 +124,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
printf("SPU: fetching = 0x%llx\n", addr);
#endif
- fetch_unaligned(& in[idx], addr, bytes_per_entry);
+ spu_dcache_fetch_unaligned(& in[idx], addr, bytes_per_entry);
idx += quads_per_entry;
}
@@ -200,15 +142,5 @@ static void generic_vertex_fetch(struct spu_vs_context *draw,
void spu_update_vertex_fetch( struct spu_vs_context *draw )
{
- unsigned i;
-
-
- /* Invalidate the vertex cache.
- */
- for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) {
- CACHELINE_CLEARVALID(i);
- }
-
-
draw->vertex_fetch.fetch_func = generic_vertex_fetch;
}
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
index 3f5bf41aa2..8363efeeb6 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c
+++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c
@@ -165,63 +165,55 @@ run_vertex_program(struct spu_vs_context *draw,
}
-static void
-spu_bind_vertex_shader(struct spu_vs_context *draw,
- void *uniforms,
- void *planes,
- unsigned nr_planes,
- unsigned num_outputs
- )
-{
- draw->constants = (float (*)[4]) uniforms;
-
- (void) memcpy(draw->plane, planes, sizeof(float) * 4 * nr_planes);
- draw->nr_planes = nr_planes;
- draw->num_vs_outputs = num_outputs;
-
- /* specify the shader to interpret/execute */
- spu_exec_machine_init(&draw->machine,
- PIPE_MAX_SAMPLERS,
- NULL /*samplers*/,
- PIPE_SHADER_VERTEX);
-}
-
-
unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32]
ALIGN16_ATTRIB;
+
void
-spu_execute_vertex_shader(struct spu_vs_context *draw,
- const struct cell_command_vs *vs)
+spu_bind_vertex_shader(struct spu_vs_context *draw,
+ struct cell_shader_info *vs)
{
- unsigned i;
-
- const uint64_t immediate_addr = vs->shader.immediates;
+ const unsigned immediate_addr = vs->immediates;
const unsigned immediate_size =
- ROUNDUP16((sizeof(float) * 4 * vs->shader.num_immediates)
- + (immediate_addr & 0x0f));
+ ROUNDUP16((sizeof(float) * 4 * vs->num_immediates)
+ + (immediate_addr & 0x0f));
+
mfc_get(immediates, immediate_addr & ~0x0f, immediate_size,
TAG_VERTEX_BUFFER, 0, 0);
draw->machine.Instructions = (struct tgsi_full_instruction *)
- vs->shader.instructions;
- draw->machine.NumInstructions = vs->shader.num_instructions;
+ vs->instructions;
+ draw->machine.NumInstructions = vs->num_instructions;
draw->machine.Declarations = (struct tgsi_full_declaration *)
- vs->shader.declarations;
- draw->machine.NumDeclarations = vs->shader.num_declarations;
+ vs->declarations;
+ draw->machine.NumDeclarations = vs->num_declarations;
- draw->vertex_fetch.nr_attrs = vs->nr_attrs;
+ draw->num_vs_outputs = vs->num_outputs;
+
+ /* specify the shader to interpret/execute */
+ spu_exec_machine_init(&draw->machine,
+ PIPE_MAX_SAMPLERS,
+ NULL /*samplers*/,
+ PIPE_SHADER_VERTEX);
wait_on_mask(1 << TAG_VERTEX_BUFFER);
(void) memcpy(& draw->machine.Imms, &immediates[immediate_addr & 0x0f],
- sizeof(float) * 4 * vs->shader.num_immediates);
+ sizeof(float) * 4 * vs->num_immediates);
+}
- spu_bind_vertex_shader(draw, vs->shader.uniforms,
- vs->plane, vs->nr_planes,
- vs->shader.num_outputs);
+
+void
+spu_execute_vertex_shader(struct spu_vs_context *draw,
+ const struct cell_command_vs *vs)
+{
+ unsigned i;
+
+ (void) memcpy(draw->plane, vs->plane, sizeof(float) * 4 * vs->nr_planes);
+ draw->nr_planes = vs->nr_planes;
+ draw->vertex_fetch.nr_attrs = vs->nr_attrs;
for (i = 0; i < vs->num_elts; i += 4) {
const unsigned batch_size = MIN2(vs->num_elts - i, 4);
diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h
index 0fb0bc28d0..54a4b8d9b9 100644
--- a/src/gallium/drivers/cell/spu/spu_vertex_shader.h
+++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h
@@ -1,6 +1,7 @@
#ifndef SPU_VERTEX_SHADER_H
#define SPU_VERTEX_SHADER_H
+#include "cell/common.h"
#include "pipe/p_format.h"
#include "spu_exec.h"
@@ -55,6 +56,10 @@ static INLINE void spu_vertex_fetch(struct spu_vs_context *draw,
struct cell_command_vs;
extern void
+spu_bind_vertex_shader(struct spu_vs_context *draw,
+ struct cell_shader_info *vs);
+
+extern void
spu_execute_vertex_shader(struct spu_vs_context *draw,
const struct cell_command_vs *vs);
diff --git a/src/gallium/drivers/failover/Makefile b/src/gallium/drivers/failover/Makefile
index 14389bd055..f08b8df07a 100644
--- a/src/gallium/drivers/failover/Makefile
+++ b/src/gallium/drivers/failover/Makefile
@@ -1,20 +1,13 @@
-
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = failover
-DRIVER_SOURCES = \
+C_SOURCES = \
fo_state.c \
fo_state_emit.c \
fo_context.c
-C_SOURCES = \
- $(COMMON_SOURCES) \
- $(DRIVER_SOURCES)
-
-ASM_SOURCES =
-
include ../../Makefile.template
symlinks:
diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript
new file mode 100644
index 0000000000..f8e9b1b491
--- /dev/null
+++ b/src/gallium/drivers/failover/SConscript
@@ -0,0 +1,13 @@
+Import('*')
+
+env = env.Clone()
+
+failover = env.ConvenienceLibrary(
+ target = 'failover',
+ source = [
+ 'fo_state.c',
+ 'fo_state_emit.c',
+ 'fo_context.c',
+ ])
+
+Export('failover')
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 7ce4a7df17..afc0d7eb1e 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -117,12 +117,15 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->hw = hw;
failover->sw = sw;
failover->pipe.winsys = hw->winsys;
+ failover->pipe.screen = hw->screen;
failover->pipe.destroy = failover_destroy;
+#if 0
failover->pipe.is_format_supported = hw->is_format_supported;
failover->pipe.get_name = hw->get_name;
failover->pipe.get_vendor = hw->get_vendor;
failover->pipe.get_param = hw->get_param;
failover->pipe.get_paramf = hw->get_paramf;
+#endif
failover->pipe.draw_arrays = failover_draw_arrays;
failover->pipe.draw_elements = failover_draw_elements;
@@ -137,15 +140,16 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover_init_state_functions( failover );
-#if 0
- failover->pipe.surface_alloc = hw->surface_alloc;
-#endif
- failover->pipe.get_tex_surface = hw->get_tex_surface;
-
failover->pipe.surface_copy = hw->surface_copy;
failover->pipe.surface_fill = hw->surface_fill;
+
+#if 0
failover->pipe.texture_create = hw->texture_create;
failover->pipe.texture_release = hw->texture_release;
+ failover->pipe.get_tex_surface = hw->get_tex_surface;
+#endif
+ failover->pipe.texture_update = hw->texture_update;
+
failover->pipe.flush = hw->flush;
failover->dirty = 0;
diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile
index ee22ba86f9..41a61a0020 100644
--- a/src/gallium/drivers/i915simple/Makefile
+++ b/src/gallium/drivers/i915simple/Makefile
@@ -1,10 +1,9 @@
-
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = i915simple
-DRIVER_SOURCES = \
+C_SOURCES = \
i915_blit.c \
i915_clear.c \
i915_flush.c \
@@ -18,7 +17,7 @@ DRIVER_SOURCES = \
i915_state_derived.c \
i915_state_emit.c \
i915_state_sampler.c \
- i915_strings.c \
+ i915_screen.c \
i915_prim_emit.c \
i915_prim_vbuf.c \
i915_texture.c \
@@ -26,12 +25,6 @@ DRIVER_SOURCES = \
i915_fpc_translate.c \
i915_surface.c
-C_SOURCES = \
- $(COMMON_SOURCES) \
- $(DRIVER_SOURCES)
-
-ASM_SOURCES =
-
include ../../Makefile.template
symlinks:
diff --git a/src/gallium/drivers/i915simple/SConscript b/src/gallium/drivers/i915simple/SConscript
index f5fb96b995..2366e1247f 100644
--- a/src/gallium/drivers/i915simple/SConscript
+++ b/src/gallium/drivers/i915simple/SConscript
@@ -15,13 +15,13 @@ i915simple = env.ConvenienceLibrary(
'i915_fpc_translate.c',
'i915_prim_emit.c',
'i915_prim_vbuf.c',
+ 'i915_screen.c',
'i915_state.c',
'i915_state_derived.c',
'i915_state_dynamic.c',
'i915_state_emit.c',
'i915_state_immediate.c',
'i915_state_sampler.c',
- 'i915_strings.c',
'i915_surface.c',
'i915_texture.c',
])
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index 7f71f8fd4f..15ff2360b7 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -36,120 +36,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
-
-
-/**
- * Query format support for creating a texture, drawing surface, etc.
- * \param format the format to test
- * \param type one of PIPE_TEXTURE, PIPE_SURFACE
- */
-static boolean
-i915_is_format_supported( struct pipe_context *pipe,
- enum pipe_format format, uint type )
-{
- static const enum pipe_format tex_supported[] = {
- PIPE_FORMAT_R8G8B8A8_UNORM,
- PIPE_FORMAT_A8R8G8B8_UNORM,
- PIPE_FORMAT_R5G6B5_UNORM,
- PIPE_FORMAT_U_L8,
- PIPE_FORMAT_U_A8,
- PIPE_FORMAT_U_I8,
- PIPE_FORMAT_U_A8_L8,
- PIPE_FORMAT_YCBCR,
- PIPE_FORMAT_YCBCR_REV,
- PIPE_FORMAT_S8Z24_UNORM,
- PIPE_FORMAT_NONE /* list terminator */
- };
- static const enum pipe_format surface_supported[] = {
- PIPE_FORMAT_A8R8G8B8_UNORM,
- PIPE_FORMAT_R5G6B5_UNORM,
- PIPE_FORMAT_S8Z24_UNORM,
- /*PIPE_FORMAT_R16G16B16A16_SNORM,*/
- PIPE_FORMAT_NONE /* list terminator */
- };
- const enum pipe_format *list;
- uint i;
-
- switch (type) {
- case PIPE_TEXTURE:
- list = tex_supported;
- break;
- case PIPE_SURFACE:
- list = surface_supported;
- break;
- default:
- assert(0);
- }
-
- for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) {
- if (list[i] == format)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static int
-i915_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
- case PIPE_CAP_NPOT_TEXTURES:
- return 1;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 0;
- case PIPE_CAP_POINT_SPRITE:
- return 0;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 1;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 0;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
- default:
- return 0;
- }
-}
-
-
-static float
-i915_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 7.5;
-
- case PIPE_CAP_MAX_POINT_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 255.0;
-
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 4.0;
-
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 16.0;
-
- default:
- return 0;
- }
-}
+#include "pipe/p_screen.h"
static void i915_destroy( struct pipe_context *pipe )
@@ -162,8 +49,6 @@ static void i915_destroy( struct pipe_context *pipe )
}
-
-
static boolean
i915_draw_elements( struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
@@ -234,33 +119,11 @@ static boolean i915_draw_arrays( struct pipe_context *pipe,
-struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys,
- struct i915_winsys *i915_winsys,
- unsigned pci_id )
+struct pipe_context *i915_create_context( struct pipe_screen *screen,
+ struct pipe_winsys *pipe_winsys,
+ struct i915_winsys *i915_winsys )
{
struct i915_context *i915;
- unsigned is_i945 = 0;
-
- switch (pci_id) {
- case PCI_CHIP_I915_G:
- case PCI_CHIP_I915_GM:
- break;
-
- case PCI_CHIP_I945_G:
- case PCI_CHIP_I945_GM:
- case PCI_CHIP_I945_GME:
- case PCI_CHIP_G33_G:
- case PCI_CHIP_Q33_G:
- case PCI_CHIP_Q35_G:
- is_i945 = 1;
- break;
-
- default:
- pipe_winsys->printf(pipe_winsys,
- "%s: unknown pci id 0x%x, cannot create context\n",
- __FUNCTION__, pci_id);
- return NULL;
- }
i915 = CALLOC_STRUCT(i915_context);
if (i915 == NULL)
@@ -268,11 +131,9 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys,
i915->winsys = i915_winsys;
i915->pipe.winsys = pipe_winsys;
+ i915->pipe.screen = screen;
i915->pipe.destroy = i915_destroy;
- i915->pipe.is_format_supported = i915_is_format_supported;
- i915->pipe.get_param = i915_get_param;
- i915->pipe.get_paramf = i915_get_paramf;
i915->pipe.clear = i915_clear;
@@ -295,13 +156,10 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys,
i915_init_surface_functions(i915);
i915_init_state_functions(i915);
i915_init_flush_functions(i915);
- i915_init_string_functions(i915);
-
- i915->pci_id = pci_id;
- i915->flags.is_i945 = is_i945;
+ i915_init_texture_functions(i915);
- i915->pipe.texture_create = i915_texture_create;
- i915->pipe.texture_release = i915_texture_release;
+ draw_install_aaline_stage(i915->draw, &i915->pipe);
+ draw_install_aapoint_stage(i915->draw, &i915->pipe);
i915->dirty = ~0;
i915->hardware_dirty = ~0;
@@ -310,11 +168,6 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys,
*/
i915->batch_start = NULL;
- /*
- * XXX we could plug GL selection/feedback into the drawing pipeline
- * by specifying a different setup/render stage.
- */
-
return &i915->pipe;
}
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index 2d876925b2..6401112f83 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -35,6 +35,8 @@
#include "draw/draw_vertex.h"
+#include "tgsi/util/tgsi_scan.h"
+
#define I915_TEX_UNITS 8
@@ -79,6 +81,43 @@
#define I915_MAX_CONSTANT 32
+/** See constant_flags[] below */
+#define I915_CONSTFLAG_USER 0x1f
+
+
+/**
+ * Subclass of pipe_shader_state
+ */
+struct i915_fragment_shader
+{
+ struct pipe_shader_state state;
+
+ struct tgsi_shader_info info;
+
+ uint *program;
+ uint program_len;
+
+ /**
+ * constants introduced during translation.
+ * These are placed at the end of the constant buffer and grow toward
+ * the beginning (eg: slot 31, 30 29, ...)
+ * User-provided constants start at 0.
+ * This allows both types of constants to co-exist (until there's too many)
+ * and doesn't require regenerating/changing the fragment program to
+ * shuffle constants around.
+ */
+ uint num_constants;
+ float constants[I915_MAX_CONSTANT][4];
+
+ /**
+ * Status of each constant
+ * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding
+ * slot of the user's constant buffer. (set by pipe->set_constant_buffer())
+ * Else, the bitmask indicates which components are occupied by immediates.
+ */
+ ubyte constant_flags[I915_MAX_CONSTANT];
+};
+
struct i915_cache_context;
@@ -93,11 +132,6 @@ struct i915_state
float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];
/** number of constants passed in through a constant buffer */
uint num_user_constants[PIPE_SHADER_TYPES];
- /** user constants, plus extra constants from shader translation */
- uint num_constants[PIPE_SHADER_TYPES];
-
- uint *program;
- uint program_len;
/* texture sampler state */
unsigned sampler[I915_TEX_UNITS][3];
@@ -187,7 +221,8 @@ struct i915_context
const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct i915_depth_stencil_state *depth_stencil;
const struct i915_rasterizer_state *rasterizer;
- const struct pipe_shader_state *fs;
+
+ struct i915_fragment_shader *fs;
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
@@ -210,11 +245,6 @@ struct i915_context
unsigned hardware_dirty;
unsigned debug;
- unsigned pci_id;
-
- struct {
- unsigned is_i945:1;
- } flags;
};
/* A flag for each state_tracker state object:
@@ -233,6 +263,7 @@ struct i915_context
#define I915_NEW_TEXTURE 0x800
#define I915_NEW_CONSTANTS 0x1000
#define I915_NEW_VBO 0x2000
+#define I915_NEW_VS 0x4000
/* Driver's internally generated state flags:
@@ -289,6 +320,7 @@ void i915_init_string_functions( struct i915_context *i915 );
+
/***********************************************************************
* Inline conversion functions. These are better-typed than the
* macros used previously:
diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c
index 94db44e1aa..78102dbac2 100644
--- a/src/gallium/drivers/i915simple/i915_debug.c
+++ b/src/gallium/drivers/i915simple/i915_debug.c
@@ -25,8 +25,6 @@
*
**************************************************************************/
-//#include "imports.h"
-
#include "i915_reg.h"
#include "i915_context.h"
#include "i915_winsys.h"
diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c
index 3c2069b827..96a54281f1 100644
--- a/src/gallium/drivers/i915simple/i915_flush.c
+++ b/src/gallium/drivers/i915simple/i915_flush.c
@@ -31,6 +31,7 @@
#include "pipe/p_defines.h"
+#include "draw/draw_context.h"
#include "i915_context.h"
#include "i915_reg.h"
#include "i915_batch.h"
@@ -44,6 +45,8 @@ static void i915_flush( struct pipe_context *pipe,
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
+
/* Do we need to emit an MI_FLUSH command to flush the hardware
* caches?
*/
diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h
index 8c7b68aefb..80a9576304 100644
--- a/src/gallium/drivers/i915simple/i915_fpc.h
+++ b/src/gallium/drivers/i915simple/i915_fpc.h
@@ -44,23 +44,19 @@
* Program translation state
*/
struct i915_fp_compile {
- const struct pipe_shader_state *shader;
+ struct i915_fragment_shader *shader; /* the shader we're compiling */
- struct vertex_info *vertex_info;
+ boolean used_constants[I915_MAX_CONSTANT];
- uint declarations[I915_PROGRAM_SIZE];
- uint program[I915_PROGRAM_SIZE];
+ /** maps TGSI immediate index to constant slot */
+ uint num_immediates;
+ uint immediates_map[I915_MAX_CONSTANT];
+ float immediates[I915_MAX_CONSTANT][4];
- uint input_semantic_name[PIPE_MAX_SHADER_INPUTS];
- uint input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+ boolean first_instruction;
- uint output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
- uint output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
-
- /** points into the i915->current.constants array: */
- float (*constants)[4];
- uint num_constants;
- uint constant_flags[I915_MAX_CONSTANT]; /**< status of each constant */
+ uint declarations[I915_PROGRAM_SIZE];
+ uint program[I915_PROGRAM_SIZE];
uint *csr; /**< Cursor, points into program. */
@@ -155,7 +151,9 @@ swizzle(int reg, uint x, uint y, uint z, uint w)
/***********************************************************************
* Public interface for the compiler
*/
-extern void i915_translate_fragment_program( struct i915_context *i915 );
+extern void
+i915_translate_fragment_program( struct i915_context *i915,
+ struct i915_fragment_shader *fs);
@@ -206,8 +204,5 @@ extern void i915_disassemble_program(const uint * program, uint sz);
extern void
i915_program_error(struct i915_fp_compile *p, const char *msg, ...);
-extern void
-i915_translate_fragment_program(struct i915_context *i915);
-
#endif
diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c
index 74924ff0a1..4bdeefb449 100644
--- a/src/gallium/drivers/i915simple/i915_fpc_emit.c
+++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c
@@ -61,8 +61,6 @@
(REG_NR_MASK << UREG_NR_SHIFT))
-#define I915_CONSTFLAG_PARAM 0x1f
-
uint
i915_get_temp(struct i915_fp_compile *p)
{
@@ -73,10 +71,21 @@ i915_get_temp(struct i915_fp_compile *p)
}
p->temp_flag |= 1 << (bit - 1);
- return UREG(REG_TYPE_R, (bit - 1));
+ return bit - 1;
+}
+
+
+static void
+i915_release_temp(struct i915_fp_compile *p, int reg)
+{
+ p->temp_flag &= ~(1 << reg);
}
+/**
+ * Get unpreserved temporary, a temp whose value is not preserved between
+ * PS program phases.
+ */
uint
i915_get_utemp(struct i915_fp_compile * p)
{
@@ -185,41 +194,62 @@ i915_emit_arith(struct i915_fp_compile * p,
return dest;
}
+
+/**
+ * Emit a texture load or texkill instruction.
+ * \param dest the dest i915 register
+ * \param destmask the dest register writemask
+ * \param sampler the i915 sampler register
+ * \param coord the i915 source texcoord operand
+ * \param opcode the instruction opcode
+ */
uint i915_emit_texld( struct i915_fp_compile *p,
uint dest,
uint destmask,
uint sampler,
uint coord,
- uint op )
+ uint opcode )
{
- uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
+ const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
+ int temp = -1;
+
if (coord != k) {
- /* No real way to work around this in the general case - need to
- * allocate and declare a new temporary register (a utemp won't
- * do). Will fallback for now.
+ /* texcoord is swizzled or negated. Need to allocate a new temporary
+ * register (a utemp / unpreserved temp) won't do.
*/
- i915_program_error(p, "Can't (yet) swizzle TEX arguments");
- assert(0);
- return 0;
+ uint tempReg;
+
+ temp = i915_get_temp(p); /* get temp reg index */
+ tempReg = UREG(REG_TYPE_R, temp); /* make i915 register */
+
+ i915_emit_arith( p, A0_MOV,
+ tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */
+ 0, /* saturate */
+ coord, 0, 0 ); /* src0, src1, src2 */
+
+ /* new src texcoord is tempReg */
+ coord = tempReg;
}
/* Don't worry about saturate as we only support
*/
if (destmask != A0_DEST_CHANNEL_ALL) {
+ /* if not writing to XYZW... */
uint tmp = i915_get_utemp(p);
- i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
+ i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode );
i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
- return dest;
+ /* XXX release utemp here? */
}
else {
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
+ /* is the sampler coord a texcoord input reg? */
if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
p->nr_tex_indirect++;
}
- *(p->csr++) = (op |
+ *(p->csr++) = (opcode |
T0_DEST( dest ) |
T0_SAMPLER( sampler ));
@@ -227,14 +257,19 @@ uint i915_emit_texld( struct i915_fp_compile *p,
*(p->csr++) = T2_MBZ;
p->nr_tex_insn++;
- return dest;
}
+
+ if (temp >= 0)
+ i915_release_temp(p, temp);
+
+ return dest;
}
uint
i915_emit_const1f(struct i915_fp_compile * p, float c0)
{
+ struct i915_fragment_shader *ifs = p->shader;
unsigned reg, idx;
if (c0 == 0.0)
@@ -243,15 +278,15 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0)
return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
+ if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
continue;
for (idx = 0; idx < 4; idx++) {
- if (!(p->constant_flags[reg] & (1 << idx)) ||
- p->constants[reg][idx] == c0) {
- p->constants[reg][idx] = c0;
- p->constant_flags[reg] |= 1 << idx;
- if (reg + 1 > p->num_constants)
- p->num_constants = reg + 1;
+ if (!(ifs->constant_flags[reg] & (1 << idx)) ||
+ ifs->constants[reg][idx] == c0) {
+ ifs->constants[reg][idx] = c0;
+ ifs->constant_flags[reg] |= 1 << idx;
+ if (reg + 1 > ifs->num_constants)
+ ifs->num_constants = reg + 1;
return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
}
}
@@ -264,6 +299,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0)
uint
i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
{
+ struct i915_fragment_shader *ifs = p->shader;
unsigned reg, idx;
if (c0 == 0.0)
@@ -277,16 +313,16 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0xf ||
- p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
+ if (ifs->constant_flags[reg] == 0xf ||
+ ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
continue;
for (idx = 0; idx < 3; idx++) {
- if (!(p->constant_flags[reg] & (3 << idx))) {
- p->constants[reg][idx + 0] = c0;
- p->constants[reg][idx + 1] = c1;
- p->constant_flags[reg] |= 3 << idx;
- if (reg + 1 > p->num_constants)
- p->num_constants = reg + 1;
+ if (!(ifs->constant_flags[reg] & (3 << idx))) {
+ ifs->constants[reg][idx + 0] = c0;
+ ifs->constants[reg][idx + 1] = c1;
+ ifs->constant_flags[reg] |= 3 << idx;
+ if (reg + 1 > ifs->num_constants)
+ ifs->num_constants = reg + 1;
return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE);
}
}
@@ -302,25 +338,26 @@ uint
i915_emit_const4f(struct i915_fp_compile * p,
float c0, float c1, float c2, float c3)
{
+ struct i915_fragment_shader *ifs = p->shader;
unsigned reg;
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0xf &&
- p->constants[reg][0] == c0 &&
- p->constants[reg][1] == c1 &&
- p->constants[reg][2] == c2 &&
- p->constants[reg][3] == c3) {
+ if (ifs->constant_flags[reg] == 0xf &&
+ ifs->constants[reg][0] == c0 &&
+ ifs->constants[reg][1] == c1 &&
+ ifs->constants[reg][2] == c2 &&
+ ifs->constants[reg][3] == c3) {
return UREG(REG_TYPE_CONST, reg);
}
- else if (p->constant_flags[reg] == 0) {
-
- p->constants[reg][0] = c0;
- p->constants[reg][1] = c1;
- p->constants[reg][2] = c2;
- p->constants[reg][3] = c3;
- p->constant_flags[reg] = 0xf;
- if (reg + 1 > p->num_constants)
- p->num_constants = reg + 1;
+ else if (ifs->constant_flags[reg] == 0) {
+
+ ifs->constants[reg][0] = c0;
+ ifs->constants[reg][1] = c1;
+ ifs->constants[reg][2] = c2;
+ ifs->constants[reg][3] = c3;
+ ifs->constant_flags[reg] = 0xf;
+ if (reg + 1 > ifs->num_constants)
+ ifs->num_constants = reg + 1;
return UREG(REG_TYPE_CONST, reg);
}
}
@@ -335,41 +372,3 @@ i915_emit_const4fv(struct i915_fp_compile * p, const float * c)
{
return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
}
-
-
-#if 00000/*UNUSED*/
-/* Reserve a slot in the constant file for a Mesa state parameter.
- * These will later need to be tracked on statechanges, but that is
- * done elsewhere.
- */
-uint
-i915_emit_param4fv(struct i915_fp_compile * p, const float * values)
-{
- struct i915_fragment_program *fp = p->fp;
- int i;
-
- for (i = 0; i < fp->nr_params; i++) {
- if (fp->param[i].values == values)
- return UREG(REG_TYPE_CONST, fp->param[i].reg);
- }
-
- if (p->constants->nr_constants == I915_MAX_CONSTANT ||
- fp->nr_params == I915_MAX_CONSTANT) {
- i915_program_error(p, "i915_emit_param4fv: out of constants\n");
- return 0;
- }
-
- {
- int reg = p->constants->nr_constants++;
- int i = fp->nr_params++;
-
- assert (p->constant_flags[reg] == 0);
- p->constant_flags[reg] = I915_CONSTFLAG_PARAM;
-
- fp->param[i].values = values;
- fp->param[i].reg = reg;
-
- return UREG(REG_TYPE_CONST, reg);
- }
-}
-#endif
diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c
index 6c1524c768..c2d9a93c6c 100644
--- a/src/gallium/drivers/i915simple/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c
@@ -34,6 +34,7 @@
#include "pipe/p_shader_tokens.h"
#include "tgsi/util/tgsi_parse.h"
+#include "tgsi/util/tgsi_dump.h"
#include "draw/draw_vertex.h"
@@ -97,19 +98,19 @@ negate(int reg, int x, int y, int z, int w)
}
+/**
+ * In the event of a translation failure, we'll generate a simple color
+ * pass-through program.
+ */
static void
-i915_use_passthrough_shader(struct i915_context *i915)
+i915_use_passthrough_shader(struct i915_fragment_shader *fs)
{
- debug_printf("**** Using i915 pass-through fragment shader\n");
-
- i915->current.program = (uint *) MALLOC(sizeof(passthrough));
- if (i915->current.program) {
- memcpy(i915->current.program, passthrough, sizeof(passthrough));
- i915->current.program_len = Elements(passthrough);
+ fs->program = (uint *) MALLOC(sizeof(passthrough));
+ if (fs->program) {
+ memcpy(fs->program, passthrough, sizeof(passthrough));
+ fs->program_len = Elements(passthrough);
}
-
- i915->current.num_constants[PIPE_SHADER_FRAGMENT] = 0;
- i915->current.num_user_constants[PIPE_SHADER_FRAGMENT] = 0;
+ fs->num_constants = 0;
}
@@ -161,11 +162,8 @@ src_vector(struct i915_fp_compile *p,
* We also use a texture coordinate to pass wpos when possible.
*/
- /* use vertex format info to map a slot number to a VF attrib */
- assert(index < p->vertex_info->num_attribs);
-
- sem_name = p->input_semantic_name[index];
- sem_ind = p->input_semantic_index[index];
+ sem_name = p->shader->info.input_semantic_name[index];
+ sem_ind = p->shader->info.input_semantic_index[index];
switch (sem_name) {
case TGSI_SEMANTIC_POSITION:
@@ -201,7 +199,8 @@ src_vector(struct i915_fp_compile *p,
break;
case TGSI_FILE_IMMEDIATE:
- /* XXX unfinished - need to append immediates onto const buffer */
+ assert(index < p->num_immediates);
+ index = p->immediates_map[index];
/* fall-through */
case TGSI_FILE_CONSTANT:
src = UREG(REG_TYPE_CONST, index);
@@ -266,7 +265,7 @@ get_result_vector(struct i915_fp_compile *p,
switch (dest->DstRegister.File) {
case TGSI_FILE_OUTPUT:
{
- uint sem_name = p->output_semantic_name[dest->DstRegister.Index];
+ uint sem_name = p->shader->info.output_semantic_name[dest->DstRegister.Index];
switch (sem_name) {
case TGSI_SEMANTIC_POSITION:
return UREG(REG_TYPE_OD, 0);
@@ -386,6 +385,26 @@ emit_simple_arith(struct i915_fp_compile *p,
arg3 );
}
+
+/** As above, but swap the first two src regs */
+static void
+emit_simple_arith_swap2(struct i915_fp_compile *p,
+ const struct tgsi_full_instruction *inst,
+ uint opcode, uint numArgs)
+{
+ struct tgsi_full_instruction inst2;
+
+ assert(numArgs == 2);
+
+ /* transpose first two registers */
+ inst2 = *inst;
+ inst2.FullSrcRegisters[0] = inst->FullSrcRegisters[1];
+ inst2.FullSrcRegisters[1] = inst->FullSrcRegisters[0];
+
+ emit_simple_arith(p, &inst2, opcode, numArgs);
+}
+
+
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
@@ -556,8 +575,12 @@ i915_translate_instruction(struct i915_fp_compile *p,
src0 = src_vector(p, &inst->FullSrcRegisters[0]);
tmp = i915_get_utemp(p);
- i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */
- 0, src0, T0_TEXKILL);
+ i915_emit_texld(p,
+ tmp, /* dest reg: a dummy reg */
+ A0_DEST_CHANNEL_ALL, /* dest writemask */
+ 0, /* sampler */
+ src0, /* coord*/
+ T0_TEXKILL); /* opcode */
break;
case TGSI_OPCODE_LG2:
@@ -773,6 +796,11 @@ i915_translate_instruction(struct i915_fp_compile *p,
emit_simple_arith(p, inst, A0_SGE, 2);
break;
+ case TGSI_OPCODE_SLE:
+ /* like SGE, but swap reg0, reg1 */
+ emit_simple_arith_swap2(p, inst, A0_SGE, 2);
+ break;
+
case TGSI_OPCODE_SIN:
src0 = src_vector(p, &inst->FullSrcRegisters[0]);
tmp = i915_get_utemp(p);
@@ -827,6 +855,11 @@ i915_translate_instruction(struct i915_fp_compile *p,
emit_simple_arith(p, inst, A0_SLT, 2);
break;
+ case TGSI_OPCODE_SGT:
+ /* like SLT, but swap reg0, reg1 */
+ emit_simple_arith_swap2(p, inst, A0_SLT, 2);
+ break;
+
case TGSI_OPCODE_SUB:
src0 = src_vector(p, &inst->FullSrcRegisters[0]);
src1 = src_vector(p, &inst->FullSrcRegisters[1]);
@@ -880,6 +913,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
default:
i915_program_error(p, "bad opcode %d", inst->Instruction.Opcode);
+ p->error = 1;
return;
}
@@ -896,6 +930,7 @@ static void
i915_translate_instructions(struct i915_fp_compile *p,
const struct tgsi_token *tokens)
{
+ struct i915_fragment_shader *ifs = p->shader;
struct tgsi_parse_context parse;
tgsi_parse_init( &parse, tokens );
@@ -907,34 +942,64 @@ i915_translate_instructions(struct i915_fp_compile *p,
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullToken.FullDeclaration.Declaration.File
- == TGSI_FILE_INPUT) {
- /* save input register info for use in src_vector() */
- uint ind, sem, semi;
- ind = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
- sem = parse.FullToken.FullDeclaration.Semantic.SemanticName;
- semi = parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
- /*debug_printf("FS Input DECL [%u] sem %u\n", ind, sem);*/
- p->input_semantic_name[ind] = sem;
- p->input_semantic_index[ind] = semi;
+ == TGSI_FILE_CONSTANT) {
+ uint i;
+ for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
+ i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
+ i++) {
+ assert(ifs->constant_flags[i] == 0x0);
+ ifs->constant_flags[i] = I915_CONSTFLAG_USER;
+ ifs->num_constants = MAX2(ifs->num_constants, i + 1);
+ }
}
else if (parse.FullToken.FullDeclaration.Declaration.File
- == TGSI_FILE_OUTPUT) {
- /* save output register info for use in get_result_vector() */
- uint ind, sem, semi;
- ind = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
- sem = parse.FullToken.FullDeclaration.Semantic.SemanticName;
- semi = parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
- /*debug_printf("FS Output DECL [%u] sem %u\n", ind, sem);*/
- p->output_semantic_name[ind] = sem;
- p->output_semantic_index[ind] = semi;
+ == TGSI_FILE_TEMPORARY) {
+ uint i;
+ for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
+ i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
+ i++) {
+ assert(i < I915_MAX_TEMPORARY);
+ /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
+ p->temp_flag |= (1 << i); /* mark temp as used */
+ }
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
- /* XXX append the immediate to the const buffer... */
+ {
+ const struct tgsi_full_immediate *imm
+ = &parse.FullToken.FullImmediate;
+ const uint pos = p->num_immediates++;
+ uint j;
+ for (j = 0; j < imm->Immediate.Size; j++) {
+ p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float;
+ }
+ }
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
+ if (p->first_instruction) {
+ /* resolve location of immediates */
+ uint i, j;
+ for (i = 0; i < p->num_immediates; i++) {
+ /* find constant slot for this immediate */
+ for (j = 0; j < I915_MAX_CONSTANT; j++) {
+ if (ifs->constant_flags[j] == 0x0) {
+ memcpy(ifs->constants[j],
+ p->immediates[i],
+ 4 * sizeof(float));
+ /*printf("immediate %d maps to const %d\n", i, j);*/
+ ifs->constant_flags[j] = 0xf; /* all four comps used */
+ p->immediates_map[i] = j;
+ ifs->num_constants = MAX2(ifs->num_constants, j + 1);
+ break;
+ }
+ }
+ }
+
+ p->first_instruction = FALSE;
+ }
+
i915_translate_instruction(p, &parse.FullToken.FullInstruction);
break;
@@ -950,32 +1015,33 @@ i915_translate_instructions(struct i915_fp_compile *p,
static struct i915_fp_compile *
i915_init_compile(struct i915_context *i915,
- const struct pipe_shader_state *fs)
+ struct i915_fragment_shader *ifs)
{
struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile);
- p->shader = i915->fs;
-
- p->vertex_info = &i915->current.vertex_info;
+ p->shader = ifs;
- /* new constants found during translation get appended after the
- * user-provided constants.
+ /* Put new constants at end of const buffer, growing downward.
+ * The problem is we don't know how many user-defined constants might
+ * be specified with pipe->set_constant_buffer().
+ * Should pre-scan the user's program to determine the highest-numbered
+ * constant referenced.
*/
- p->constants = i915->current.constants[PIPE_SHADER_FRAGMENT];
- p->num_constants = i915->current.num_user_constants[PIPE_SHADER_FRAGMENT];
+ ifs->num_constants = 0;
+ memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags));
+
+ p->first_instruction = TRUE;
p->nr_tex_indirect = 1; /* correct? */
p->nr_tex_insn = 0;
p->nr_alu_insn = 0;
p->nr_decl_insn = 0;
- memset(p->constant_flags, 0, sizeof(p->constant_flags));
-
p->csr = p->program;
p->decl = p->declarations;
p->decl_s = 0;
p->decl_t = 0;
- p->temp_flag = 0xffff000;
+ p->temp_flag = ~0x0 << I915_MAX_TEMPORARY;
p->utemp_flag = ~0x7;
p->wpos_tex = -1;
@@ -993,6 +1059,7 @@ i915_init_compile(struct i915_context *i915,
static void
i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
{
+ struct i915_fragment_shader *ifs = p->shader;
unsigned long program_size = (unsigned long) (p->csr - p->program);
unsigned long decl_size = (unsigned long) (p->decl - p->declarations);
@@ -1008,19 +1075,13 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
if (p->nr_decl_insn > I915_MAX_DECL_INSN)
i915_program_error(p, "Exceeded max DECL instructions");
- /* free old program, if present */
- if (i915->current.program) {
- FREE(i915->current.program);
- i915->current.program_len = 0;
- }
-
if (p->error) {
p->NumNativeInstructions = 0;
p->NumNativeAluInstructions = 0;
p->NumNativeTexInstructions = 0;
p->NumNativeTexIndirections = 0;
- i915_use_passthrough_shader(i915);
+ i915_use_passthrough_shader(ifs);
}
else {
p->NumNativeInstructions
@@ -1034,24 +1095,20 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
/* Copy compilation results to fragment program struct:
*/
- i915->current.program
+ assert(!ifs->program);
+ ifs->program
= (uint *) MALLOC((program_size + decl_size) * sizeof(uint));
- if (i915->current.program) {
- i915->current.program_len = program_size + decl_size;
+ if (ifs->program) {
+ ifs->program_len = program_size + decl_size;
- memcpy(i915->current.program,
+ memcpy(ifs->program,
p->declarations,
decl_size * sizeof(uint));
- memcpy(i915->current.program + decl_size,
+ memcpy(ifs->program + decl_size,
p->program,
program_size * sizeof(uint));
}
-
- /* update number of constants */
- i915->current.num_constants[PIPE_SHADER_FRAGMENT] = p->num_constants;
- assert(i915->current.num_constants[PIPE_SHADER_FRAGMENT]
- >= i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]);
}
/* Release the compilation struct:
@@ -1085,7 +1142,7 @@ i915_find_wpos_space(struct i915_fp_compile *p)
i915_program_error(p, "No free texcoord for wpos value");
}
#else
- if (p->shader->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
+ if (p->shader->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
/* frag shader using the fragment position input */
#if 0
assert(0);
@@ -1106,7 +1163,7 @@ static void
i915_fixup_depth_write(struct i915_fp_compile *p)
{
/* XXX assuming pos/depth is always in output[0] */
- if (p->shader->output_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
+ if (p->shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
const uint depth = UREG(REG_TYPE_OD, 0);
i915_emit_arith(p,
@@ -1121,13 +1178,18 @@ i915_fixup_depth_write(struct i915_fp_compile *p)
void
-i915_translate_fragment_program( struct i915_context *i915 )
+i915_translate_fragment_program( struct i915_context *i915,
+ struct i915_fragment_shader *fs)
{
- struct i915_fp_compile *p = i915_init_compile(i915, i915->fs);
- const struct tgsi_token *tokens = i915->fs->tokens;
+ struct i915_fp_compile *p = i915_init_compile(i915, fs);
+ const struct tgsi_token *tokens = fs->state.tokens;
i915_find_wpos_space(p);
+#if 0
+ tgsi_dump(tokens, 0);
+#endif
+
i915_translate_instructions(p, tokens);
i915_fixup_depth_write(p);
diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c
index 44c4325936..d8de5178f6 100644
--- a/src/gallium/drivers/i915simple/i915_prim_emit.c
+++ b/src/gallium/drivers/i915simple/i915_prim_emit.c
@@ -72,38 +72,42 @@ emit_hw_vertex( struct i915_context *i915,
uint i;
uint count = 0; /* for debug/sanity */
+ assert(!i915->dirty);
+
for (i = 0; i < vinfo->num_attribs; i++) {
+ const uint j = vinfo->src_index[i];
+ const float *attrib = vertex->data[j];
switch (vinfo->emit[i]) {
case EMIT_OMIT:
/* no-op */
break;
case EMIT_1F:
- OUT_BATCH( fui(vertex->data[i][0]) );
+ OUT_BATCH( fui(attrib[0]) );
count++;
break;
case EMIT_2F:
- OUT_BATCH( fui(vertex->data[i][0]) );
- OUT_BATCH( fui(vertex->data[i][1]) );
+ OUT_BATCH( fui(attrib[0]) );
+ OUT_BATCH( fui(attrib[1]) );
count += 2;
break;
case EMIT_3F:
- OUT_BATCH( fui(vertex->data[i][0]) );
- OUT_BATCH( fui(vertex->data[i][1]) );
- OUT_BATCH( fui(vertex->data[i][2]) );
+ OUT_BATCH( fui(attrib[0]) );
+ OUT_BATCH( fui(attrib[1]) );
+ OUT_BATCH( fui(attrib[2]) );
count += 3;
break;
case EMIT_4F:
- OUT_BATCH( fui(vertex->data[i][0]) );
- OUT_BATCH( fui(vertex->data[i][1]) );
- OUT_BATCH( fui(vertex->data[i][2]) );
- OUT_BATCH( fui(vertex->data[i][3]) );
+ OUT_BATCH( fui(attrib[0]) );
+ OUT_BATCH( fui(attrib[1]) );
+ OUT_BATCH( fui(attrib[2]) );
+ OUT_BATCH( fui(attrib[3]) );
count += 4;
break;
case EMIT_4UB:
- OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[i][2] ),
- float_to_ubyte( vertex->data[i][1] ),
- float_to_ubyte( vertex->data[i][0] ),
- float_to_ubyte( vertex->data[i][3] )) );
+ OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ),
+ float_to_ubyte( attrib[1] ),
+ float_to_ubyte( attrib[0] ),
+ float_to_ubyte( attrib[3] )) );
count += 1;
break;
default:
@@ -122,17 +126,19 @@ emit_prim( struct draw_stage *stage,
unsigned nr )
{
struct i915_context *i915 = setup_stage(stage)->i915;
- unsigned vertex_size = i915->current.vertex_info.size * 4; /* in bytes */
+ unsigned vertex_size;
unsigned i;
- assert(vertex_size >= 12); /* never smaller than 12 bytes */
-
if (i915->dirty)
i915_update_derived( i915 );
if (i915->hardware_dirty)
i915_emit_hardware_state( i915 );
+ /* need to do this after validation! */
+ vertex_size = i915->current.vertex_info.size * 4; /* in bytes */
+ assert(vertex_size >= 12); /* never smaller than 12 bytes */
+
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
FLUSH_BATCH();
diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
index c5bf6174f6..9d5f609220 100644
--- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
@@ -83,6 +83,12 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
+
+ if (i915->dirty) {
+ /* make sure we have up to date vertex layout */
+ i915_update_derived( i915 );
+ }
+
return &i915->current.vertex_info;
}
@@ -143,7 +149,8 @@ i915_vbuf_render_draw( struct vbuf_render *render,
assert(nr_indices);
- assert((i915->dirty & ~I915_NEW_VBO) == 0);
+ /* this seems to be bogus, since we validate state right after this */
+ /*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/
if (i915->dirty)
i915_update_derived( i915 );
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
new file mode 100644
index 0000000000..8d7bf0b33e
--- /dev/null
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -0,0 +1,250 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_screen.h"
+#include "i915_texture.h"
+
+
+static const char *
+i915_get_vendor( struct pipe_screen *pscreen )
+{
+ return "Tungsten Graphics, Inc.";
+}
+
+
+static const char *
+i915_get_name( struct pipe_screen *pscreen )
+{
+ static char buffer[128];
+ const char *chipset;
+
+ switch (i915_screen(pscreen)->pci_id) {
+ case PCI_CHIP_I915_G:
+ chipset = "915G";
+ break;
+ case PCI_CHIP_I915_GM:
+ chipset = "915GM";
+ break;
+ case PCI_CHIP_I945_G:
+ chipset = "945G";
+ break;
+ case PCI_CHIP_I945_GM:
+ chipset = "945GM";
+ break;
+ case PCI_CHIP_I945_GME:
+ chipset = "945GME";
+ break;
+ case PCI_CHIP_G33_G:
+ chipset = "G33";
+ break;
+ case PCI_CHIP_Q35_G:
+ chipset = "Q35";
+ break;
+ case PCI_CHIP_Q33_G:
+ chipset = "Q33";
+ break;
+ default:
+ chipset = "unknown";
+ break;
+ }
+
+ sprintf(buffer, "i915 (chipset: %s)", chipset);
+ return buffer;
+}
+
+
+static int
+i915_get_param(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 8;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 0;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 0;
+ case PIPE_CAP_POINT_SPRITE:
+ return 0;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 1;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 0;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 11; /* max 1024x1024 */
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 8; /* max 128x128x128 */
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 11; /* max 1024x1024 */
+ default:
+ return 0;
+ }
+}
+
+
+static float
+i915_get_paramf(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 7.5;
+
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 255.0;
+
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 4.0;
+
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0;
+
+ default:
+ return 0;
+ }
+}
+
+
+static boolean
+i915_is_format_supported( struct pipe_screen *screen,
+ enum pipe_format format, uint type )
+{
+ static const enum pipe_format tex_supported[] = {
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_R5G6B5_UNORM,
+ PIPE_FORMAT_U_L8,
+ PIPE_FORMAT_U_A8,
+ PIPE_FORMAT_U_I8,
+ PIPE_FORMAT_U_A8_L8,
+ PIPE_FORMAT_YCBCR,
+ PIPE_FORMAT_YCBCR_REV,
+ PIPE_FORMAT_S8Z24_UNORM,
+ PIPE_FORMAT_NONE /* list terminator */
+ };
+ static const enum pipe_format surface_supported[] = {
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_R5G6B5_UNORM,
+ PIPE_FORMAT_S8Z24_UNORM,
+ /*PIPE_FORMAT_R16G16B16A16_SNORM,*/
+ PIPE_FORMAT_NONE /* list terminator */
+ };
+ const enum pipe_format *list;
+ uint i;
+
+ switch (type) {
+ case PIPE_TEXTURE:
+ list = tex_supported;
+ break;
+ case PIPE_SURFACE:
+ list = surface_supported;
+ break;
+ default:
+ assert(0);
+ }
+
+ for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) {
+ if (list[i] == format)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+i915_destroy_screen( struct pipe_screen *screen )
+{
+ FREE(screen);
+}
+
+
+/**
+ * Create a new i915_screen object
+ */
+struct pipe_screen *
+i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
+{
+ struct i915_screen *i915screen = CALLOC_STRUCT(i915_screen);
+
+ if (!i915screen)
+ return NULL;
+
+ switch (pci_id) {
+ case PCI_CHIP_I915_G:
+ case PCI_CHIP_I915_GM:
+ i915screen->is_i945 = FALSE;
+ break;
+
+ case PCI_CHIP_I945_G:
+ case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I945_GME:
+ case PCI_CHIP_G33_G:
+ case PCI_CHIP_Q33_G:
+ case PCI_CHIP_Q35_G:
+ i915screen->is_i945 = TRUE;
+ break;
+
+ default:
+ winsys->printf(winsys,
+ "%s: unknown pci id 0x%x, cannot create screen\n",
+ __FUNCTION__, pci_id);
+ return NULL;
+ }
+
+ i915screen->pci_id = pci_id;
+
+ i915screen->screen.winsys = winsys;
+
+ i915screen->screen.destroy = i915_destroy_screen;
+
+ i915screen->screen.get_name = i915_get_name;
+ i915screen->screen.get_vendor = i915_get_vendor;
+ i915screen->screen.get_param = i915_get_param;
+ i915screen->screen.get_paramf = i915_get_paramf;
+ i915screen->screen.is_format_supported = i915_is_format_supported;
+
+ i915_init_screen_texture_functions(&i915screen->screen);
+
+ return &i915screen->screen;
+}
diff --git a/src/gallium/drivers/i965simple/brw_strings.c b/src/gallium/drivers/i915simple/i915_screen.h
index 3d9c50961f..73b0ff05ce 100644
--- a/src/gallium/drivers/i965simple/brw_strings.c
+++ b/src/gallium/drivers/i915simple/i915_screen.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,48 +25,45 @@
*
**************************************************************************/
-#include "brw_context.h"
-#include "brw_reg.h"
+#ifndef I915_SCREEN_H
+#define I915_SCREEN_H
-static const char *brw_get_vendor( struct pipe_context *pipe )
+
+#include "pipe/p_screen.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Subclass of pipe_screen
+ */
+struct i915_screen
{
- return "Tungsten Graphics, Inc.";
-}
+ struct pipe_screen screen;
+ boolean is_i945;
+ uint pci_id;
+};
-static const char *brw_get_name( struct pipe_context *pipe )
+
+/** cast wrapper */
+static INLINE struct i915_screen *
+i915_screen(struct pipe_screen *pscreen)
{
- static char buffer[128];
- const char *chipset;
-
- switch (brw_context(pipe)->pci_id) {
- case PCI_CHIP_I965_Q:
- chipset = "Intel(R) 965Q";
- break;
- case PCI_CHIP_I965_G:
- case PCI_CHIP_I965_G_1:
- chipset = "Intel(R) 965G";
- break;
- case PCI_CHIP_I965_GM:
- chipset = "Intel(R) 965GM";
- break;
- case PCI_CHIP_I965_GME:
- chipset = "Intel(R) 965GME/GLE";
- break;
- default:
- chipset = "unknown";
- break;
- }
-
- sprintf(buffer, "i965 (chipset: %s)", chipset);
- return buffer;
+ return (struct i915_screen *) pscreen;
}
-void
-brw_init_string_functions(struct brw_context *brw)
-{
- brw->pipe.get_name = brw_get_name;
- brw->pipe.get_vendor = brw_get_vendor;
+extern struct pipe_screen *
+i915_create_screen(struct pipe_winsys *winsys, uint pci_id);
+
+
+#ifdef __cplusplus
}
+#endif
+
+#endif /* I915_SCREEN_H */
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 294e6fad03..27af46bea0 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -32,11 +32,13 @@
#include "draw/draw_context.h"
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "i915_context.h"
#include "i915_reg.h"
#include "i915_state.h"
#include "i915_state_inlines.h"
+#include "i915_fpc.h"
/* The i915 (and related graphics cores) do not support GL_CLAMP. The
@@ -415,26 +417,49 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe,
}
-static void * i915_create_fs_state(struct pipe_context *pipe,
- const struct pipe_shader_state *templ)
+
+static void *
+i915_create_fs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *templ)
{
- return 0;
+ struct i915_context *i915 = i915_context(pipe);
+ struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader);
+ if (!ifs)
+ return NULL;
+
+ ifs->state = *templ;
+
+ tgsi_scan_shader(templ->tokens, &ifs->info);
+
+ /* The shader's compiled to i915 instructions here */
+ i915_translate_fragment_program(i915, ifs);
+
+ return ifs;
}
-static void i915_bind_fs_state(struct pipe_context *pipe, void *fs)
+static void
+i915_bind_fs_state(struct pipe_context *pipe, void *shader)
{
struct i915_context *i915 = i915_context(pipe);
- i915->fs = (struct pipe_shader_state *)fs;
+ i915->fs = (struct i915_fragment_shader*) shader;
i915->dirty |= I915_NEW_FS;
}
-static void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
+static
+void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
{
- /*do nothing*/
+ struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader;
+
+ if (ifs->program)
+ FREE(ifs->program);
+ ifs->program_len = 0;
+
+ FREE(ifs);
}
+
static void *
i915_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
@@ -451,6 +476,8 @@ static void i915_bind_vs_state(struct pipe_context *pipe, void *shader)
/* just pass-through to draw module */
draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader);
+
+ i915->dirty |= I915_NEW_VS;
}
static void i915_delete_vs_state(struct pipe_context *pipe, void *shader)
@@ -505,7 +532,8 @@ static void i915_set_sampler_texture(struct pipe_context *pipe,
{
struct i915_context *i915 = i915_context(pipe);
- i915->texture[sampler] = (struct i915_texture*)texture; /* ptr, not struct */
+ pipe_texture_reference((struct pipe_texture **) &i915->texture[sampler],
+ texture);
i915->dirty |= I915_NEW_TEXTURE;
}
diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c
index 4767584fc6..4daccec6e0 100644
--- a/src/gallium/drivers/i915simple/i915_state_derived.c
+++ b/src/gallium/drivers/i915simple/i915_state_derived.c
@@ -27,104 +27,111 @@
#include "pipe/p_util.h"
+#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "draw/draw_vertex.h"
#include "i915_context.h"
#include "i915_state.h"
#include "i915_reg.h"
#include "i915_fpc.h"
-#include "pipe/p_shader_tokens.h"
+
/**
- * Determine which post-transform / pre-rasterization vertex attributes
- * we need.
- * Derived from: fs, setup states.
+ * Determine the hardware vertex layout.
+ * Depends on vertex/fragment shader state.
*/
static void calculate_vertex_layout( struct i915_context *i915 )
{
- const struct pipe_shader_state *fs = i915->fs;
+ const struct i915_fragment_shader *fs = i915->fs;
const enum interp_mode colorInterp = i915->rasterizer->color_interp;
struct vertex_info vinfo;
- uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
- boolean needW = 0;
+ boolean texCoords[8], colors[2], fog, needW;
uint i;
- boolean texCoords[8];
- uint src = 0;
+ int src;
memset(texCoords, 0, sizeof(texCoords));
+ colors[0] = colors[1] = fog = needW = FALSE;
memset(&vinfo, 0, sizeof(vinfo));
- /* pos */
- draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src++);
- /* Note: we'll set the S4_VFMT_XYZ[W] bits below */
-
- for (i = 0; i < fs->num_inputs; i++) {
- switch (fs->input_semantic_name[i]) {
+ /* Determine which fragment program inputs are needed. Setup HW vertex
+ * layout below, in the HW-specific attribute order.
+ */
+ for (i = 0; i < fs->info.num_inputs; i++) {
+ switch (fs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
break;
case TGSI_SEMANTIC_COLOR:
- if (fs->input_semantic_index[i] == 0) {
- front0 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++);
- vinfo.hwfmt[0] |= S4_VFMT_COLOR;
- }
- else {
- assert(fs->input_semantic_index[i] == 1);
- front1 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++);
- vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
- }
+ assert(fs->info.input_semantic_index[i] < 2);
+ colors[fs->info.input_semantic_index[i]] = TRUE;
break;
case TGSI_SEMANTIC_GENERIC:
/* usually a texcoord */
{
- const uint unit = fs->input_semantic_index[i];
- uint hwtc;
+ const uint unit = fs->info.input_semantic_index[i];
+ assert(unit < 8);
texCoords[unit] = TRUE;
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
- hwtc = TEXCOORDFMT_4D;
needW = TRUE;
- vinfo.hwfmt[1] |= hwtc << (unit * 4);
}
break;
case TGSI_SEMANTIC_FOG:
- debug_printf("i915 fogcoord not implemented yet\n");
- draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src++);
+ fog = TRUE;
break;
default:
assert(0);
}
-
}
- /* finish up texcoord fields */
- for (i = 0; i < 8; i++) {
- if (!texCoords[i]) {
- const uint hwtc = TEXCOORDFMT_NOT_PRESENT;
- vinfo.hwfmt[1] |= hwtc << (i* 4);
- }
- }
-
- /* go back and fill in the vertex position info now that we have needW */
+
+ /* pos */
+ src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
if (needW) {
+ draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src);
vinfo.hwfmt[0] |= S4_VFMT_XYZW;
vinfo.emit[0] = EMIT_4F;
}
else {
+ draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src);
vinfo.hwfmt[0] |= S4_VFMT_XYZ;
vinfo.emit[0] = EMIT_3F;
}
- /* Additional attributes required for setup: Just twosided
- * lighting. Edgeflag is dealt with specially by setting bits in
- * the vertex header.
- */
- if (i915->rasterizer->light_twoside) {
- if (front0) {
- back0 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++);
+ /* hardware point size */
+ /* XXX todo */
+
+ /* primary color */
+ if (colors[0]) {
+ src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ vinfo.hwfmt[0] |= S4_VFMT_COLOR;
+ }
+
+ /* secondary color */
+ if (colors[1]) {
+ src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
+ }
+
+ /* fog coord, not fog blend factor */
+ if (fog) {
+ src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
+ draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
+ vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
+ }
+
+ /* texcoords */
+ for (i = 0; i < 8; i++) {
+ uint hwtc;
+ if (texCoords[i]) {
+ hwtc = TEXCOORDFMT_4D;
+ src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_GENERIC, i);
+ draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
}
- if (back0) {
- back1 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++);
+ else {
+ hwtc = TEXCOORDFMT_NOT_PRESENT;
}
+ vinfo.hwfmt[1] |= hwtc << (i * 4);
}
draw_compute_vertex_size(&vinfo);
@@ -148,7 +155,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
*/
void i915_update_derived( struct i915_context *i915 )
{
- if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS))
+ if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS))
calculate_vertex_layout( i915 );
if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE))
@@ -164,7 +171,6 @@ void i915_update_derived( struct i915_context *i915 )
i915_update_dynamic( i915 );
if (i915->dirty & I915_NEW_FS) {
- i915_translate_fragment_program(i915);
i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */
}
diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c
index 3339287f49..6bbaac4e34 100644
--- a/src/gallium/drivers/i915simple/i915_state_emit.c
+++ b/src/gallium/drivers/i915simple/i915_state_emit.c
@@ -99,7 +99,11 @@ i915_emit_hardware_state(struct i915_context *i915 )
2 + I915_TEX_UNITS*3 +
2 + I915_TEX_UNITS*3 +
2 + I915_MAX_CONSTANT*4 +
+#if 0
i915->current.program_len +
+#else
+ i915->fs->program_len +
+#endif
6
) * 3/2; /* plus 50% margin */
const unsigned relocs = ( I915_TEX_UNITS +
@@ -325,15 +329,34 @@ i915_emit_hardware_state(struct i915_context *i915 )
/* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_PROGRAM)
{
- const uint nr = i915->current.num_constants[PIPE_SHADER_FRAGMENT];
- assert(nr <= I915_MAX_CONSTANT);
- if (nr > 0) {
- const uint *c
- = (const uint *) i915->current.constants[PIPE_SHADER_FRAGMENT];
+ /* Collate the user-defined constants with the fragment shader's
+ * immediates according to the constant_flags[] array.
+ */
+ const uint nr = i915->fs->num_constants;
+ if (nr) {
uint i;
+
OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) );
OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) );
+
for (i = 0; i < nr; i++) {
+ const uint *c;
+ if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) {
+ /* grab user-defined constant */
+ c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i];
+ }
+ else {
+ /* emit program constant */
+ c = (uint *) i915->fs->constants[i];
+ }
+#if 0 /* debug */
+ {
+ float *f = (float *) c;
+ printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3],
+ (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER
+ ? "user" : "immediate"));
+ }
+#endif
OUT_BATCH(*c++);
OUT_BATCH(*c++);
OUT_BATCH(*c++);
@@ -348,9 +371,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
{
uint i;
/* we should always have, at least, a pass-through program */
- assert(i915->current.program_len > 0);
- for (i = 0; i < i915->current.program_len; i++) {
- OUT_BATCH(i915->current.program[i]);
+ assert(i915->fs->program_len > 0);
+ for (i = 0; i < i915->fs->program_len; i++) {
+ OUT_BATCH(i915->fs->program[i]);
}
}
diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c
index 07031fc6c5..dfbbcab624 100644
--- a/src/gallium/drivers/i915simple/i915_state_immediate.c
+++ b/src/gallium/drivers/i915simple/i915_state_immediate.c
@@ -33,7 +33,7 @@
#include "i915_context.h"
#include "i915_state.h"
#include "i915_reg.h"
-#include "p_util.h"
+#include "pipe/p_util.h"
/* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet.
diff --git a/src/gallium/drivers/i915simple/i915_state_inlines.h b/src/gallium/drivers/i915simple/i915_state_inlines.h
index 0934ac79a4..378de8f9c4 100644
--- a/src/gallium/drivers/i915simple/i915_state_inlines.h
+++ b/src/gallium/drivers/i915simple/i915_state_inlines.h
@@ -28,8 +28,8 @@
#ifndef I915_STATE_INLINES_H
#define I915_STATE_INLINES_H
-#include "p_compiler.h"
-#include "p_defines.h"
+#include "pipe/p_compiler.h"
+#include "pipe/p_defines.h"
#include "i915_reg.h"
diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c
index 17fd27895a..f4fbedbe9b 100644
--- a/src/gallium/drivers/i915simple/i915_surface.c
+++ b/src/gallium/drivers/i915simple/i915_surface.c
@@ -36,48 +36,6 @@
#include "util/p_tile.h"
-/*
- * XXX note: same as code in sp_surface.c
- */
-static struct pipe_surface *
-i915_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
-{
- struct i915_texture *tex = (struct i915_texture *)pt;
- struct pipe_surface *ps;
- unsigned offset; /* in bytes */
-
- offset = tex->level_offset[level];
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- offset += tex->image_offset[level][face] * pt->cpp;
- }
- else if (pt->target == PIPE_TEXTURE_3D) {
- offset += tex->image_offset[level][zslice] * pt->cpp;
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
-
- ps = pipe->winsys->surface_alloc(pipe->winsys);
- if (ps) {
- assert(ps->refcount);
- assert(ps->winsys);
- pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
- ps->format = pt->format;
- ps->cpp = pt->cpp;
- ps->width = pt->width[level];
- ps->height = pt->height[level];
- ps->pitch = tex->pitch;
- ps->offset = offset;
- }
- return ps;
-}
-
-
-
/* Assumes all values are within bounds -- no checking at this level -
* do it higher up if required.
*/
@@ -115,6 +73,7 @@ i915_surface_copy(struct pipe_context *pipe,
}
}
+
/* Fill a rectangular sub-region. Need better logic about when to
* push buffers into AGP - will currently do so whenever possible.
*/
@@ -184,8 +143,6 @@ i915_surface_fill(struct pipe_context *pipe,
void
i915_init_surface_functions(struct i915_context *i915)
{
- i915->pipe.get_tex_surface = i915_get_tex_surface;
-
i915->pipe.surface_copy = i915_surface_copy;
i915->pipe.surface_fill = i915_surface_fill;
}
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index 6d37ae3d74..ef5adff550 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -40,6 +40,7 @@
#include "i915_context.h"
#include "i915_texture.h"
#include "i915_debug.h"
+#include "i915_screen.h"
static unsigned minify( unsigned d )
@@ -187,7 +188,7 @@ static const int step_offsets[6][2] = {
static boolean
-i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
+i915_miptree_layout(struct i915_texture * tex)
{
struct pipe_texture *pt = &tex->base;
unsigned level;
@@ -311,7 +312,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
static boolean
-i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
+i945_miptree_layout(struct i915_texture * tex)
{
struct pipe_texture *pt = &tex->base;
unsigned level;
@@ -478,23 +479,26 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
}
-struct pipe_texture *
-i915_texture_create(struct pipe_context *pipe,
- const struct pipe_texture *templat)
+static struct pipe_texture *
+i915_texture_create_screen(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
if (tex) {
- struct i915_context *i915 = i915_context(pipe);
+ struct i915_screen *i915screen = i915_screen(screen);
+ struct pipe_winsys *ws = screen->winsys;
tex->base = *templat;
+ tex->base.refcount = 1;
+ tex->base.screen = screen;
- if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) :
- i915_miptree_layout(pipe, tex))
- tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex->pitch * tex->base.cpp *
- tex->total_height);
+ if (i915screen->is_i945 ? i945_miptree_layout(tex) :
+ i915_miptree_layout(tex))
+ tex->buffer = ws->buffer_create(ws, 64,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->pitch * tex->base.cpp *
+ tex->total_height);
if (!tex->buffer) {
FREE(tex);
@@ -506,8 +510,9 @@ i915_texture_create(struct pipe_context *pipe,
}
-void
-i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+static void
+i915_texture_release_screen(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -524,7 +529,7 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
- pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL);
+ pipe_buffer_reference(screen->winsys, &tex->buffer, NULL);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i])
@@ -534,3 +539,68 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
}
*pt = NULL;
}
+
+
+static void
+i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture)
+{
+ /* no-op? */
+}
+
+
+/*
+ * XXX note: same as code in sp_surface.c
+ */
+static struct pipe_surface *
+i915_get_tex_surface_screen(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
+{
+ struct i915_texture *tex = (struct i915_texture *)pt;
+ struct pipe_winsys *ws = screen->winsys;
+ struct pipe_surface *ps;
+ unsigned offset; /* in bytes */
+
+ offset = tex->level_offset[level];
+
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ offset += tex->image_offset[level][face] * pt->cpp;
+ }
+ else if (pt->target == PIPE_TEXTURE_3D) {
+ offset += tex->image_offset[level][zslice] * pt->cpp;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+
+ ps = ws->surface_alloc(ws);
+ if (ps) {
+ assert(ps->refcount);
+ assert(ps->winsys);
+ pipe_buffer_reference(ws, &ps->buffer, tex->buffer);
+ ps->format = pt->format;
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = tex->pitch;
+ ps->offset = offset;
+ }
+ return ps;
+}
+
+
+void
+i915_init_texture_functions(struct i915_context *i915)
+{
+ i915->pipe.texture_update = i915_texture_update;
+}
+
+
+void
+i915_init_screen_texture_functions(struct pipe_screen *screen)
+{
+ screen->texture_create = i915_texture_create_screen;
+ screen->texture_release = i915_texture_release_screen;
+ screen->get_tex_surface = i915_get_tex_surface_screen;
+}
diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h
index 330d111dc7..7225016a9f 100644
--- a/src/gallium/drivers/i915simple/i915_texture.h
+++ b/src/gallium/drivers/i915simple/i915_texture.h
@@ -1,17 +1,43 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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 I915_TEXTURE_H
#define I915_TEXTURE_H
-struct pipe_context;
-struct pipe_texture;
+struct i915_context;
+struct pipe_screen;
-struct pipe_texture *
-i915_texture_create(struct pipe_context *pipe,
- const struct pipe_texture *templat);
+extern void
+i915_init_texture_functions(struct i915_context *i915);
+
extern void
-i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+i915_init_screen_texture_functions(struct pipe_screen *screen);
#endif /* I915_TEXTURE_H */
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
index fe49710852..aea3003281 100644
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ b/src/gallium/drivers/i915simple/i915_winsys.h
@@ -40,6 +40,11 @@
#include "pipe/p_defines.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
/* Pipe drivers are (meant to be!) independent of both GL and the
* window system. The window system provides a buffer manager and a
* set of additional hooks for things like command buffer submission,
@@ -52,6 +57,7 @@
struct pipe_buffer;
struct pipe_winsys;
+struct pipe_screen;
/**
@@ -107,9 +113,12 @@ struct i915_winsys {
#define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
-struct pipe_context *i915_create( struct pipe_winsys *,
- struct i915_winsys *,
- unsigned pci_id );
+struct pipe_context *i915_create_context( struct pipe_screen *,
+ struct pipe_winsys *,
+ struct i915_winsys * );
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile
index 1dec1f9749..e97146e57c 100644
--- a/src/gallium/drivers/i965simple/Makefile
+++ b/src/gallium/drivers/i965simple/Makefile
@@ -1,14 +1,13 @@
-
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = i965simple
-DRIVER_SOURCES = \
- brw_blit.c \
- brw_flush.c \
- brw_strings.c \
- brw_surface.c \
+C_SOURCES = \
+ brw_blit.c \
+ brw_flush.c \
+ brw_screen.c \
+ brw_surface.c \
brw_cc.c \
brw_clip.c \
brw_clip_line.c \
@@ -31,8 +30,7 @@ DRIVER_SOURCES = \
brw_sf.c \
brw_sf_emit.c \
brw_sf_state.c \
- brw_shader_info.c \
- brw_state.c \
+ brw_state.c \
brw_state_batch.c \
brw_state_cache.c \
brw_state_pool.c \
@@ -51,16 +49,6 @@ DRIVER_SOURCES = \
brw_wm_state.c \
brw_wm_surface_state.c
-C_SOURCES = \
- $(COMMON_SOURCES) \
- $(COMMON_BM_SOURCES) \
- $(MINIGLX_SOURCES) \
- $(DRIVER_SOURCES)
-
-ASM_SOURCES =
-
-DRIVER_DEFINES = -I.
-
include ../../Makefile.template
symlinks:
diff --git a/src/gallium/drivers/i965simple/SConscript b/src/gallium/drivers/i965simple/SConscript
index 74621de84c..c0825c4de3 100644
--- a/src/gallium/drivers/i965simple/SConscript
+++ b/src/gallium/drivers/i965simple/SConscript
@@ -29,13 +29,11 @@ i965simple = env.ConvenienceLibrary(
'brw_sf.c',
'brw_sf_emit.c',
'brw_sf_state.c',
- 'brw_shader_info.c',
'brw_state.c',
'brw_state_batch.c',
'brw_state_cache.c',
'brw_state_pool.c',
'brw_state_upload.c',
- 'brw_strings.c',
'brw_surface.c',
'brw_tex_layout.c',
'brw_urb.c',
diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c
index 5e58701e91..7c908da672 100644
--- a/src/gallium/drivers/i965simple/brw_context.c
+++ b/src/gallium/drivers/i965simple/brw_context.c
@@ -40,15 +40,14 @@
#include "pipe/p_winsys.h"
#include "pipe/p_context.h"
#include "pipe/p_util.h"
+#include "pipe/p_screen.h"
-/***************************************
- * Mesa's Driver Functions
- ***************************************/
#ifndef BRW_DEBUG
int BRW_DEBUG = (0);
#endif
+
static void brw_destroy(struct pipe_context *pipe)
{
struct brw_context *brw = brw_context(pipe);
@@ -56,6 +55,7 @@ static void brw_destroy(struct pipe_context *pipe)
FREE(brw);
}
+
static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue)
{
@@ -71,164 +71,31 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps,
}
-static int
-brw_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
- case PIPE_CAP_NPOT_TEXTURES:
- return 1;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 0;
- case PIPE_CAP_POINT_SPRITE:
- return 0;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 1;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 0;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
- default:
- return 0;
- }
-}
-
-
-static float
-brw_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 7.5;
-
- case PIPE_CAP_MAX_POINT_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 255.0;
-
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 4.0;
-
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 16.0;
-
- default:
- return 0;
- }
-}
-
-static boolean
-brw_is_format_supported( struct pipe_context *pipe,
- enum pipe_format format, uint type )
-{
-#if 0
- /* XXX: This is broken -- rewrite if still needed. */
- static const unsigned tex_supported[] = {
- PIPE_FORMAT_U_R8_G8_B8_A8,
- PIPE_FORMAT_U_A8_R8_G8_B8,
- PIPE_FORMAT_U_R5_G6_B5,
- PIPE_FORMAT_U_L8,
- PIPE_FORMAT_U_A8,
- PIPE_FORMAT_U_I8,
- PIPE_FORMAT_U_L8_A8,
- PIPE_FORMAT_YCBCR,
- PIPE_FORMAT_YCBCR_REV,
- PIPE_FORMAT_S8_Z24,
- };
-
-
- /* Actually a lot more than this - add later:
- */
- static const unsigned render_supported[] = {
- PIPE_FORMAT_U_A8_R8_G8_B8,
- PIPE_FORMAT_U_R5_G6_B5,
- };
-
- /*
- */
- static const unsigned z_stencil_supported[] = {
- PIPE_FORMAT_U_Z16,
- PIPE_FORMAT_U_Z32,
- PIPE_FORMAT_S8_Z24,
- };
-
- switch (type) {
- case PIPE_RENDER_FORMAT:
- *numFormats = Elements(render_supported);
- return render_supported;
-
- case PIPE_TEX_FORMAT:
- *numFormats = Elements(tex_supported);
- return render_supported;
-
- case PIPE_Z_STENCIL_FORMAT:
- *numFormats = Elements(render_supported);
- return render_supported;
-
- default:
- *numFormats = 0;
- return NULL;
- }
-#else
- switch (format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_S8Z24_UNORM:
- return TRUE;
- default:
- return FALSE;
- };
- return FALSE;
-#endif
-}
-
-
-
-
-struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys,
+struct pipe_context *brw_create(struct pipe_screen *screen,
struct brw_winsys *brw_winsys,
unsigned pci_id)
{
struct brw_context *brw;
- pipe_winsys->printf(pipe_winsys,
- "%s: creating brw_context with pci id 0x%x\n",
- __FUNCTION__, pci_id);
+ screen->winsys->printf(screen->winsys,
+ "%s: creating brw_context with pci id 0x%x\n",
+ __FUNCTION__, pci_id);
brw = CALLOC_STRUCT(brw_context);
if (brw == NULL)
return NULL;
brw->winsys = brw_winsys;
- brw->pipe.winsys = pipe_winsys;
+ brw->pipe.winsys = screen->winsys;
+ brw->pipe.screen = screen;
brw->pipe.destroy = brw_destroy;
- brw->pipe.is_format_supported = brw_is_format_supported;
- brw->pipe.get_param = brw_get_param;
- brw->pipe.get_paramf = brw_get_paramf;
brw->pipe.clear = brw_clear;
- brw->pipe.texture_create = brw_texture_create;
- brw->pipe.texture_release = brw_texture_release;
brw_init_surface_functions(brw);
+ brw_init_texture_functions(brw);
brw_init_state_functions(brw);
brw_init_flush_functions(brw);
- brw_init_string_functions(brw);
brw_init_draw_functions( brw );
diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h
index 65664d853d..4da3a8cffc 100644
--- a/src/gallium/drivers/i965simple/brw_context.h
+++ b/src/gallium/drivers/i965simple/brw_context.h
@@ -38,6 +38,8 @@
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "tgsi/util/tgsi_scan.h"
+
#include "brw_structs.h"
#include "brw_winsys.h"
@@ -195,33 +197,22 @@ struct brw_state_flags {
};
-struct brw_shader_info {
- int nr_regs[8]; /* TGSI_FILE_* */
-};
-
-
-
struct brw_vertex_program {
struct pipe_shader_state program;
- struct brw_shader_info info;
+ struct tgsi_shader_info info;
int id;
};
-
struct brw_fragment_program {
struct pipe_shader_state program;
- struct brw_shader_info info;
+ struct tgsi_shader_info info;
- boolean UsesDepth;
- boolean UsesKill;
- boolean ComputesDepth;
+ boolean UsesDepth; /* XXX add this to tgsi_shader_info? */
int id;
};
-
-
struct pipe_setup_linkage {
struct {
unsigned vp_output:5;
@@ -502,7 +493,7 @@ struct brw_context
/* Arrays with buffer objects to copy non-bufferobj arrays into
* for upload:
*/
- struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX];
+ const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX];
struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX];
diff --git a/src/gallium/drivers/i965simple/brw_draw_upload.c b/src/gallium/drivers/i965simple/brw_draw_upload.c
index aa85d93866..9c0c78c236 100644
--- a/src/gallium/drivers/i965simple/brw_draw_upload.c
+++ b/src/gallium/drivers/i965simple/brw_draw_upload.c
@@ -256,7 +256,7 @@ boolean brw_upload_vertex_elements( struct brw_context *brw )
struct brw_vertex_element_packet vep;
unsigned i;
- unsigned nr_enabled = brw->attribs.VertexProgram->program.num_inputs;
+ unsigned nr_enabled = brw->attribs.VertexProgram->info.num_inputs;
memset(&vep, 0, sizeof(vep));
diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c
new file mode 100644
index 0000000000..5be369fe52
--- /dev/null
+++ b/src/gallium/drivers/i965simple/brw_screen.c
@@ -0,0 +1,235 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+
+#include "brw_context.h"
+#include "brw_screen.h"
+#include "brw_tex_layout.h"
+
+
+static const char *
+brw_get_vendor( struct pipe_screen *screen )
+{
+ return "Tungsten Graphics, Inc.";
+}
+
+
+static const char *
+brw_get_name( struct pipe_screen *screen )
+{
+ static char buffer[128];
+ const char *chipset;
+
+ switch (brw_screen(screen)->pci_id) {
+ case PCI_CHIP_I965_Q:
+ chipset = "Intel(R) 965Q";
+ break;
+ case PCI_CHIP_I965_G:
+ case PCI_CHIP_I965_G_1:
+ chipset = "Intel(R) 965G";
+ break;
+ case PCI_CHIP_I965_GM:
+ chipset = "Intel(R) 965GM";
+ break;
+ case PCI_CHIP_I965_GME:
+ chipset = "Intel(R) 965GME/GLE";
+ break;
+ default:
+ chipset = "unknown";
+ break;
+ }
+
+ sprintf(buffer, "i965 (chipset: %s)", chipset);
+ return buffer;
+}
+
+
+static int
+brw_get_param(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 8;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 0;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 0;
+ case PIPE_CAP_POINT_SPRITE:
+ return 0;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 1;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 0;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 11; /* max 1024x1024 */
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 8; /* max 128x128x128 */
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 11; /* max 1024x1024 */
+ default:
+ return 0;
+ }
+}
+
+
+static float
+brw_get_paramf(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 7.5;
+
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 255.0;
+
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 4.0;
+
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0;
+
+ default:
+ return 0;
+ }
+}
+
+
+static boolean
+brw_is_format_supported( struct pipe_screen *screen,
+ enum pipe_format format, uint type )
+{
+#if 0
+ /* XXX: This is broken -- rewrite if still needed. */
+ static const unsigned tex_supported[] = {
+ PIPE_FORMAT_U_R8_G8_B8_A8,
+ PIPE_FORMAT_U_A8_R8_G8_B8,
+ PIPE_FORMAT_U_R5_G6_B5,
+ PIPE_FORMAT_U_L8,
+ PIPE_FORMAT_U_A8,
+ PIPE_FORMAT_U_I8,
+ PIPE_FORMAT_U_L8_A8,
+ PIPE_FORMAT_YCBCR,
+ PIPE_FORMAT_YCBCR_REV,
+ PIPE_FORMAT_S8_Z24,
+ };
+
+
+ /* Actually a lot more than this - add later:
+ */
+ static const unsigned render_supported[] = {
+ PIPE_FORMAT_U_A8_R8_G8_B8,
+ PIPE_FORMAT_U_R5_G6_B5,
+ };
+
+ /*
+ */
+ static const unsigned z_stencil_supported[] = {
+ PIPE_FORMAT_U_Z16,
+ PIPE_FORMAT_U_Z32,
+ PIPE_FORMAT_S8_Z24,
+ };
+
+ switch (type) {
+ case PIPE_RENDER_FORMAT:
+ *numFormats = Elements(render_supported);
+ return render_supported;
+
+ case PIPE_TEX_FORMAT:
+ *numFormats = Elements(tex_supported);
+ return render_supported;
+
+ case PIPE_Z_STENCIL_FORMAT:
+ *numFormats = Elements(render_supported);
+ return render_supported;
+
+ default:
+ *numFormats = 0;
+ return NULL;
+ }
+#else
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ return TRUE;
+ default:
+ return FALSE;
+ };
+ return FALSE;
+#endif
+}
+
+
+static void
+brw_destroy_screen( struct pipe_screen *screen )
+{
+ FREE(screen);
+}
+
+
+/**
+ * Create a new brw_screen object
+ */
+struct pipe_screen *
+brw_create_screen(struct pipe_winsys *winsys, uint pci_id)
+{
+ struct brw_screen *brwscreen = CALLOC_STRUCT(brw_screen);
+
+ if (!brwscreen)
+ return NULL;
+
+ brwscreen->pci_id = pci_id;
+
+ brwscreen->screen.winsys = winsys;
+
+ brwscreen->screen.destroy = brw_destroy_screen;
+
+ brwscreen->screen.get_name = brw_get_name;
+ brwscreen->screen.get_vendor = brw_get_vendor;
+ brwscreen->screen.get_param = brw_get_param;
+ brwscreen->screen.get_paramf = brw_get_paramf;
+ brwscreen->screen.is_format_supported = brw_is_format_supported;
+
+ brw_init_screen_texture_funcs(&brwscreen->screen);
+
+ return &brwscreen->screen;
+}
diff --git a/src/gallium/drivers/i915simple/i915_strings.c b/src/gallium/drivers/i965simple/brw_screen.h
index 301fedea19..d3c70387e6 100644
--- a/src/gallium/drivers/i915simple/i915_strings.c
+++ b/src/gallium/drivers/i965simple/brw_screen.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,59 +25,44 @@
*
**************************************************************************/
-#include "i915_context.h"
-#include "i915_reg.h"
+#ifndef BRW_SCREEN_H
+#define BRW_SCREEN_H
-static const char *i915_get_vendor( struct pipe_context *pipe )
+
+#include "pipe/p_screen.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Subclass of pipe_screen
+ */
+struct brw_screen
{
- return "Tungsten Graphics, Inc.";
-}
+ struct pipe_screen screen;
+ uint pci_id;
+};
-static const char *i915_get_name( struct pipe_context *pipe )
+
+/** cast wrapper */
+static INLINE struct brw_screen *
+brw_screen(struct pipe_screen *pscreen)
{
- static char buffer[128];
- const char *chipset;
-
- switch (i915_context(pipe)->pci_id) {
- case PCI_CHIP_I915_G:
- chipset = "915G";
- break;
- case PCI_CHIP_I915_GM:
- chipset = "915GM";
- break;
- case PCI_CHIP_I945_G:
- chipset = "945G";
- break;
- case PCI_CHIP_I945_GM:
- chipset = "945GM";
- break;
- case PCI_CHIP_I945_GME:
- chipset = "945GME";
- break;
- case PCI_CHIP_G33_G:
- chipset = "G33";
- break;
- case PCI_CHIP_Q35_G:
- chipset = "Q35";
- break;
- case PCI_CHIP_Q33_G:
- chipset = "Q33";
- break;
- default:
- chipset = "unknown";
- break;
- }
-
- sprintf(buffer, "i915 (chipset: %s)", chipset);
- return buffer;
+ return (struct brw_screen *) pscreen;
}
-void
-i915_init_string_functions(struct i915_context *i915)
-{
- i915->pipe.get_name = i915_get_name;
- i915->pipe.get_vendor = i915_get_vendor;
+extern struct pipe_screen *
+brw_create_screen(struct pipe_winsys *winsys, uint pci_id);
+
+
+#ifdef __cplusplus
}
+#endif
+
+#endif /* BRW_SCREEN_H */
diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c
index 7c83b81c85..c3b815a82b 100644
--- a/src/gallium/drivers/i965simple/brw_sf.c
+++ b/src/gallium/drivers/i965simple/brw_sf.c
@@ -133,7 +133,7 @@ static void upload_sf_prog( struct brw_context *brw )
key.vp_output_count = brw->vs.prog_data->outputs_written;
/* BRW_NEW_FS */
- key.fp_input_count = brw->attribs.FragmentProgram->info.nr_regs[TGSI_FILE_INPUT];
+ key.fp_input_count = brw->attribs.FragmentProgram->info.file_max[TGSI_FILE_INPUT] + 1;
/* BRW_NEW_REDUCED_PRIMITIVE */
diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c
index a762a870fe..f4694a4433 100644
--- a/src/gallium/drivers/i965simple/brw_shader_info.c
+++ b/src/gallium/drivers/i965simple/brw_shader_info.c
@@ -6,8 +6,9 @@
#include "tgsi/util/tgsi_parse.h"
-
-
+/**
+ * XXX this obsolete new and no longer compiled.
+ */
void brw_shader_info(const struct tgsi_token *tokens,
struct brw_shader_info *info )
{
diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c
index f746d1cc57..6744a8aa4f 100644
--- a/src/gallium/drivers/i965simple/brw_state.c
+++ b/src/gallium/drivers/i965simple/brw_state.c
@@ -32,6 +32,7 @@
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/util/tgsi_dump.h"
@@ -174,8 +175,12 @@ static void * brw_create_fs_state(struct pipe_context *pipe,
brw_fp->program = *shader;
brw_fp->id = brw_context(pipe)->program_id++;
+ tgsi_scan_shader(shader->tokens, &brw_fp->info);
+
+#if 0
brw_shader_info(shader->tokens,
- &brw_fp->info);
+ &brw_fp->info2);
+#endif
tgsi_dump(shader->tokens, 0);
@@ -210,9 +215,13 @@ static void *brw_create_vs_state(struct pipe_context *pipe,
*/
brw_vp->program = *shader;
brw_vp->id = brw_context(pipe)->program_id++;
- brw_shader_info(shader->tokens,
- &brw_vp->info);
+ tgsi_scan_shader(shader->tokens, &brw_vp->info);
+
+#if 0
+ brw_shader_info(shader->tokens,
+ &brw_vp->info2);
+#endif
tgsi_dump(shader->tokens, 0);
return (void *)brw_vp;
@@ -327,7 +336,8 @@ static void brw_set_sampler_texture(struct pipe_context *pipe,
{
struct brw_context *brw = brw_context(pipe);
- brw->attribs.Texture[unit] = (struct brw_texture*)texture; /* ptr, not struct */
+ pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit],
+ texture);
brw->state.dirty.brw |= BRW_NEW_TEXTURE;
}
diff --git a/src/gallium/drivers/i965simple/brw_state.h b/src/gallium/drivers/i965simple/brw_state.h
index 258e9a556e..de0a6371b8 100644
--- a/src/gallium/drivers/i965simple/brw_state.h
+++ b/src/gallium/drivers/i965simple/brw_state.h
@@ -148,11 +148,4 @@ void brw_invalidate_pools( struct brw_context *brw );
void brw_clear_batch_cache_flush( struct brw_context *brw );
-/* brw_shader_info.c
- */
-
-void brw_shader_info(const struct tgsi_token *tokens,
- struct brw_shader_info *info );
-
-
#endif
diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c
index 376a42b1a6..c99a91dcf7 100644
--- a/src/gallium/drivers/i965simple/brw_surface.c
+++ b/src/gallium/drivers/i965simple/brw_surface.c
@@ -35,47 +35,6 @@
#include "util/p_tile.h"
-/*
- * XXX note: same as code in sp_surface.c
- */
-static struct pipe_surface *
-brw_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
-{
- struct brw_texture *tex = (struct brw_texture *)pt;
- struct pipe_surface *ps;
- unsigned offset; /* in bytes */
-
- offset = tex->level_offset[level];
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- offset += tex->image_offset[level][face] * pt->cpp;
- }
- else if (pt->target == PIPE_TEXTURE_3D) {
- offset += tex->image_offset[level][zslice] * pt->cpp;
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
-
- ps = pipe->winsys->surface_alloc(pipe->winsys);
- if (ps) {
- assert(ps->format);
- assert(ps->refcount);
- pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer);
- ps->format = pt->format;
- ps->cpp = pt->cpp;
- ps->width = pt->width[level];
- ps->height = pt->height[level];
- ps->pitch = tex->pitch;
- ps->offset = offset;
- }
- return ps;
-}
-
-
/* Upload data to a rectangular sub-region. Lots of choices how to do this:
*
* - memcpy by span to current destination
@@ -201,10 +160,11 @@ brw_surface_fill(struct pipe_context *pipe,
}
}
+
void
brw_init_surface_functions(struct brw_context *brw)
{
- brw->pipe.get_tex_surface = brw_get_tex_surface;
+ (void) brw_surface_data; /* silence warning */
brw->pipe.surface_copy = brw_surface_copy;
brw->pipe.surface_fill = brw_surface_fill;
}
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index 90561f1307..b24ac87c37 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -71,8 +71,6 @@ static unsigned minify( unsigned d )
}
-static boolean brw_miptree_layout(struct pipe_context *, struct brw_texture *);
-
static void intel_miptree_set_image_offset(struct brw_texture *tex,
unsigned level,
unsigned img,
@@ -199,7 +197,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
}
}
-static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture *tex)
+static boolean brw_miptree_layout(struct brw_texture *tex)
{
struct pipe_texture *pt = &tex->base;
/* XXX: these vary depending on image format:
@@ -300,19 +298,22 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture
}
-struct pipe_texture *
-brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat)
+static struct pipe_texture *
+brw_texture_create_screen(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
+ struct pipe_winsys *ws = screen->winsys;
struct brw_texture *tex = CALLOC_STRUCT(brw_texture);
if (tex) {
tex->base = *templat;
+ tex->base.refcount = 1;
- if (brw_miptree_layout(pipe, tex))
- tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex->pitch * tex->base.cpp *
- tex->total_height);
+ if (brw_miptree_layout(tex))
+ tex->buffer = ws->buffer_create(ws, 64,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->pitch * tex->base.cpp *
+ tex->total_height);
if (!tex->buffer) {
FREE(tex);
@@ -323,8 +324,10 @@ brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat
return &tex->base;
}
-void
-brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+
+static void
+brw_texture_release_screen(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -334,6 +337,7 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
*/
if (--(*pt)->refcount <= 0) {
+ struct pipe_winsys *ws = screen->winsys;
struct brw_texture *tex = (struct brw_texture *)*pt;
uint i;
@@ -341,7 +345,7 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
- pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL);
+ pipe_buffer_reference(ws, &tex->buffer, NULL);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i])
@@ -351,3 +355,66 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
}
*pt = NULL;
}
+
+
+static void
+brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture)
+{
+ /* no-op? */
+}
+
+
+static struct pipe_surface *
+brw_get_tex_surface_screen(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
+{
+ struct pipe_winsys *ws = screen->winsys;
+ struct brw_texture *tex = (struct brw_texture *)pt;
+ struct pipe_surface *ps;
+ unsigned offset; /* in bytes */
+
+ offset = tex->level_offset[level];
+
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ offset += tex->image_offset[level][face] * pt->cpp;
+ }
+ else if (pt->target == PIPE_TEXTURE_3D) {
+ offset += tex->image_offset[level][zslice] * pt->cpp;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+
+ ps = ws->surface_alloc(ws);
+ if (ps) {
+ assert(ps->format);
+ assert(ps->refcount);
+ pipe_buffer_reference(ws, &ps->buffer, tex->buffer);
+ ps->format = pt->format;
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = tex->pitch;
+ ps->offset = offset;
+ }
+ return ps;
+}
+
+
+void
+brw_init_texture_functions(struct brw_context *brw)
+{
+ brw->pipe.texture_update = brw_texture_update;
+}
+
+
+void
+brw_init_screen_texture_funcs(struct pipe_screen *screen)
+{
+ screen->texture_create = brw_texture_create_screen;
+ screen->texture_release = brw_texture_release_screen;
+ screen->get_tex_surface = brw_get_tex_surface_screen;
+}
+
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h
index cfd6b1ef3a..a6b6ba8146 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.h
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.h
@@ -1,15 +1,44 @@
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 BRW_TEX_LAYOUT_H
#define BRW_TEX_LAYOUT_H
-#include "pipe/p_compiler.h"
-struct pipe_context;
-struct pipe_texture;
+struct brw_context;
+struct pipe_screen;
+
-extern struct pipe_texture *
-brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat);
+extern void
+brw_init_texture_functions(struct brw_context *brw);
extern void
-brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+brw_init_screen_texture_funcs(struct pipe_screen *screen);
+
#endif
diff --git a/src/gallium/drivers/i965simple/brw_vs.c b/src/gallium/drivers/i965simple/brw_vs.c
index 738c6346d5..92327e896d 100644
--- a/src/gallium/drivers/i965simple/brw_vs.c
+++ b/src/gallium/drivers/i965simple/brw_vs.c
@@ -50,8 +50,8 @@ static void do_vs_prog( struct brw_context *brw,
brw_init_compile(&c.func);
c.vp = vp;
- c.prog_data.outputs_written = vp->program.num_outputs;
- c.prog_data.inputs_read = vp->program.num_inputs;
+ c.prog_data.outputs_written = vp->info.num_outputs;
+ c.prog_data.inputs_read = vp->info.num_inputs;
#if 0
if (c.key.copy_edgeflag) {
diff --git a/src/gallium/drivers/i965simple/brw_vs.h b/src/gallium/drivers/i965simple/brw_vs.h
index 0e58f043b0..070f9dfcae 100644
--- a/src/gallium/drivers/i965simple/brw_vs.h
+++ b/src/gallium/drivers/i965simple/brw_vs.h
@@ -52,7 +52,7 @@ struct brw_vs_compile {
struct brw_vs_prog_key key;
struct brw_vs_prog_data prog_data;
- struct brw_vertex_program *vp;
+ const struct brw_vertex_program *vp;
unsigned nr_inputs;
diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c
index 05df4860ed..9020fcc001 100644
--- a/src/gallium/drivers/i965simple/brw_vs_emit.c
+++ b/src/gallium/drivers/i965simple/brw_vs_emit.c
@@ -86,7 +86,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c,
/* Allocate input regs:
*/
- c->nr_inputs = c->vp->program.num_inputs;
+ c->nr_inputs = c->vp->info.num_inputs;
for (i = 0; i < c->nr_inputs; i++) {
c->regs[TGSI_FILE_INPUT][i] = brw_vec8_grf(reg, 0);
reg++;
@@ -99,7 +99,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c,
c->nr_outputs = 0;
c->first_output = reg;
mrf = 4;
- for (i = 0; i < c->vp->program.num_outputs; i++) {
+ for (i = 0; i < c->vp->info.num_outputs; i++) {
c->nr_outputs++;
#if 0
if (i == VERT_RESULT_HPOS) {
@@ -1051,7 +1051,7 @@ static void process_instruction(struct brw_vs_compile *c,
{
struct brw_reg args[3], dst;
struct brw_compile *p = &c->func;
- struct brw_indirect stack_index = brw_indirect(0, 0);
+ /*struct brw_indirect stack_index = brw_indirect(0, 0);*/
unsigned i;
unsigned index;
unsigned file;
diff --git a/src/gallium/drivers/i965simple/brw_winsys.h b/src/gallium/drivers/i965simple/brw_winsys.h
index 3523a58614..b67bd73750 100644
--- a/src/gallium/drivers/i965simple/brw_winsys.h
+++ b/src/gallium/drivers/i965simple/brw_winsys.h
@@ -53,6 +53,8 @@
struct pipe_buffer;
struct pipe_fence_handle;
struct pipe_winsys;
+struct pipe_screen;
+
/* The pipe driver currently understands the following chipsets:
*/
@@ -181,7 +183,7 @@ struct brw_winsys {
#define BRW_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
-struct pipe_context *brw_create(struct pipe_winsys *,
+struct pipe_context *brw_create(struct pipe_screen *,
struct brw_winsys *,
unsigned pci_id);
diff --git a/src/gallium/drivers/i965simple/brw_wm.c b/src/gallium/drivers/i965simple/brw_wm.c
index 539b170744..1c4b5b5ede 100644
--- a/src/gallium/drivers/i965simple/brw_wm.c
+++ b/src/gallium/drivers/i965simple/brw_wm.c
@@ -94,11 +94,11 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* Build the index for table lookup
*/
/* BRW_NEW_DEPTH_STENCIL */
- if (fp->UsesKill ||
+ if (fp->info.uses_kill ||
brw->attribs.DepthStencil->alpha.enabled)
lookup |= IZ_PS_KILL_ALPHATEST_BIT;
- if (fp->ComputesDepth)
+ if (fp->info.writes_z)
lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
if (brw->attribs.DepthStencil->depth.enabled)
diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c
index 97418a52e7..74ccfd494a 100644
--- a/src/gallium/drivers/i965simple/brw_wm_decl.c
+++ b/src/gallium/drivers/i965simple/brw_wm_decl.c
@@ -259,9 +259,12 @@ static void prealloc_reg(struct brw_wm_compile *c)
/* Then a copy of our part of the CURBE entry:
*/
{
- int nr_constants = c->fp->info.nr_regs[TGSI_FILE_CONSTANT];
+ int nr_constants = c->fp->info.file_max[TGSI_FILE_CONSTANT] + 1;
int index = 0;
+ /* XXX number of constants, or highest numbered constant? */
+ assert(nr_constants == c->fp->info.file_count[TGSI_FILE_CONSTANT]);
+
c->prog_data.max_const = 4*nr_constants;
for (i = 0; i < nr_constants; i++) {
for (j = 0; j < 4; j++, index++)
@@ -282,13 +285,14 @@ static void prealloc_reg(struct brw_wm_compile *c)
/* Next we receive the plane coefficients for parameter
* interpolation:
*/
- for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++) {
+ assert(c->fp->info.file_max[TGSI_FILE_INPUT] == c->fp->info.num_inputs);
+ for (i = 0; i < c->fp->info.file_max[TGSI_FILE_INPUT] + 1; i++) {
c->payload_coef[i] = brw_vec8_grf(c->reg_index, 0);
c->reg_index += 2;
}
c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
- c->prog_data.urb_read_length = (c->fp->program.num_inputs + 1) * 2;
+ c->prog_data.urb_read_length = (c->fp->info.num_inputs + 1) * 2;
c->prog_data.curb_read_length = nr_curbe_regs;
/* That's the end of the payload, now we can start allocating registers.
@@ -302,11 +306,17 @@ static void prealloc_reg(struct brw_wm_compile *c)
/* Now allocate room for the interpolated inputs and staging
* registers for the outputs:
*/
- for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++)
+ /* XXX do we want to loop over the _number_ of inputs/outputs or loop
+ * to the highest input/output index that's used?
+ * Probably the same, actually.
+ */
+ assert(c->fp->info.file_max[TGSI_FILE_INPUT] + 1 == c->fp->info.num_inputs);
+ assert(c->fp->info.file_max[TGSI_FILE_OUTPUT] + 1 == c->fp->info.num_outputs);
+ for (i = 0; i < c->fp->info.file_max[TGSI_FILE_INPUT] + 1; i++)
for (j = 0; j < 4; j++)
c->wm_regs[TGSI_FILE_INPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 );
- for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_OUTPUT]; i++)
+ for (i = 0; i < c->fp->info.file_max[TGSI_FILE_OUTPUT] + 1; i++)
for (j = 0; j < 4; j++)
c->wm_regs[TGSI_FILE_OUTPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 );
diff --git a/src/gallium/drivers/i965simple/brw_wm_state.c b/src/gallium/drivers/i965simple/brw_wm_state.c
index 5ccd488842..f3aa36b07f 100644
--- a/src/gallium/drivers/i965simple/brw_wm_state.c
+++ b/src/gallium/drivers/i965simple/brw_wm_state.c
@@ -117,11 +117,11 @@ static void upload_wm_unit(struct brw_context *brw )
if (fp->UsesDepth)
wm.wm5.program_uses_depth = 1; /* as far as we can tell */
- if (fp->ComputesDepth)
+ if (fp->info.writes_z)
wm.wm5.program_computes_depth = 1;
/* BRW_NEW_ALPHA_TEST */
- if (fp->UsesKill ||
+ if (fp->info.uses_kill ||
brw->attribs.DepthStencil->alpha.enabled)
wm.wm5.program_uses_killpixel = 1;
diff --git a/src/gallium/drivers/nouveau/nouveau_class.h b/src/gallium/drivers/nouveau/nouveau_class.h
index 5998945677..c80461038b 100644
--- a/src/gallium/drivers/nouveau/nouveau_class.h
+++ b/src/gallium/drivers/nouveau/nouveau_class.h
@@ -4926,9 +4926,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV40TCL_VIEWPORT_SCALE_Y 0x00000a34
#define NV40TCL_VIEWPORT_SCALE_Z 0x00000a38
#define NV40TCL_VIEWPORT_SCALE_W 0x00000a3c
-#define NV40TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a60
+#define NV40TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a60
#define NV40TCL_POLYGON_OFFSET_LINE_ENABLE 0x00000a64
-#define NV40TCL_POLYGON_OFFSET_POINT_ENABLE 0x00000a68
+#define NV40TCL_POLYGON_OFFSET_FILL_ENABLE 0x00000a68
#define NV40TCL_DEPTH_FUNC 0x00000a6c
#define NV40TCL_DEPTH_FUNC_NEVER 0x00000200
#define NV40TCL_DEPTH_FUNC_LESS 0x00000201
diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h
index 07c31b014a..439c7e4734 100644
--- a/src/gallium/drivers/nouveau/nouveau_stateobj.h
+++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h
@@ -32,7 +32,7 @@ so_new(unsigned push, unsigned reloc)
struct nouveau_stateobj *so;
so = MALLOC(sizeof(struct nouveau_stateobj));
- so->refcount = 1;
+ so->refcount = 0;
so->push = MALLOC(sizeof(unsigned) * push);
so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc);
@@ -45,22 +45,19 @@ so_new(unsigned push, unsigned reloc)
static INLINE void
so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso)
{
- struct nouveau_stateobj *so;
-
- so = *pso;
- if (so) {
- if (--so->refcount <= 0) {
- free(so->push);
- free(so->reloc);
- free(so);
- }
- *pso = NULL;
- }
+ struct nouveau_stateobj *so = *pso;
if (ref) {
ref->refcount++;
- *pso = ref;
}
+
+ if (so && --so->refcount <= 0) {
+ free(so->push);
+ free(so->reloc);
+ free(so);
+ }
+
+ *pso = ref;
}
static INLINE void
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index b5e470cfaa..44c8bb919b 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -49,13 +49,25 @@ struct nouveau_winsys {
unsigned, unsigned, unsigned, unsigned, unsigned);
};
+extern struct pipe_screen *
+nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
+ unsigned chipset);
+
extern struct pipe_context *
-nv30_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset);
+nv30_create(struct pipe_screen *, unsigned pctx_id);
+
+extern struct pipe_screen *
+nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
+ unsigned chipset);
extern struct pipe_context *
-nv40_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset);
+nv40_create(struct pipe_screen *, unsigned pctx_id);
+
+extern struct pipe_screen *
+nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
+ unsigned chipset);
extern struct pipe_context *
-nv50_create(struct pipe_winsys *, struct nouveau_winsys *, unsigned chipset);
+nv50_create(struct pipe_screen *, unsigned pctx_id);
#endif
diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile
index b7c252fc98..3f80fb87c9 100644
--- a/src/gallium/drivers/nv30/Makefile
+++ b/src/gallium/drivers/nv30/Makefile
@@ -11,6 +11,7 @@ DRIVER_SOURCES = \
nv30_fragtex.c \
nv30_miptree.c \
nv30_query.c \
+ nv30_screen.c \
nv30_state.c \
nv30_state_emit.c \
nv30_surface.c \
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
index e9afeb8017..28d3f057cc 100644
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ b/src/gallium/drivers/nv30/nv30_context.c
@@ -4,80 +4,7 @@
#include "pipe/p_util.h"
#include "nv30_context.h"
-
-static const char *
-nv30_get_name(struct pipe_context *pipe)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", nv30->chipset);
- return buffer;
-}
-
-static const char *
-nv30_get_vendor(struct pipe_context *pipe)
-{
- return "nouveau";
-}
-
-static int
-nv30_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 16;
- case PIPE_CAP_NPOT_TEXTURES:
- return 0;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 1;
- case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 2;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13;
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 10;
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0;
- }
-}
-
-static float
-nv30_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 10.0;
- case PIPE_CAP_MAX_POINT_WIDTH:
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 64.0;
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 16.0;
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 4.0;
- case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
- return 0.0;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0.0;
- }
-}
+#include "nv30_screen.h"
static void
nv30_flush(struct pipe_context *pipe, unsigned flags)
@@ -338,9 +265,11 @@ nv30_init_hwctx(struct nv30_context *nv30, int rankine_class)
#define NV35TCL_CHIPSET_3X_MASK 0x000001e0
struct pipe_context *
-nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
- unsigned chipset)
+nv30_create(struct pipe_screen *screen, unsigned pctx_id)
{
+ struct pipe_winsys *pipe_winsys = screen->winsys;
+ struct nouveau_winsys *nvws = nv30_screen(screen)->nvws;
+ unsigned chipset = nv30_screen(screen)->chipset;
struct nv30_context *nv30;
int rankine_class = 0, ret;
@@ -404,12 +333,9 @@ nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
/* Pipe context setup */
nv30->pipe.winsys = pipe_winsys;
+ nv30->pipe.screen = screen;
nv30->pipe.destroy = nv30_destroy;
- nv30->pipe.get_name = nv30_get_name;
- nv30->pipe.get_vendor = nv30_get_vendor;
- nv30->pipe.get_param = nv30_get_param;
- nv30->pipe.get_paramf = nv30_get_paramf;
nv30->pipe.draw_arrays = nv30_draw_arrays;
nv30->pipe.draw_elements = nv30_draw_elements;
@@ -420,7 +346,6 @@ nv30_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
nv30_init_query_functions(nv30);
nv30_init_surface_functions(nv30);
nv30_init_state_functions(nv30);
- nv30_init_miptree_functions(nv30);
nv30->draw = draw_create();
assert(nv30->draw);
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index d6d16ee868..c63847a087 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -91,7 +91,7 @@ nv30_context(struct pipe_context *pipe)
extern void nv30_init_state_functions(struct nv30_context *nv30);
extern void nv30_init_surface_functions(struct nv30_context *nv30);
-extern void nv30_init_miptree_functions(struct nv30_context *nv30);
+extern void nv30_init_miptree_functions(struct pipe_screen *screen);
extern void nv30_init_query_functions(struct nv30_context *nv30);
/* nv30_draw.c */
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index 5fb89f4cfd..23bcef08eb 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -4,6 +4,7 @@
#include "pipe/p_inlines.h"
#include "nv30_context.h"
+#include "nv30_screen.h"
static void
nv30_miptree_layout(struct nv30_miptree *nv30mt)
@@ -54,9 +55,9 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
}
static void
-nv30_miptree_create(struct pipe_context *pipe, struct pipe_texture **pt)
+nv30_miptree_create(struct pipe_screen *screen, struct pipe_texture **pt)
{
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_winsys *ws = screen->winsys;
struct nv30_miptree *nv30mt;
nv30mt = realloc(*pt, sizeof(struct nv30_miptree));
@@ -77,9 +78,9 @@ nv30_miptree_create(struct pipe_context *pipe, struct pipe_texture **pt)
}
static void
-nv30_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt)
+nv30_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt)
{
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_winsys *ws = screen->winsys;
struct pipe_texture *mt = *pt;
*pt = NULL;
@@ -96,10 +97,42 @@ nv30_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt)
}
}
+static struct pipe_surface *
+nv30_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
+{
+ struct pipe_winsys *ws = screen->winsys;
+ struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt;
+ struct pipe_surface *ps;
+
+ ps = ws->surface_alloc(ws);
+ if (!ps)
+ return NULL;
+ pipe_buffer_reference(ws, &ps->buffer, nv30mt->buffer);
+ ps->format = pt->format;
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = nv30mt->level[level].pitch / ps->cpp;
+
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ ps->offset = nv30mt->level[level].image_offset[face];
+ } else
+ if (pt->target == PIPE_TEXTURE_3D) {
+ ps->offset = nv30mt->level[level].image_offset[zslice];
+ } else {
+ ps->offset = nv30mt->level[level].image_offset[0];
+ }
+
+ return ps;
+}
void
-nv30_init_miptree_functions(struct nv30_context *nv30)
+nv30_init_miptree_functions(struct pipe_screen *screen)
{
- nv30->pipe.texture_create = nv30_miptree_create;
- nv30->pipe.texture_release = nv30_miptree_release;
+ struct nv30_screen *nv30screen = nv30_screen(screen);
+
+ nv30screen->screen.texture_create = nv30_miptree_create;
+ nv30screen->screen.texture_release = nv30_miptree_release;
+ nv30screen->screen.get_tex_surface = nv30_miptree_surface_get;
}
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
new file mode 100644
index 0000000000..39f2ac1af5
--- /dev/null
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -0,0 +1,153 @@
+#include "pipe/p_screen.h"
+#include "pipe/p_util.h"
+
+#include "nv30_context.h"
+#include "nv30_screen.h"
+
+static const char *
+nv30_screen_get_name(struct pipe_screen *screen)
+{
+ struct nv30_screen *nv30screen = nv30_screen(screen);
+ static char buffer[128];
+
+ snprintf(buffer, sizeof(buffer), "NV%02X", nv30screen->chipset);
+ return buffer;
+}
+
+static const char *
+nv30_screen_get_vendor(struct pipe_screen *screen)
+{
+ return "nouveau";
+}
+
+static int
+nv30_screen_get_param(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 16;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 0;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 0;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 1;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 2;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 13;
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 10;
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 13;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0;
+ }
+}
+
+static float
+nv30_screen_get_paramf(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 10.0;
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 64.0;
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 16.0;
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 4.0;
+ case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
+ return 0.0;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0.0;
+ }
+}
+
+static boolean
+nv30_screen_is_format_supported(struct pipe_screen *screen,
+ enum pipe_format format, uint type)
+{
+ switch (type) {
+ case PIPE_SURFACE:
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ return TRUE;
+ default:
+ break;
+ }
+ break;
+ case PIPE_TEXTURE:
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_U_L8:
+ case PIPE_FORMAT_U_A8:
+ case PIPE_FORMAT_U_I8:
+ case PIPE_FORMAT_U_A8_L8:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ return TRUE;
+ default:
+ break;
+ }
+ break;
+ default:
+ assert(0);
+ };
+
+ return FALSE;
+}
+
+static void
+nv30_screen_destroy(struct pipe_screen *screen)
+{
+ FREE(screen);
+}
+
+struct pipe_screen *
+nv30_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws,
+ unsigned chipset)
+{
+ struct nv30_screen *nv30screen = CALLOC_STRUCT(nv30_screen);
+
+ if (!nv30screen)
+ return NULL;
+
+ nv30screen->chipset = chipset;
+ nv30screen->nvws = nvws;
+
+ nv30screen->screen.winsys = winsys;
+
+ nv30screen->screen.destroy = nv30_screen_destroy;
+
+ nv30screen->screen.get_name = nv30_screen_get_name;
+ nv30screen->screen.get_vendor = nv30_screen_get_vendor;
+ nv30screen->screen.get_param = nv30_screen_get_param;
+ nv30screen->screen.get_paramf = nv30_screen_get_paramf;
+ nv30screen->screen.is_format_supported =
+ nv30_screen_is_format_supported;
+
+ nv30_init_miptree_functions(&nv30screen->screen);
+ return &nv30screen->screen;
+}
+
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
new file mode 100644
index 0000000000..f878f81e11
--- /dev/null
+++ b/src/gallium/drivers/nv30/nv30_screen.h
@@ -0,0 +1,19 @@
+#ifndef __NV30_SCREEN_H__
+#define __NV30_SCREEN_H__
+
+#include "pipe/p_screen.h"
+
+struct nv30_screen {
+ struct pipe_screen screen;
+
+ struct nouveau_winsys *nvws;
+ unsigned chipset;
+};
+
+static INLINE struct nv30_screen *
+nv30_screen(struct pipe_screen *screen)
+{
+ return (struct nv30_screen *)screen;
+}
+
+#endif
diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c
index 974965679f..b20a3dd4c1 100644
--- a/src/gallium/drivers/nv30/nv30_surface.c
+++ b/src/gallium/drivers/nv30/nv30_surface.c
@@ -33,76 +33,6 @@
#include "pipe/p_inlines.h"
#include "util/p_tile.h"
-static boolean
-nv30_surface_format_supported(struct pipe_context *pipe,
- enum pipe_format format, uint type)
-{
- switch (type) {
- case PIPE_SURFACE:
- switch (format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- return TRUE;
- default:
- break;
- }
- break;
- case PIPE_TEXTURE:
- switch (format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_A1R5G5B5_UNORM:
- case PIPE_FORMAT_A4R4G4B4_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_U_L8:
- case PIPE_FORMAT_U_A8:
- case PIPE_FORMAT_U_I8:
- case PIPE_FORMAT_U_A8_L8:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- return TRUE;
- default:
- break;
- }
- break;
- default:
- assert(0);
- };
-
- return FALSE;
-}
-
-static struct pipe_surface *
-nv30_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
-{
- struct pipe_winsys *ws = pipe->winsys;
- struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt;
- struct pipe_surface *ps;
-
- ps = ws->surface_alloc(ws);
- if (!ps)
- return NULL;
- pipe_buffer_reference(ws, &ps->buffer, nv30mt->buffer);
- ps->format = pt->format;
- ps->cpp = pt->cpp;
- ps->width = pt->width[level];
- ps->height = pt->height[level];
- ps->pitch = nv30mt->level[level].pitch / ps->cpp;
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- ps->offset = nv30mt->level[level].image_offset[face];
- } else
- if (pt->target == PIPE_TEXTURE_3D) {
- ps->offset = nv30mt->level[level].image_offset[zslice];
- } else {
- ps->offset = nv30mt->level[level].image_offset[0];
- }
-
- return ps;
-}
-
static void
nv30_surface_copy(struct pipe_context *pipe, unsigned do_flip,
struct pipe_surface *dest, unsigned destx, unsigned desty,
@@ -130,8 +60,6 @@ nv30_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
void
nv30_init_surface_functions(struct nv30_context *nv30)
{
- nv30->pipe.is_format_supported = nv30_surface_format_supported;
- nv30->pipe.get_tex_surface = nv30_get_tex_surface;
nv30->pipe.surface_copy = nv30_surface_copy;
nv30->pipe.surface_fill = nv30_surface_fill;
}
diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile
index 2a9de4a2dc..3369a21574 100644
--- a/src/gallium/drivers/nv40/Makefile
+++ b/src/gallium/drivers/nv40/Makefile
@@ -11,8 +11,17 @@ DRIVER_SOURCES = \
nv40_fragtex.c \
nv40_miptree.c \
nv40_query.c \
+ nv40_screen.c \
nv40_state.c \
+ nv40_state_blend.c \
+ nv40_state_clip.c \
nv40_state_emit.c \
+ nv40_state_fb.c \
+ nv40_state_rasterizer.c \
+ nv40_state_scissor.c \
+ nv40_state_stipple.c \
+ nv40_state_viewport.c \
+ nv40_state_zsa.c \
nv40_surface.c \
nv40_vbo.c \
nv40_vertprog.c
diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c
index 8b5cc693de..203c843a01 100644
--- a/src/gallium/drivers/nv40/nv40_context.c
+++ b/src/gallium/drivers/nv40/nv40_context.c
@@ -4,84 +4,7 @@
#include "pipe/p_util.h"
#include "nv40_context.h"
-
-#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf
-#define NV4X_GRCLASS4497_CHIPSETS 0x00005450
-#define NV6X_GRCLASS4497_CHIPSETS 0x00000088
-
-static const char *
-nv40_get_name(struct pipe_context *pipe)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", nv40->chipset);
- return buffer;
-}
-
-static const char *
-nv40_get_vendor(struct pipe_context *pipe)
-{
- return "nouveau";
-}
-
-static int
-nv40_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 16;
- case PIPE_CAP_NPOT_TEXTURES:
- return 1;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 1;
- case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 4;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13;
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 10;
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0;
- }
-}
-
-static float
-nv40_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 10.0;
- case PIPE_CAP_MAX_POINT_WIDTH:
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 64.0;
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 16.0;
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 16.0;
- case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
- return 0.0;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0.0;
- }
-}
+#include "nv40_screen.h"
static void
nv40_flush(struct pipe_context *pipe, unsigned flags)
@@ -97,7 +20,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags)
}
if (flags & PIPE_FLUSH_WAIT) {
- nvws->notifier_reset(nv40->hw->sync, 0);
+ nvws->notifier_reset(nv40->screen->sync, 0);
BEGIN_RING(curie, 0x104, 1);
OUT_RING (0);
BEGIN_RING(curie, 0x100, 1);
@@ -107,149 +30,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags)
FIRE_RING();
if (flags & PIPE_FLUSH_WAIT)
- nvws->notifier_wait(nv40->hw->sync, 0, 0, 2000);
-}
-
-static void
-nv40_channel_takedown(struct nv40_channel_context *cnv40)
-{
- struct nouveau_winsys *nvws = cnv40->nvws;
-
- nvws->res_free(&cnv40->vp_exec_heap);
- nvws->res_free(&cnv40->vp_data_heap);
- nvws->res_free(&cnv40->query_heap);
- nvws->notifier_free(&cnv40->query);
- nvws->notifier_free(&cnv40->sync);
- nvws->grobj_free(&cnv40->curie);
- free(cnv40);
-}
-
-static struct nv40_channel_context *
-nv40_channel_init(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
- unsigned chipset)
-{
- struct nv40_channel_context *cnv40 = NULL;
- struct nouveau_stateobj *so;
- unsigned curie_class = 0;
- int ret;
-
- switch (chipset & 0xf0) {
- case 0x40:
- if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f)))
- curie_class = NV40TCL;
- else
- if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f)))
- curie_class = NV44TCL;
- break;
- case 0x60:
- if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f)))
- curie_class = NV44TCL;
- break;
- default:
- break;
- }
-
- if (!curie_class) {
- NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset);
- return NULL;
- }
-
- cnv40 = CALLOC(1, sizeof(struct nv40_channel_context));
- if (!cnv40)
- return NULL;
- cnv40->chipset = chipset;
- cnv40->nvws = nvws;
-
- /* Notifier for sync purposes */
- ret = nvws->notifier_alloc(nvws, 1, &cnv40->sync);
- if (ret) {
- NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv40_channel_takedown(cnv40);
- return NULL;
- }
-
- /* Query objects */
- ret = nvws->notifier_alloc(nvws, 32, &cnv40->query);
- if (ret) {
- NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
- nv40_channel_takedown(cnv40);
- return NULL;
- }
-
- ret = nvws->res_init(&cnv40->query_heap, 0, 32);
- if (ret) {
- NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
- nv40_channel_takedown(cnv40);
- return NULL;
- }
-
- /* Vtxprog resources */
- if (nvws->res_init(&cnv40->vp_exec_heap, 0, 512) ||
- nvws->res_init(&cnv40->vp_data_heap, 0, 256)) {
- nv40_channel_takedown(cnv40);
- return NULL;
- }
-
- /* 3D object */
- ret = nvws->grobj_alloc(nvws, curie_class, &cnv40->curie);
- if (ret) {
- NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
- return FALSE;
- }
-
- /* Static curie initialisation */
- so = so_new(128, 0);
- so_method(so, cnv40->curie, NV40TCL_DMA_NOTIFY, 1);
- so_data (so, cnv40->sync->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_TEXTURE0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->gart->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_COLOR1, 1);
- so_data (so, nvws->channel->vram->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_COLOR0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_VTXBUF0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->gart->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_FENCE, 2);
- so_data (so, 0);
- so_data (so, cnv40->query->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_UNK01AC, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
- so_method(so, cnv40->curie, NV40TCL_DMA_COLOR2, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
-
- so_method(so, cnv40->curie, 0x1ea4, 3);
- so_data (so, 0x00000010);
- so_data (so, 0x01000100);
- so_data (so, 0xff800006);
-
- /* vtxprog output routing */
- so_method(so, cnv40->curie, 0x1fc4, 1);
- so_data (so, 0x06144321);
- so_method(so, cnv40->curie, 0x1fc8, 2);
- so_data (so, 0xedcba987);
- so_data (so, 0x00000021);
- so_method(so, cnv40->curie, 0x1fd0, 1);
- so_data (so, 0x00171615);
- so_method(so, cnv40->curie, 0x1fd4, 1);
- so_data (so, 0x001b1a19);
-
- so_method(so, cnv40->curie, 0x1ef8, 1);
- so_data (so, 0x0020ffff);
- so_method(so, cnv40->curie, 0x1d64, 1);
- so_data (so, 0x00d30000);
- so_method(so, cnv40->curie, 0x1e94, 1);
- so_data (so, 0x00000001);
-
- so_emit(nvws, so);
- so_ref(NULL, &so);
- nvws->push_flush(nvws->channel, 0);
-
- return cnv40;
+ nvws->notifier_wait(nv40->screen->sync, 0, 0, 2000);
}
static void
@@ -259,40 +40,30 @@ nv40_destroy(struct pipe_context *pipe)
if (nv40->draw)
draw_destroy(nv40->draw);
-
- if (nv40->hw) {
- if (--nv40->hw->refcount == 0)
- nv40_channel_takedown(nv40->hw);
- }
-
free(nv40);
}
struct pipe_context *
-nv40_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
- unsigned chipset)
+nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
+ struct nv40_screen *screen = nv40_screen(pscreen);
+ struct pipe_winsys *ws = pscreen->winsys;
struct nv40_context *nv40;
+ unsigned chipset = screen->chipset;
+ struct nouveau_winsys *nvws = screen->nvws;
nv40 = CALLOC(1, sizeof(struct nv40_context));
if (!nv40)
return NULL;
-
- nv40->hw = nv40_channel_init(ws, nvws, chipset);
- if (!nv40->hw) {
- nv40_destroy(&nv40->pipe);
- return NULL;
- }
+ nv40->screen = screen;
+ nv40->pctx_id = pctx_id;
nv40->chipset = chipset;
nv40->nvws = nvws;
nv40->pipe.winsys = ws;
+ nv40->pipe.screen = pscreen;
nv40->pipe.destroy = nv40_destroy;
- nv40->pipe.get_name = nv40_get_name;
- nv40->pipe.get_vendor = nv40_get_vendor;
- nv40->pipe.get_param = nv40_get_param;
- nv40->pipe.get_paramf = nv40_get_paramf;
nv40->pipe.draw_arrays = nv40_draw_arrays;
nv40->pipe.draw_elements = nv40_draw_elements;
nv40->pipe.clear = nv40_clear;
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index f511759e3b..e118776306 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -11,7 +11,7 @@
#include "nouveau/nouveau_gldefs.h"
#define NOUVEAU_PUSH_CONTEXT(ctx) \
- struct nv40_channel_context *ctx = nv40->hw
+ struct nv40_screen *ctx = nv40->screen
#include "nouveau/nouveau_push.h"
#include "nouveau/nouveau_stateobj.h"
@@ -22,6 +22,45 @@
#define NOUVEAU_MSG(fmt, args...) \
fprintf(stderr, "nouveau: "fmt, ##args);
+enum nv40_state_index {
+ NV40_STATE_FB = 0,
+ NV40_STATE_VIEWPORT = 1,
+ NV40_STATE_BLEND = 2,
+ NV40_STATE_RAST = 3,
+ NV40_STATE_ZSA = 4,
+ NV40_STATE_BCOL = 5,
+ NV40_STATE_CLIP = 6,
+ NV40_STATE_SCISSOR = 7,
+ NV40_STATE_STIPPLE = 8,
+ NV40_STATE_FRAGPROG = 9,
+ NV40_STATE_VERTPROG = 10,
+ NV40_STATE_FRAGTEX0 = 11,
+ NV40_STATE_FRAGTEX1 = 12,
+ NV40_STATE_FRAGTEX2 = 13,
+ NV40_STATE_FRAGTEX3 = 14,
+ NV40_STATE_FRAGTEX4 = 15,
+ NV40_STATE_FRAGTEX5 = 16,
+ NV40_STATE_FRAGTEX6 = 17,
+ NV40_STATE_FRAGTEX7 = 18,
+ NV40_STATE_FRAGTEX8 = 19,
+ NV40_STATE_FRAGTEX9 = 20,
+ NV40_STATE_FRAGTEX10 = 21,
+ NV40_STATE_FRAGTEX11 = 22,
+ NV40_STATE_FRAGTEX12 = 23,
+ NV40_STATE_FRAGTEX13 = 24,
+ NV40_STATE_FRAGTEX14 = 25,
+ NV40_STATE_FRAGTEX15 = 26,
+ NV40_STATE_VERTTEX0 = 27,
+ NV40_STATE_VERTTEX1 = 28,
+ NV40_STATE_VERTTEX2 = 29,
+ NV40_STATE_VERTTEX3 = 30,
+ NV40_STATE_VTXBUF = 31,
+ NV40_STATE_VTXFMT = 32,
+ NV40_STATE_MAX = 33
+};
+
+#include "nv40_screen.h"
+
#define NV40_NEW_BLEND (1 << 0)
#define NV40_NEW_RAST (1 << 1)
#define NV40_NEW_ZSA (1 << 2)
@@ -34,68 +73,70 @@
#define NV40_NEW_VERTPROG (1 << 9)
#define NV40_NEW_FRAGPROG (1 << 10)
#define NV40_NEW_ARRAYS (1 << 11)
+#define NV40_NEW_UCP (1 << 12)
-struct nv40_channel_context {
- struct nouveau_winsys *nvws;
- unsigned refcount;
+#define NV40_FALLBACK_TNL (1 << 0)
+#define NV40_FALLBACK_RAST (1 << 1)
+
+struct nv40_rasterizer_state {
+ struct pipe_rasterizer_state pipe;
+ struct nouveau_stateobj *so;
+};
- unsigned chipset;
+struct nv40_zsa_state {
+ struct pipe_depth_stencil_alpha_state pipe;
+ struct nouveau_stateobj *so;
+};
+
+struct nv40_blend_state {
+ struct pipe_blend_state pipe;
+ struct nouveau_stateobj *so;
+};
- /* HW graphics objects */
- struct nouveau_grobj *curie;
- struct nouveau_notifier *sync;
- /* Query object resources */
- struct nouveau_notifier *query;
- struct nouveau_resource *query_heap;
+struct nv40_state {
+ unsigned scissor_enabled;
+ unsigned stipple_enabled;
+ unsigned fp_samplers;
- /* Vtxprog resources */
- struct nouveau_resource *vp_exec_heap;
- struct nouveau_resource *vp_data_heap;
+ uint64_t dirty;
+ struct nouveau_stateobj *hw[NV40_STATE_MAX];
};
struct nv40_context {
struct pipe_context pipe;
+
struct nouveau_winsys *nvws;
+ struct nv40_screen *screen;
+ unsigned pctx_id;
- struct nv40_channel_context *hw;
struct draw_context *draw;
int chipset;
- uint32_t dirty;
-
+ /* HW state derived from pipe states */
+ struct nv40_state state;
+ unsigned fallback;
+
+ /* Context state */
+ unsigned dirty;
+ struct pipe_scissor_state scissor;
+ unsigned stipple[32];
+ struct pipe_clip_state clip;
+ struct nv40_vertex_program *vertprog;
+ struct nv40_fragment_program *fragprog;
+ struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
+ struct nv40_rasterizer_state *rasterizer;
+ struct nv40_zsa_state *zsa;
+ struct nv40_blend_state *blend;
+ struct pipe_blend_color blend_colour;
+ struct pipe_viewport_state viewport;
+ struct pipe_framebuffer_state framebuffer;
+ struct pipe_buffer *idxbuf;
+ unsigned idxbuf_format;
struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
unsigned dirty_samplers;
- unsigned fp_samplers;
- unsigned vp_samplers;
-
- struct nouveau_stateobj *so_framebuffer;
- struct nouveau_stateobj *so_fragtex[16];
- struct nouveau_stateobj *so_vtxbuf;
- struct nouveau_stateobj *so_blend;
- struct nouveau_stateobj *so_rast;
- struct nouveau_stateobj *so_zsa;
- struct nouveau_stateobj *so_bcol;
- struct nouveau_stateobj *so_scissor;
- struct nouveau_stateobj *so_viewport;
- struct nouveau_stateobj *so_stipple;
-
- struct {
- struct nv40_vertex_program *active;
-
- struct nv40_vertex_program *current;
- struct pipe_buffer *constant_buf;
- } vertprog;
-
- struct {
- struct nv40_fragment_program *active;
-
- struct nv40_fragment_program *current;
- struct pipe_buffer *constant_buf;
- } fragprog;
-
struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX];
};
@@ -106,27 +147,29 @@ nv40_context(struct pipe_context *pipe)
return (struct nv40_context *)pipe;
}
+struct nv40_state_entry {
+ boolean (*validate)(struct nv40_context *nv40);
+ struct {
+ unsigned pipe;
+ unsigned hw;
+ } dirty;
+};
+
extern void nv40_init_state_functions(struct nv40_context *nv40);
extern void nv40_init_surface_functions(struct nv40_context *nv40);
extern void nv40_init_miptree_functions(struct nv40_context *nv40);
extern void nv40_init_query_functions(struct nv40_context *nv40);
+extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen);
+
/* nv40_draw.c */
extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40);
/* nv40_vertprog.c */
-extern void nv40_vertprog_translate(struct nv40_context *,
- struct nv40_vertex_program *);
-extern void nv40_vertprog_bind(struct nv40_context *,
- struct nv40_vertex_program *);
extern void nv40_vertprog_destroy(struct nv40_context *,
struct nv40_vertex_program *);
/* nv40_fragprog.c */
-extern void nv40_fragprog_translate(struct nv40_context *,
- struct nv40_fragment_program *);
-extern void nv40_fragprog_bind(struct nv40_context *,
- struct nv40_fragment_program *);
extern void nv40_fragprog_destroy(struct nv40_context *,
struct nv40_fragment_program *);
@@ -136,6 +179,19 @@ extern void nv40_fragtex_bind(struct nv40_context *);
/* nv40_state.c and friends */
extern void nv40_emit_hw_state(struct nv40_context *nv40);
extern void nv40_state_tex_update(struct nv40_context *nv40);
+extern struct nv40_state_entry nv40_state_clip;
+extern struct nv40_state_entry nv40_state_rasterizer;
+extern struct nv40_state_entry nv40_state_scissor;
+extern struct nv40_state_entry nv40_state_stipple;
+extern struct nv40_state_entry nv40_state_fragprog;
+extern struct nv40_state_entry nv40_state_vertprog;
+extern struct nv40_state_entry nv40_state_blend;
+extern struct nv40_state_entry nv40_state_blend_colour;
+extern struct nv40_state_entry nv40_state_zsa;
+extern struct nv40_state_entry nv40_state_viewport;
+extern struct nv40_state_entry nv40_state_framebuffer;
+extern struct nv40_state_entry nv40_state_fragtex;
+extern struct nv40_state_entry nv40_state_vbo;
/* nv40_vbo.c */
extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode,
diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c
index 07a418c1e9..3c4ea7e99e 100644
--- a/src/gallium/drivers/nv40/nv40_fragprog.c
+++ b/src/gallium/drivers/nv40/nv40_fragprog.c
@@ -668,7 +668,7 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc,
return TRUE;
}
-void
+static void
nv40_fragprog_translate(struct nv40_context *nv40,
struct nv40_fragment_program *fp)
{
@@ -750,28 +750,80 @@ nv40_fragprog_translate(struct nv40_context *nv40,
fp->insn[fpc->inst_offset + 3] = 0x00000000;
fp->translated = TRUE;
- fp->on_hw = FALSE;
out_err:
tgsi_parse_free(&parse);
free(fpc);
}
-void
-nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp)
+static void
+nv40_fragprog_upload(struct nv40_context *nv40,
+ struct nv40_fragment_program *fp)
+{
+ struct pipe_winsys *ws = nv40->pipe.winsys;
+ const uint32_t le = 1;
+ uint32_t *map;
+ int i;
+
+ map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+#if 0
+ for (i = 0; i < fp->insn_len; i++) {
+ NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]);
+ }
+#endif
+
+ if ((*(const uint8_t *)&le)) {
+ for (i = 0; i < fp->insn_len; i++) {
+ map[i] = fp->insn[i];
+ }
+ } else {
+ /* Weird swapping for big-endian chips */
+ for (i = 0; i < fp->insn_len; i++) {
+ map[i] = ((fp->insn[i] & 0xffff) << 16) |
+ ((fp->insn[i] >> 16) & 0xffff);
+ }
+ }
+
+ ws->buffer_unmap(ws, fp->buffer);
+}
+
+static boolean
+nv40_fragprog_validate(struct nv40_context *nv40)
{
+ struct nv40_fragment_program *fp = nv40->fragprog;
+ struct pipe_buffer *constbuf =
+ nv40->constbuf[PIPE_SHADER_FRAGMENT];
struct pipe_winsys *ws = nv40->pipe.winsys;
struct nouveau_stateobj *so;
int i;
+ if (fp->translated)
+ goto update_constants;
+
+ nv40_fragprog_translate(nv40, fp);
if (!fp->translated) {
- nv40_fragprog_translate(nv40, fp);
- if (!fp->translated)
- assert(0);
+ nv40->fallback |= NV40_FALLBACK_RAST;
+ return FALSE;
}
+ fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4);
+ nv40_fragprog_upload(nv40, fp);
+
+ so = so_new(4, 1);
+ so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1);
+ so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
+ NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
+ NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1);
+ so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1);
+ so_data (so, fp->fp_control);
+ so_ref(so, &fp->so);
+
+update_constants:
if (fp->nr_consts) {
- float *map = ws->buffer_map(ws, nv40->fragprog.constant_buf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ boolean new_consts = FALSE;
+ float *map;
+
+ map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ);
for (i = 0; i < fp->nr_consts; i++) {
struct nv40_fragment_program_data *fpd = &fp->consts[i];
uint32_t *p = &fp->insn[fpd->offset];
@@ -780,56 +832,20 @@ nv40_fragprog_bind(struct nv40_context *nv40, struct nv40_fragment_program *fp)
if (!memcmp(p, cb, 4 * sizeof(float)))
continue;
memcpy(p, cb, 4 * sizeof(float));
- fp->on_hw = 0;
+ new_consts = TRUE;
}
- ws->buffer_unmap(ws, nv40->fragprog.constant_buf);
- }
+ ws->buffer_unmap(ws, constbuf);
- if (!fp->on_hw) {
- const uint32_t le = 1;
- uint32_t *map;
-
- if (!fp->buffer)
- fp->buffer = ws->buffer_create(ws, 0x100, 0,
- fp->insn_len * 4);
- map = ws->buffer_map(ws, fp->buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
-#if 0
- for (i = 0; i < fp->insn_len; i++) {
- NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]);
- }
-#endif
-
- if ((*(const uint8_t *)&le)) {
- for (i = 0; i < fp->insn_len; i++) {
- map[i] = fp->insn[i];
- }
- } else {
- /* Weird swapping for big-endian chips */
- for (i = 0; i < fp->insn_len; i++) {
- map[i] = ((fp->insn[i] & 0xffff) << 16) |
- ((fp->insn[i] >> 16) & 0xffff);
- }
- }
-
- ws->buffer_unmap(ws, fp->buffer);
- fp->on_hw = TRUE;
+ if (new_consts)
+ nv40_fragprog_upload(nv40, fp);
}
- so = so_new(4, 1);
- so_method(so, nv40->hw->curie, NV40TCL_FP_ADDRESS, 1);
- so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1);
- so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1);
- so_data (so, fp->fp_control);
-
- so_emit(nv40->nvws, so);
- so_ref(so, &fp->so);
- so_ref(NULL, &so);
+ if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) {
+ so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]);
+ return TRUE;
+ }
- nv40->fragprog.active = fp;
+ return FALSE;
}
void
@@ -840,3 +856,11 @@ nv40_fragprog_destroy(struct nv40_context *nv40,
free(fp->insn);
}
+struct nv40_state_entry nv40_state_fragprog = {
+ .validate = nv40_fragprog_validate,
+ .dirty = {
+ .pipe = NV40_NEW_FRAGPROG,
+ .hw = NV40_STATE_FRAGPROG
+ }
+};
+
diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c
index 5af5fbe746..436f954cec 100644
--- a/src/gallium/drivers/nv40/nv40_fragtex.c
+++ b/src/gallium/drivers/nv40/nv40_fragtex.c
@@ -41,6 +41,7 @@ static struct nv40_texture_format *
nv40_fragtex_format(uint pipe_format)
{
struct nv40_texture_format *tf = nv40_texture_formats;
+ char fs[128];
while (tf->defined) {
if (tf->pipe == pipe_format)
@@ -48,11 +49,13 @@ nv40_fragtex_format(uint pipe_format)
tf++;
}
+ pf_sprint_name(fs, pipe_format);
+ NOUVEAU_ERR("unknown texture format %s\n", fs);
return NULL;
}
-static void
+static struct nouveau_stateobj *
nv40_fragtex_build(struct nv40_context *nv40, int unit)
{
struct nv40_sampler_state *ps = nv40->tex_sampler[unit];
@@ -90,7 +93,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
break;
default:
NOUVEAU_ERR("Unknown target %d\n", pt->target);
- return;
+ return NULL;
}
if (swizzled) {
@@ -103,7 +106,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
txs = tf->swizzle;
so = so_new(16, 2);
- so_method(so, nv40->hw->curie, NV40TCL_TEX_OFFSET(unit), 8);
+ so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8);
so_reloc (so, nv40mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
so_reloc (so, nv40mt->buffer, txf, tex_flags | NOUVEAU_BO_OR,
NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1);
@@ -114,28 +117,30 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) |
pt->height[0]);
so_data (so, ps->bcol);
- so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1);
+ so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1);
so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
- so_emit(nv40->nvws, so);
- so_ref (so, &nv40->so_fragtex[unit]);
- so_ref (NULL, &so);
+ return so;
}
-void
-nv40_fragtex_bind(struct nv40_context *nv40)
+static boolean
+nv40_fragtex_validate(struct nv40_context *nv40)
{
- struct nv40_fragment_program *fp = nv40->fragprog.active;
+ struct nv40_fragment_program *fp = nv40->fragprog;
+ struct nv40_state *state = &nv40->state;
+ struct nouveau_stateobj *so;
unsigned samplers, unit;
- samplers = nv40->fp_samplers & ~fp->samplers;
+ samplers = state->fp_samplers & ~fp->samplers;
while (samplers) {
unit = ffs(samplers) - 1;
samplers &= ~(1 << unit);
- so_ref(NULL, &nv40->so_fragtex[unit]);
- BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1);
- OUT_RING (0);
+ so = so_new(2, 0);
+ so_method(so, nv40->screen->curie, NV40TCL_TEX_ENABLE(unit), 1);
+ so_data (so, 0);
+ so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
+ state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit));
}
samplers = nv40->dirty_samplers & fp->samplers;
@@ -143,9 +148,20 @@ nv40_fragtex_bind(struct nv40_context *nv40)
unit = ffs(samplers) - 1;
samplers &= ~(1 << unit);
- nv40_fragtex_build(nv40, unit);
+ so = nv40_fragtex_build(nv40, unit);
+ so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
+ state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit));
}
- nv40->fp_samplers = fp->samplers;
+ nv40->state.fp_samplers = fp->samplers;
+ return FALSE;
}
+struct nv40_state_entry nv40_state_fragtex = {
+ .validate = nv40_fragtex_validate,
+ .dirty = {
+ .pipe = NV40_NEW_SAMPLER | NV40_NEW_FRAGPROG,
+ .hw = 0
+ }
+};
+
diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c
index 92e6b3a43d..94ba05b710 100644
--- a/src/gallium/drivers/nv40/nv40_miptree.c
+++ b/src/gallium/drivers/nv40/nv40_miptree.c
@@ -54,15 +54,18 @@ nv40_miptree_layout(struct nv40_miptree *nv40mt)
}
static struct pipe_texture *
-nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt)
+nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
{
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_winsys *ws = pscreen->winsys;
struct nv40_miptree *mt;
mt = MALLOC(sizeof(struct nv40_miptree));
if (!mt)
return NULL;
mt->base = *pt;
+ mt->base.refcount = 1;
+ mt->base.screen = pscreen;
+
nv40_miptree_layout(mt);
mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL,
@@ -76,9 +79,9 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt)
}
static void
-nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt)
+nv40_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt)
{
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_winsys *ws = pscreen->winsys;
struct pipe_texture *mt = *pt;
*pt = NULL;
@@ -95,10 +98,52 @@ nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt)
}
}
+static void
+nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt)
+{
+}
+
+static struct pipe_surface *
+nv40_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
+{
+ struct pipe_winsys *ws = pscreen->winsys;
+ struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt;
+ struct pipe_surface *ps;
+
+ ps = ws->surface_alloc(ws);
+ if (!ps)
+ return NULL;
+ pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer);
+ ps->format = pt->format;
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = nv40mt->level[level].pitch / ps->cpp;
+
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ ps->offset = nv40mt->level[level].image_offset[face];
+ } else
+ if (pt->target == PIPE_TEXTURE_3D) {
+ ps->offset = nv40mt->level[level].image_offset[zslice];
+ } else {
+ ps->offset = nv40mt->level[level].image_offset[0];
+ }
+
+ return ps;
+}
+
void
nv40_init_miptree_functions(struct nv40_context *nv40)
{
- nv40->pipe.texture_create = nv40_miptree_create;
- nv40->pipe.texture_release = nv40_miptree_release;
+ nv40->pipe.texture_update = nv40_miptree_update;
+}
+
+void
+nv40_screen_init_miptree_functions(struct pipe_screen *pscreen)
+{
+ pscreen->texture_create = nv40_miptree_create;
+ pscreen->texture_release = nv40_miptree_release;
+ pscreen->get_tex_surface = nv40_miptree_surface;
}
diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c
index 8bca2788b9..0317845624 100644
--- a/src/gallium/drivers/nv40/nv40_query.c
+++ b/src/gallium/drivers/nv40/nv40_query.c
@@ -45,9 +45,9 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
- if (nv40->nvws->res_alloc(nv40->hw->query_heap, 1, NULL, &q->object))
+ if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object))
assert(0);
- nv40->nvws->notifier_reset(nv40->hw->query, q->object->start);
+ nv40->nvws->notifier_reset(nv40->screen->query, q->object->start);
BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1);
OUT_RING (1);
@@ -82,17 +82,17 @@ nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq,
if (!q->ready) {
unsigned status;
- status = nvws->notifier_status(nv40->hw->query,
+ status = nvws->notifier_status(nv40->screen->query,
q->object->start);
if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
if (wait == FALSE)
return FALSE;
- nvws->notifier_wait(nv40->hw->query, q->object->start,
+ nvws->notifier_wait(nv40->screen->query, q->object->start,
NV_NOTIFY_STATE_STATUS_COMPLETED,
0);
}
- q->result = nvws->notifier_retval(nv40->hw->query,
+ q->result = nvws->notifier_retval(nv40->screen->query,
q->object->start);
q->ready = TRUE;
nvws->res_free(&q->object);
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
new file mode 100644
index 0000000000..268ca83ce0
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -0,0 +1,279 @@
+#include "pipe/p_screen.h"
+#include "pipe/p_util.h"
+
+#include "nv40_context.h"
+#include "nv40_screen.h"
+
+#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf
+#define NV4X_GRCLASS4497_CHIPSETS 0x00005450
+#define NV6X_GRCLASS4497_CHIPSETS 0x00000088
+
+static const char *
+nv40_screen_get_name(struct pipe_screen *pscreen)
+{
+ struct nv40_screen *screen = nv40_screen(pscreen);
+ static char buffer[128];
+
+ snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset);
+ return buffer;
+}
+
+static const char *
+nv40_screen_get_vendor(struct pipe_screen *pscreen)
+{
+ return "nouveau";
+}
+
+static int
+nv40_screen_get_param(struct pipe_screen *pscreen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 16;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 0;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 1;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 4;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 13;
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 10;
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 13;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0;
+ }
+}
+
+static float
+nv40_screen_get_paramf(struct pipe_screen *pscreen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 10.0;
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 64.0;
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 16.0;
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0;
+ case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
+ return 0.0;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0.0;
+ }
+}
+
+static boolean
+nv40_screen_surface_format_supported(struct pipe_screen *pscreen,
+ enum pipe_format format, uint type)
+{
+ switch (type) {
+ case PIPE_SURFACE:
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ return TRUE;
+ default:
+ break;
+ }
+ break;
+ case PIPE_TEXTURE:
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_U_L8:
+ case PIPE_FORMAT_U_A8:
+ case PIPE_FORMAT_U_I8:
+ case PIPE_FORMAT_U_A8_L8:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ return TRUE;
+ default:
+ break;
+ }
+ break;
+ default:
+ assert(0);
+ };
+
+ return FALSE;
+}
+
+static void
+nv40_screen_destroy(struct pipe_screen *pscreen)
+{
+ struct nv40_screen *screen = nv40_screen(pscreen);
+ struct nouveau_winsys *nvws = screen->nvws;
+
+ nvws->res_free(&screen->vp_exec_heap);
+ nvws->res_free(&screen->vp_data_heap);
+ nvws->res_free(&screen->query_heap);
+ nvws->notifier_free(&screen->query);
+ nvws->notifier_free(&screen->sync);
+ nvws->grobj_free(&screen->curie);
+
+ FREE(pscreen);
+}
+
+struct pipe_screen *
+nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
+ unsigned chipset)
+{
+ struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen);
+ struct nouveau_stateobj *so;
+ unsigned curie_class;
+ int ret;
+
+ if (!screen)
+ return NULL;
+ screen->chipset = chipset;
+ screen->nvws = nvws;
+
+ /* 3D object */
+ switch (chipset & 0xf0) {
+ case 0x40:
+ if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f)))
+ curie_class = NV40TCL;
+ else
+ if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f)))
+ curie_class = NV44TCL;
+ break;
+ case 0x60:
+ if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f)))
+ curie_class = NV44TCL;
+ break;
+ default:
+ break;
+ }
+
+ if (!curie_class) {
+ NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset);
+ return NULL;
+ }
+
+ ret = nvws->grobj_alloc(nvws, curie_class, &screen->curie);
+ if (ret) {
+ NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
+ return FALSE;
+ }
+
+ /* Notifier for sync purposes */
+ ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ if (ret) {
+ NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
+ nv40_screen_destroy(&screen->pipe);
+ return NULL;
+ }
+
+ /* Query objects */
+ ret = nvws->notifier_alloc(nvws, 32, &screen->query);
+ if (ret) {
+ NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
+ nv40_screen_destroy(&screen->pipe);
+ return NULL;
+ }
+
+ ret = nvws->res_init(&screen->query_heap, 0, 32);
+ if (ret) {
+ NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
+ nv40_screen_destroy(&screen->pipe);
+ return NULL;
+ }
+
+ /* Vtxprog resources */
+ if (nvws->res_init(&screen->vp_exec_heap, 0, 512) ||
+ nvws->res_init(&screen->vp_data_heap, 0, 256)) {
+ nv40_screen_destroy(&screen->pipe);
+ return NULL;
+ }
+
+ /* Static curie initialisation */
+ so = so_new(128, 0);
+ so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1);
+ so_data (so, screen->sync->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2);
+ so_data (so, nvws->channel->vram->handle);
+ so_data (so, nvws->channel->gart->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1);
+ so_data (so, nvws->channel->vram->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2);
+ so_data (so, nvws->channel->vram->handle);
+ so_data (so, nvws->channel->vram->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2);
+ so_data (so, nvws->channel->vram->handle);
+ so_data (so, nvws->channel->gart->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2);
+ so_data (so, 0);
+ so_data (so, screen->query->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2);
+ so_data (so, nvws->channel->vram->handle);
+ so_data (so, nvws->channel->vram->handle);
+ so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2);
+ so_data (so, nvws->channel->vram->handle);
+ so_data (so, nvws->channel->vram->handle);
+
+ so_method(so, screen->curie, 0x1ea4, 3);
+ so_data (so, 0x00000010);
+ so_data (so, 0x01000100);
+ so_data (so, 0xff800006);
+
+ /* vtxprog output routing */
+ so_method(so, screen->curie, 0x1fc4, 1);
+ so_data (so, 0x06144321);
+ so_method(so, screen->curie, 0x1fc8, 2);
+ so_data (so, 0xedcba987);
+ so_data (so, 0x00000021);
+ so_method(so, screen->curie, 0x1fd0, 1);
+ so_data (so, 0x00171615);
+ so_method(so, screen->curie, 0x1fd4, 1);
+ so_data (so, 0x001b1a19);
+
+ so_method(so, screen->curie, 0x1ef8, 1);
+ so_data (so, 0x0020ffff);
+ so_method(so, screen->curie, 0x1d64, 1);
+ so_data (so, 0x00d30000);
+ so_method(so, screen->curie, 0x1e94, 1);
+ so_data (so, 0x00000001);
+
+ so_emit(nvws, so);
+ so_ref(NULL, &so);
+ nvws->push_flush(nvws->channel, 0);
+
+ screen->pipe.winsys = ws;
+ screen->pipe.destroy = nv40_screen_destroy;
+
+ screen->pipe.get_name = nv40_screen_get_name;
+ screen->pipe.get_vendor = nv40_screen_get_vendor;
+ screen->pipe.get_param = nv40_screen_get_param;
+ screen->pipe.get_paramf = nv40_screen_get_paramf;
+
+ screen->pipe.is_format_supported = nv40_screen_surface_format_supported;
+
+ nv40_screen_init_miptree_functions(&screen->pipe);
+
+ return &screen->pipe;
+}
+
diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h
new file mode 100644
index 0000000000..3ea78aadfd
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_screen.h
@@ -0,0 +1,36 @@
+#ifndef __NV40_SCREEN_H__
+#define __NV40_SCREEN_H__
+
+#include "pipe/p_screen.h"
+
+struct nv40_screen {
+ struct pipe_screen pipe;
+
+ struct nouveau_winsys *nvws;
+ unsigned chipset;
+
+ unsigned cur_pctx;
+
+ /* HW graphics objects */
+ struct nouveau_grobj *curie;
+ struct nouveau_notifier *sync;
+
+ /* Query object resources */
+ struct nouveau_notifier *query;
+ struct nouveau_resource *query_heap;
+
+ /* Vtxprog resources */
+ struct nouveau_resource *vp_exec_heap;
+ struct nouveau_resource *vp_data_heap;
+
+ /* Current 3D state of channel */
+ struct nouveau_stateobj *state[NV40_STATE_MAX];
+};
+
+static INLINE struct nv40_screen *
+nv40_screen(struct pipe_screen *screen)
+{
+ return (struct nv40_screen *)screen;
+}
+
+#endif
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 713f31dbb1..caa2f9df0c 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -10,7 +10,8 @@ nv40_blend_state_create(struct pipe_context *pipe,
const struct pipe_blend_state *cso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_grobj *curie = nv40->hw->curie;
+ struct nouveau_grobj *curie = nv40->screen->curie;
+ struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso));
struct nouveau_stateobj *so = so_new(16, 0);
if (cso->blend_enable) {
@@ -46,7 +47,9 @@ nv40_blend_state_create(struct pipe_context *pipe,
so_method(so, curie, NV40TCL_DITHER_ENABLE, 1);
so_data (so, cso->dither ? 1 : 0);
- return (void *)so;
+ so_ref(so, &bso->so);
+ bso->pipe = *cso;
+ return (void *)bso;
}
static void
@@ -54,16 +57,17 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- so_ref(hwcso, &nv40->so_blend);
+ nv40->blend = hwcso;
nv40->dirty |= NV40_NEW_BLEND;
}
static void
nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nouveau_stateobj *so = hwcso;
+ struct nv40_blend_state *bso = hwcso;
- so_ref(NULL, &so);
+ so_ref(NULL, &bso->so);
+ FREE(bso);
}
@@ -255,12 +259,13 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit,
nv40->tex_sampler[unit] = ps;
nv40->dirty_samplers |= (1 << unit);
+ nv40->dirty |= NV40_NEW_SAMPLER;
}
static void
nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
{
- free(hwcso);
+ FREE(hwcso);
}
static void
@@ -271,6 +276,7 @@ nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit,
nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree;
nv40->dirty_samplers |= (1 << unit);
+ nv40->dirty |= NV40_NEW_SAMPLER;
}
static void *
@@ -278,33 +284,32 @@ nv40_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nv40_context *nv40 = nv40_context(pipe);
+ struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
struct nouveau_stateobj *so = so_new(32, 0);
+ struct nouveau_grobj *curie = nv40->screen->curie;
/*XXX: ignored:
* light_twoside
- * offset_cw/ccw -nohw
- * scissor
* point_smooth -nohw
* multisample
- * offset_units / offset_scale
*/
- so_method(so, nv40->hw->curie, NV40TCL_SHADE_MODEL, 1);
+ so_method(so, curie, NV40TCL_SHADE_MODEL, 1);
so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT :
NV40TCL_SHADE_MODEL_SMOOTH);
- so_method(so, nv40->hw->curie, NV40TCL_LINE_WIDTH, 2);
+ so_method(so, curie, NV40TCL_LINE_WIDTH, 2);
so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
so_data (so, cso->line_smooth ? 1 : 0);
- so_method(so, nv40->hw->curie, NV40TCL_LINE_STIPPLE_ENABLE, 2);
+ so_method(so, curie, NV40TCL_LINE_STIPPLE_ENABLE, 2);
so_data (so, cso->line_stipple_enable ? 1 : 0);
so_data (so, (cso->line_stipple_pattern << 16) |
cso->line_stipple_factor);
- so_method(so, nv40->hw->curie, NV40TCL_POINT_SIZE, 1);
+ so_method(so, curie, NV40TCL_POINT_SIZE, 1);
so_data (so, fui(cso->point_size));
- so_method(so, nv40->hw->curie, NV40TCL_POLYGON_MODE_FRONT, 6);
+ so_method(so, curie, NV40TCL_POLYGON_MODE_FRONT, 6);
if (cso->front_winding == PIPE_WINDING_CCW) {
so_data(so, nvgl_polygon_mode(cso->fill_ccw));
so_data(so, nvgl_polygon_mode(cso->fill_cw));
@@ -345,10 +350,32 @@ nv40_rasterizer_state_create(struct pipe_context *pipe,
so_data(so, cso->poly_smooth ? 1 : 0);
so_data(so, cso->cull_mode != PIPE_WINDING_NONE ? 1 : 0);
- so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
+ so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
so_data (so, cso->poly_stipple_enable ? 1 : 0);
- so_method(so, nv40->hw->curie, NV40TCL_POINT_SPRITE, 1);
+ so_method(so, curie, NV40TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
+ if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
+ (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
+ so_data(so, 1);
+ else
+ so_data(so, 0);
+ if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
+ (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
+ so_data(so, 1);
+ else
+ so_data(so, 0);
+ if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
+ (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
+ so_data(so, 1);
+ else
+ so_data(so, 0);
+ if (cso->offset_cw || cso->offset_ccw) {
+ so_method(so, curie, NV40TCL_POLYGON_OFFSET_FACTOR, 2);
+ so_data (so, fui(cso->offset_scale));
+ so_data (so, fui(cso->offset_units * 2));
+ }
+
+ so_method(so, curie, NV40TCL_POINT_SPRITE, 1);
if (cso->point_sprite) {
unsigned psctl = (1 << 0), i;
@@ -362,7 +389,9 @@ nv40_rasterizer_state_create(struct pipe_context *pipe,
so_data(so, 0);
}
- return (void *)so;
+ so_ref(so, &rsso->so);
+ rsso->pipe = *cso;
+ return (void *)rsso;
}
static void
@@ -370,16 +399,17 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- so_ref(hwcso, &nv40->so_rast);
+ nv40->rasterizer = hwcso;
nv40->dirty |= NV40_NEW_RAST;
}
static void
nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nouveau_stateobj *so = hwcso;
+ struct nv40_rasterizer_state *rsso = hwcso;
- so_ref(NULL, &so);
+ so_ref(NULL, &rsso->so);
+ FREE(rsso);
}
static void *
@@ -387,20 +417,21 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *cso)
{
struct nv40_context *nv40 = nv40_context(pipe);
+ struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
struct nouveau_stateobj *so = so_new(32, 0);
- so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3);
+ so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3);
so_data (so, nvgl_comparison_op(cso->depth.func));
so_data (so, cso->depth.writemask ? 1 : 0);
so_data (so, cso->depth.enabled ? 1 : 0);
- so_method(so, nv40->hw->curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
+ so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
so_data (so, cso->alpha.enabled ? 1 : 0);
so_data (so, nvgl_comparison_op(cso->alpha.func));
so_data (so, float_to_ubyte(cso->alpha.ref));
if (cso->stencil[0].enabled) {
- so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
+ so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
so_data (so, cso->stencil[0].enabled ? 1 : 0);
so_data (so, cso->stencil[0].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[0].func));
@@ -410,12 +441,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
} else {
- so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
+ so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
so_data (so, 0);
}
if (cso->stencil[1].enabled) {
- so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
+ so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
so_data (so, cso->stencil[1].enabled ? 1 : 0);
so_data (so, cso->stencil[1].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[1].func));
@@ -425,11 +456,13 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
} else {
- so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
+ so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
so_data (so, 0);
}
- return (void *)so;
+ so_ref(so, &zsaso->so);
+ zsaso->pipe = *cso;
+ return (void *)zsaso;
}
static void
@@ -437,16 +470,17 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- so_ref(hwcso, &nv40->so_zsa);
+ nv40->zsa = hwcso;
nv40->dirty |= NV40_NEW_ZSA;
}
static void
nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nouveau_stateobj *so = hwcso;
+ struct nv40_zsa_state *zsaso = hwcso;
- so_ref(NULL, &so);
+ so_ref(NULL, &zsaso->so);
+ FREE(zsaso);
}
static void *
@@ -465,9 +499,8 @@ static void
nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_vertex_program *vp = hwcso;
- nv40->vertprog.current = vp;
+ nv40->vertprog = hwcso;
nv40->dirty |= NV40_NEW_VERTPROG;
}
@@ -478,7 +511,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso)
struct nv40_vertex_program *vp = hwcso;
nv40_vertprog_destroy(nv40, vp);
- free(vp);
+ FREE(vp);
}
static void *
@@ -497,9 +530,8 @@ static void
nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_fragment_program *fp = hwcso;
- nv40->fragprog.current = fp;
+ nv40->fragprog = hwcso;
nv40->dirty |= NV40_NEW_FRAGPROG;
}
@@ -510,7 +542,7 @@ nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso)
struct nv40_fragment_program *fp = hwcso;
nv40_fragprog_destroy(nv40, fp);
- free(fp);
+ FREE(fp);
}
static void
@@ -518,16 +550,8 @@ nv40_set_blend_color(struct pipe_context *pipe,
const struct pipe_blend_color *bcol)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_stateobj *so = so_new(2, 0);
-
- so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1);
- so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) |
- (float_to_ubyte(bcol->color[0]) << 16) |
- (float_to_ubyte(bcol->color[1]) << 8) |
- (float_to_ubyte(bcol->color[2]) << 0)));
- so_ref(so, &nv40->so_bcol);
- so_ref(NULL, &so);
+ nv40->blend_colour = *bcol;
nv40->dirty |= NV40_NEW_BCOL;
}
@@ -535,6 +559,10 @@ static void
nv40_set_clip_state(struct pipe_context *pipe,
const struct pipe_clip_state *clip)
{
+ struct nv40_context *nv40 = nv40_context(pipe);
+
+ nv40->clip = *clip;
+ nv40->dirty |= NV40_NEW_UCP;
}
static void
@@ -544,11 +572,11 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
struct nv40_context *nv40 = nv40_context(pipe);
if (shader == PIPE_SHADER_VERTEX) {
- nv40->vertprog.constant_buf = buf->buffer;
+ nv40->constbuf[PIPE_SHADER_VERTEX] = buf->buffer;
nv40->dirty |= NV40_NEW_VERTPROG;
} else
if (shader == PIPE_SHADER_FRAGMENT) {
- nv40->fragprog.constant_buf = buf->buffer;
+ nv40->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer;
nv40->dirty |= NV40_NEW_FRAGPROG;
}
}
@@ -558,146 +586,8 @@ nv40_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct pipe_surface *rt[4], *zeta;
- uint32_t rt_enable, rt_format, w, h;
- int i, colour_format = 0, zeta_format = 0;
- struct nouveau_stateobj *so = so_new(64, 10);
- unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
-
- rt_enable = 0;
- for (i = 0; i < 4; i++) {
- if (!fb->cbufs[i])
- continue;
-
- if (colour_format) {
- assert(w == fb->cbufs[i]->width);
- assert(h == fb->cbufs[i]->height);
- assert(colour_format == fb->cbufs[i]->format);
- } else {
- w = fb->cbufs[i]->width;
- h = fb->cbufs[i]->height;
- colour_format = fb->cbufs[i]->format;
- rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i);
- rt[i] = fb->cbufs[i];
- }
- }
-
- if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 |
- NV40TCL_RT_ENABLE_COLOR3))
- rt_enable |= NV40TCL_RT_ENABLE_MRT;
-
- if (fb->zsbuf) {
- if (colour_format) {
- assert(w == fb->zsbuf->width);
- assert(h == fb->zsbuf->height);
- } else {
- w = fb->zsbuf->width;
- h = fb->zsbuf->height;
- }
- zeta_format = fb->zsbuf->format;
- zeta = fb->zsbuf;
- }
-
- rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR;
-
- switch (colour_format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case 0:
- rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8;
- break;
- case PIPE_FORMAT_R5G6B5_UNORM:
- rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5;
- break;
- default:
- assert(0);
- }
-
- switch (zeta_format) {
- case PIPE_FORMAT_Z16_UNORM:
- rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16;
- break;
- case PIPE_FORMAT_Z24S8_UNORM:
- case 0:
- rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8;
- break;
- default:
- assert(0);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) {
- so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1);
- so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->hw->curie, NV40TCL_COLOR0_PITCH, 2);
- so_data (so, rt[0]->pitch * rt[0]->cpp);
- so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) {
- so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR1, 1);
- so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->hw->curie, NV40TCL_COLOR1_OFFSET, 2);
- so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_data (so, rt[1]->pitch * rt[1]->cpp);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
- so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR2, 1);
- so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->hw->curie, NV40TCL_COLOR2_OFFSET, 1);
- so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_method(so, nv40->hw->curie, NV40TCL_COLOR2_PITCH, 1);
- so_data (so, rt[2]->pitch * rt[2]->cpp);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
- so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR3, 1);
- so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->hw->curie, NV40TCL_COLOR3_OFFSET, 1);
- so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_method(so, nv40->hw->curie, NV40TCL_COLOR3_PITCH, 1);
- so_data (so, rt[3]->pitch * rt[3]->cpp);
- }
-
- if (zeta_format) {
- so_method(so, nv40->hw->curie, NV40TCL_DMA_ZETA, 1);
- so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->hw->curie, NV40TCL_ZETA_OFFSET, 1);
- so_reloc (so, zeta->buffer, zeta->offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1);
- so_data (so, zeta->pitch * zeta->cpp);
- }
-
- so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1);
- so_data (so, rt_enable);
- so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_data (so, rt_format);
- so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
- so_data (so, ((w - 1) << 16) | 0);
- so_data (so, ((h - 1) << 16) | 0);
-
- so_ref(so, &nv40->so_framebuffer);
- so_ref(NULL, &so);
+ nv40->framebuffer = *fb;
nv40->dirty |= NV40_NEW_FB;
}
@@ -706,15 +596,8 @@ nv40_set_polygon_stipple(struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_stateobj *so = so_new(33, 0);
- unsigned i;
- so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32);
- for (i = 0; i < 32; i++)
- so_data(so, stipple->stipple[i]);
-
- so_ref(so, &nv40->so_stipple);
- so_ref(NULL, &so);
+ memcpy(nv40->stipple, stipple->stipple, 4 * 32);
nv40->dirty |= NV40_NEW_STIPPLE;
}
@@ -723,14 +606,8 @@ nv40_set_scissor_state(struct pipe_context *pipe,
const struct pipe_scissor_state *s)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_stateobj *so = so_new(3, 0);
-
- so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2);
- so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
- so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
- so_ref(so, &nv40->so_scissor);
- so_ref(NULL, &so);
+ nv40->scissor = *s;
nv40->dirty |= NV40_NEW_SCISSOR;
}
@@ -739,20 +616,8 @@ nv40_set_viewport_state(struct pipe_context *pipe,
const struct pipe_viewport_state *vpt)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_stateobj *so = so_new(9, 0);
-
- so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(vpt->translate[0]));
- so_data (so, fui(vpt->translate[1]));
- so_data (so, fui(vpt->translate[2]));
- so_data (so, fui(vpt->translate[3]));
- so_data (so, fui(vpt->scale[0]));
- so_data (so, fui(vpt->scale[1]));
- so_data (so, fui(vpt->scale[2]));
- so_data (so, fui(vpt->scale[3]));
-
- so_ref(so, &nv40->so_viewport);
- so_ref(NULL, &so);
+
+ nv40->viewport = *vpt;
nv40->dirty |= NV40_NEW_VIEWPORT;
}
@@ -763,7 +628,6 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index,
struct nv40_context *nv40 = nv40_context(pipe);
nv40->vtxbuf[index] = *vb;
-
nv40->dirty |= NV40_NEW_ARRAYS;
}
@@ -774,7 +638,6 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index,
struct nv40_context *nv40 = nv40_context(pipe);
nv40->vtxelt[index] = *ve;
-
nv40->dirty |= NV40_NEW_ARRAYS;
}
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h
index e82ab9de98..e5217fe91c 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nv40/nv40_state.h
@@ -39,6 +39,7 @@ struct nv40_vertex_program {
uint32_t ir;
uint32_t or;
+ struct nouveau_stateobj *so;
};
struct nv40_fragment_program_data {
@@ -50,7 +51,6 @@ struct nv40_fragment_program {
const struct pipe_shader_state *pipe;
boolean translated;
- boolean on_hw;
unsigned samplers;
uint32_t *insn;
diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c
new file mode 100644
index 0000000000..95e6d7394f
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_blend.c
@@ -0,0 +1,40 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_blend_validate(struct nv40_context *nv40)
+{
+ so_ref(nv40->blend->so, &nv40->state.hw[NV40_STATE_BLEND]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_blend = {
+ .validate = nv40_state_blend_validate,
+ .dirty = {
+ .pipe = NV40_NEW_BLEND,
+ .hw = NV40_STATE_BLEND
+ }
+};
+
+static boolean
+nv40_state_blend_colour_validate(struct nv40_context *nv40)
+{
+ struct nouveau_stateobj *so = so_new(2, 0);
+ struct pipe_blend_color *bcol = &nv40->blend_colour;
+
+ so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1);
+ so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) |
+ (float_to_ubyte(bcol->color[0]) << 16) |
+ (float_to_ubyte(bcol->color[1]) << 8) |
+ (float_to_ubyte(bcol->color[2]) << 0)));
+
+ so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_blend_colour = {
+ .validate = nv40_state_blend_colour_validate,
+ .dirty = {
+ .pipe = NV40_NEW_BCOL,
+ .hw = NV40_STATE_BCOL
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c
new file mode 100644
index 0000000000..93e690161f
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_clip.c
@@ -0,0 +1,18 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_clip_validate(struct nv40_context *nv40)
+{
+ if (nv40->clip.nr)
+ nv40->fallback |= NV40_FALLBACK_TNL;
+
+ return FALSE;
+}
+
+struct nv40_state_entry nv40_state_clip = {
+ .validate = nv40_state_clip_validate,
+ .dirty = {
+ .pipe = NV40_NEW_UCP,
+ .hw = 0
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index a10c995548..9f268640e0 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -1,77 +1,108 @@
#include "nv40_context.h"
#include "nv40_state.h"
-/* Emit relocs for every referenced buffer.
- *
- * This is to ensure the bufmgr has an accurate idea of how
- * the buffer is used. These relocs appear in the push buffer as
- * NOPs, and will only be turned into state changes if a buffer
- * actually moves.
- */
+static struct nv40_state_entry *render_states[] = {
+ &nv40_state_framebuffer,
+ &nv40_state_rasterizer,
+ &nv40_state_clip,
+ &nv40_state_scissor,
+ &nv40_state_stipple,
+ &nv40_state_fragprog,
+ &nv40_state_fragtex,
+ &nv40_state_vertprog,
+ &nv40_state_blend,
+ &nv40_state_blend_colour,
+ &nv40_state_zsa,
+ &nv40_state_viewport,
+ &nv40_state_vbo,
+ NULL
+};
+
static void
-nv40_state_emit_dummy_relocs(struct nv40_context *nv40)
+nv40_state_validate(struct nv40_context *nv40)
{
- unsigned i;
-
- so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer);
- for (i = 0; i < 16; i++) {
- if (!(nv40->fp_samplers & (1 << i)))
- continue;
- so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]);
- }
- so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so);
-}
+ struct nv40_state_entry **states = render_states;
+ unsigned last_fallback;
-void
-nv40_emit_hw_state(struct nv40_context *nv40)
-{
- if (nv40->dirty & NV40_NEW_FB)
- so_emit(nv40->nvws, nv40->so_framebuffer);
+ last_fallback = nv40->fallback;
+ nv40->fallback = 0;
- if (nv40->dirty & NV40_NEW_BLEND)
- so_emit(nv40->nvws, nv40->so_blend);
+ while (*states) {
+ struct nv40_state_entry *e = *states;
- if (nv40->dirty & NV40_NEW_RAST)
- so_emit(nv40->nvws, nv40->so_rast);
+ if (nv40->dirty & e->dirty.pipe) {
+ if (e->validate(nv40))
+ nv40->state.dirty |= (1ULL << e->dirty.hw);
+ }
- if (nv40->dirty & NV40_NEW_ZSA)
- so_emit(nv40->nvws, nv40->so_zsa);
+ states++;
+ }
+ nv40->dirty = 0;
- if (nv40->dirty & NV40_NEW_BCOL)
- so_emit(nv40->nvws, nv40->so_bcol);
+ if (nv40->fallback & NV40_FALLBACK_TNL &&
+ !(last_fallback & NV40_FALLBACK_TNL)) {
+ NOUVEAU_ERR("XXX: hwtnl->swtnl\n");
+ } else
+ if (last_fallback & NV40_FALLBACK_TNL &&
+ !(nv40->fallback & NV40_FALLBACK_TNL)) {
+ NOUVEAU_ERR("XXX: swtnl->hwtnl\n");
+ }
- if (nv40->dirty & NV40_NEW_SCISSOR)
- so_emit(nv40->nvws, nv40->so_scissor);
+ if (nv40->fallback & NV40_FALLBACK_RAST &&
+ !(last_fallback & NV40_FALLBACK_RAST)) {
+ NOUVEAU_ERR("XXX: hwrast->swrast\n");
+ } else
+ if (last_fallback & NV40_FALLBACK_RAST &&
+ !(nv40->fallback & NV40_FALLBACK_RAST)) {
+ NOUVEAU_ERR("XXX: swrast->hwrast\n");
+ }
+}
- if (nv40->dirty & NV40_NEW_VIEWPORT)
- so_emit(nv40->nvws, nv40->so_viewport);
+static void
+nv40_state_emit(struct nv40_context *nv40)
+{
+ struct nv40_state *state = &nv40->state;
+ struct nv40_screen *screen = nv40->screen;
+ unsigned i, samplers;
- if (nv40->dirty & NV40_NEW_STIPPLE)
- so_emit(nv40->nvws, nv40->so_stipple);
+ if (nv40->pctx_id != screen->cur_pctx) {
+ for (i = 0; i < NV40_STATE_MAX; i++) {
+ if (state->hw[i] && screen->state[i] != state->hw[i])
+ state->dirty |= (1ULL << i);
+ }
- if (nv40->dirty & NV40_NEW_FRAGPROG) {
- nv40_fragprog_bind(nv40, nv40->fragprog.current);
- /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */
+ screen->cur_pctx = nv40->pctx_id;
}
- if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) {
- nv40_fragtex_bind(nv40);
+ while (state->dirty) {
+ unsigned idx = ffsll(state->dirty) - 1;
- BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
- OUT_RING (2);
- BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
- OUT_RING (1);
- nv40->dirty &= ~NV40_NEW_FRAGPROG;
+ so_ref (state->hw[idx], &nv40->screen->state[idx]);
+ so_emit(nv40->nvws, nv40->screen->state[idx]);
+ state->dirty &= ~(1ULL << idx);
}
- if (nv40->dirty & NV40_NEW_VERTPROG) {
- nv40_vertprog_bind(nv40, nv40->vertprog.current);
- nv40->dirty &= ~NV40_NEW_VERTPROG;
+ so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]);
+ for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
+ if (!(samplers & (1 << i)))
+ continue;
+ so_emit_reloc_markers(nv40->nvws,
+ state->hw[NV40_STATE_FRAGTEX0+i]);
+ samplers &= ~(1ULL << i);
}
+ so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]);
+ so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]);
+}
- nv40->dirty_samplers = 0;
- nv40->dirty = 0;
+void
+nv40_emit_hw_state(struct nv40_context *nv40)
+{
+ nv40_state_validate(nv40);
+ nv40_state_emit(nv40);
- nv40_state_emit_dummy_relocs(nv40);
+ BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
+ OUT_RING (2);
+ BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
+ OUT_RING (1);
}
diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c
new file mode 100644
index 0000000000..71795ab182
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_fb.c
@@ -0,0 +1,155 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_framebuffer_validate(struct nv40_context *nv40)
+{
+ struct pipe_framebuffer_state *fb = &nv40->framebuffer;
+ struct pipe_surface *rt[4], *zeta;
+ uint32_t rt_enable, rt_format, w, h;
+ int i, colour_format = 0, zeta_format = 0;
+ struct nouveau_stateobj *so = so_new(64, 10);
+ unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
+
+ rt_enable = 0;
+ for (i = 0; i < 4; i++) {
+ if (!fb->cbufs[i])
+ continue;
+
+ if (colour_format) {
+ assert(w == fb->cbufs[i]->width);
+ assert(h == fb->cbufs[i]->height);
+ assert(colour_format == fb->cbufs[i]->format);
+ } else {
+ w = fb->cbufs[i]->width;
+ h = fb->cbufs[i]->height;
+ colour_format = fb->cbufs[i]->format;
+ rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i);
+ rt[i] = fb->cbufs[i];
+ }
+ }
+
+ if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 |
+ NV40TCL_RT_ENABLE_COLOR3))
+ rt_enable |= NV40TCL_RT_ENABLE_MRT;
+
+ if (fb->zsbuf) {
+ if (colour_format) {
+ assert(w == fb->zsbuf->width);
+ assert(h == fb->zsbuf->height);
+ } else {
+ w = fb->zsbuf->width;
+ h = fb->zsbuf->height;
+ }
+
+ zeta_format = fb->zsbuf->format;
+ zeta = fb->zsbuf;
+ }
+
+ rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR;
+
+ switch (colour_format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case 0:
+ rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8;
+ break;
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5;
+ break;
+ default:
+ assert(0);
+ }
+
+ switch (zeta_format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16;
+ break;
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case 0:
+ rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8;
+ break;
+ default:
+ assert(0);
+ }
+
+ if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) {
+ so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR0, 1);
+ so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
+ nv40->nvws->channel->vram->handle,
+ nv40->nvws->channel->gart->handle);
+ so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2);
+ so_data (so, rt[0]->pitch * rt[0]->cpp);
+ so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags |
+ NOUVEAU_BO_LOW, 0, 0);
+ }
+
+ if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) {
+ so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR1, 1);
+ so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
+ nv40->nvws->channel->vram->handle,
+ nv40->nvws->channel->gart->handle);
+ so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2);
+ so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags |
+ NOUVEAU_BO_LOW, 0, 0);
+ so_data (so, rt[1]->pitch * rt[1]->cpp);
+ }
+
+ if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
+ so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR2, 1);
+ so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
+ nv40->nvws->channel->vram->handle,
+ nv40->nvws->channel->gart->handle);
+ so_method(so, nv40->screen->curie, NV40TCL_COLOR2_OFFSET, 1);
+ so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags |
+ NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1);
+ so_data (so, rt[2]->pitch * rt[2]->cpp);
+ }
+
+ if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
+ so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR3, 1);
+ so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
+ nv40->nvws->channel->vram->handle,
+ nv40->nvws->channel->gart->handle);
+ so_method(so, nv40->screen->curie, NV40TCL_COLOR3_OFFSET, 1);
+ so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags |
+ NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1);
+ so_data (so, rt[3]->pitch * rt[3]->cpp);
+ }
+
+ if (zeta_format) {
+ so_method(so, nv40->screen->curie, NV40TCL_DMA_ZETA, 1);
+ so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR,
+ nv40->nvws->channel->vram->handle,
+ nv40->nvws->channel->gart->handle);
+ so_method(so, nv40->screen->curie, NV40TCL_ZETA_OFFSET, 1);
+ so_reloc (so, zeta->buffer, zeta->offset, rt_flags |
+ NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1);
+ so_data (so, zeta->pitch * zeta->cpp);
+ }
+
+ so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1);
+ so_data (so, rt_enable);
+ so_method(so, nv40->screen->curie, NV40TCL_RT_HORIZ, 3);
+ so_data (so, (w << 16) | 0);
+ so_data (so, (h << 16) | 0);
+ so_data (so, rt_format);
+ so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_HORIZ, 2);
+ so_data (so, (w << 16) | 0);
+ so_data (so, (h << 16) | 0);
+ so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
+ so_data (so, ((w - 1) << 16) | 0);
+ so_data (so, ((h - 1) << 16) | 0);
+
+ so_ref(so, &nv40->state.hw[NV40_STATE_FB]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_framebuffer = {
+ .validate = nv40_state_framebuffer_validate,
+ .dirty = {
+ .pipe = NV40_NEW_FB,
+ .hw = NV40_STATE_FB
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c
new file mode 100644
index 0000000000..9ecda5990f
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_rasterizer.c
@@ -0,0 +1,17 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_rasterizer_validate(struct nv40_context *nv40)
+{
+ so_ref(nv40->rasterizer->so,
+ &nv40->state.hw[NV40_STATE_RAST]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_rasterizer = {
+ .validate = nv40_state_rasterizer_validate,
+ .dirty = {
+ .pipe = NV40_NEW_RAST,
+ .hw = NV40_STATE_RAST
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c
new file mode 100644
index 0000000000..9e9eadc511
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_scissor.c
@@ -0,0 +1,34 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_scissor_validate(struct nv40_context *nv40)
+{
+ struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe;
+ struct pipe_scissor_state *s = &nv40->scissor;
+ struct nouveau_stateobj *so;
+
+ if (nv40->state.hw[NV40_STATE_SCISSOR] &&
+ (rast->scissor == 0 && nv40->state.scissor_enabled == 0))
+ return FALSE;
+
+ so = so_new(3, 0);
+ so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2);
+ if (rast->scissor) {
+ so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
+ so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
+ } else {
+ so_data (so, 4096 << 16);
+ so_data (so, 4096 << 16);
+ }
+
+ so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_scissor = {
+ .validate = nv40_state_scissor_validate,
+ .dirty = {
+ .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST,
+ .hw = NV40_STATE_SCISSOR
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c
new file mode 100644
index 0000000000..b51024ad9b
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_stipple.c
@@ -0,0 +1,39 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_stipple_validate(struct nv40_context *nv40)
+{
+ struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe;
+ struct nouveau_grobj *curie = nv40->screen->curie;
+ struct nouveau_stateobj *so;
+
+ if (nv40->state.hw[NV40_STATE_STIPPLE] &&
+ (rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0))
+ return FALSE;
+
+ if (rast->poly_stipple_enable) {
+ unsigned i;
+
+ so = so_new(35, 0);
+ so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
+ so_data (so, 1);
+ so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32);
+ for (i = 0; i < 32; i++)
+ so_data(so, nv40->stipple[i]);
+ } else {
+ so = so_new(2, 0);
+ so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
+ so_data (so, 0);
+ }
+
+ so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_stipple = {
+ .validate = nv40_state_stipple_validate,
+ .dirty = {
+ .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST,
+ .hw = NV40_STATE_STIPPLE,
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c
new file mode 100644
index 0000000000..3a32533907
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_viewport.c
@@ -0,0 +1,29 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_viewport_validate(struct nv40_context *nv40)
+{
+ struct nouveau_stateobj *so = so_new(9, 0);
+ struct pipe_viewport_state *vpt = &nv40->viewport;
+
+ so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8);
+ so_data (so, fui(vpt->translate[0]));
+ so_data (so, fui(vpt->translate[1]));
+ so_data (so, fui(vpt->translate[2]));
+ so_data (so, fui(vpt->translate[3]));
+ so_data (so, fui(vpt->scale[0]));
+ so_data (so, fui(vpt->scale[1]));
+ so_data (so, fui(vpt->scale[2]));
+ so_data (so, fui(vpt->scale[3]));
+
+ so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_viewport = {
+ .validate = nv40_state_viewport_validate,
+ .dirty = {
+ .pipe = NV40_NEW_VIEWPORT,
+ .hw = NV40_STATE_VIEWPORT
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c
new file mode 100644
index 0000000000..fb760677c8
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_state_zsa.c
@@ -0,0 +1,17 @@
+#include "nv40_context.h"
+
+static boolean
+nv40_state_zsa_validate(struct nv40_context *nv40)
+{
+ so_ref(nv40->zsa->so,
+ &nv40->state.hw[NV40_STATE_ZSA]);
+ return TRUE;
+}
+
+struct nv40_state_entry nv40_state_zsa = {
+ .validate = nv40_state_zsa_validate,
+ .dirty = {
+ .pipe = NV40_NEW_ZSA,
+ .hw = NV40_STATE_ZSA
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c
index 9726ab4e4d..e8a6011696 100644
--- a/src/gallium/drivers/nv40/nv40_surface.c
+++ b/src/gallium/drivers/nv40/nv40_surface.c
@@ -33,76 +33,6 @@
#include "pipe/p_inlines.h"
#include "util/p_tile.h"
-static boolean
-nv40_surface_format_supported(struct pipe_context *pipe,
- enum pipe_format format, uint type)
-{
- switch (type) {
- case PIPE_SURFACE:
- switch (format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- return TRUE;
- default:
- break;
- }
- break;
- case PIPE_TEXTURE:
- switch (format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_A1R5G5B5_UNORM:
- case PIPE_FORMAT_A4R4G4B4_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_U_L8:
- case PIPE_FORMAT_U_A8:
- case PIPE_FORMAT_U_I8:
- case PIPE_FORMAT_U_A8_L8:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- return TRUE;
- default:
- break;
- }
- break;
- default:
- assert(0);
- };
-
- return FALSE;
-}
-
-static struct pipe_surface *
-nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
-{
- struct pipe_winsys *ws = pipe->winsys;
- struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt;
- struct pipe_surface *ps;
-
- ps = ws->surface_alloc(ws);
- if (!ps)
- return NULL;
- pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer);
- ps->format = pt->format;
- ps->cpp = pt->cpp;
- ps->width = pt->width[level];
- ps->height = pt->height[level];
- ps->pitch = nv40mt->level[level].pitch / ps->cpp;
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- ps->offset = nv40mt->level[level].image_offset[face];
- } else
- if (pt->target == PIPE_TEXTURE_3D) {
- ps->offset = nv40mt->level[level].image_offset[zslice];
- } else {
- ps->offset = nv40mt->level[level].image_offset[0];
- }
-
- return ps;
-}
-
static void
nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip,
struct pipe_surface *dest, unsigned destx, unsigned desty,
@@ -130,8 +60,6 @@ nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
void
nv40_init_surface_functions(struct nv40_context *nv40)
{
- nv40->pipe.is_format_supported = nv40_surface_format_supported;
- nv40->pipe.get_tex_surface = nv40_get_tex_surface;
nv40->pipe.surface_copy = nv40_surface_copy;
nv40->pipe.surface_fill = nv40_surface_fill;
}
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index fa827ef0c5..bedc8c6d4e 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -30,9 +30,50 @@ nv40_vbo_type(uint format)
case PIPE_FORMAT_TYPE_UNORM:
return NV40TCL_VTXFMT_TYPE_UBYTE;
default:
- NOUVEAU_ERR("Unknown format 0x%08x\n", format);
+ {
+ char fs[128];
+ pf_sprint_name(fs, format);
+ NOUVEAU_ERR("Unknown format %s\n", fs);
return NV40TCL_VTXFMT_TYPE_FLOAT;
}
+ }
+}
+
+static boolean
+nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib,
+ unsigned ib_size)
+{
+ unsigned type;
+
+ if (!ib) {
+ nv40->idxbuf = NULL;
+ nv40->idxbuf_format = 0xdeadbeef;
+ return FALSE;
+ }
+
+ /* No support for 8bit indices, no support at all on 0x4497 chips */
+ if (nv40->screen->curie->grclass == NV44TCL || ib_size == 1)
+ return FALSE;
+
+ switch (ib_size) {
+ case 2:
+ type = NV40TCL_IDXBUF_FORMAT_TYPE_U16;
+ break;
+ case 4:
+ type = NV40TCL_IDXBUF_FORMAT_TYPE_U32;
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (ib != nv40->idxbuf ||
+ type != nv40->idxbuf_format) {
+ nv40->dirty |= NV40_NEW_ARRAYS;
+ nv40->idxbuf = ib;
+ nv40->idxbuf_format = type;
+ }
+
+ return TRUE;
}
static boolean
@@ -97,105 +138,15 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, int attrib,
return TRUE;
}
-static void
-nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib,
- unsigned ib_format)
-{
- struct nv40_vertex_program *vp = nv40->vertprog.active;
- struct nouveau_stateobj *vtxbuf, *vtxfmt;
- unsigned inputs, hw, num_hw;
- unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- inputs = vp->ir;
- for (hw = 0; hw < 16 && inputs; hw++) {
- if (inputs & (1 << hw)) {
- num_hw = hw;
- inputs &= ~(1 << hw);
- }
- }
- num_hw++;
-
- vtxbuf = so_new(20, 18);
- so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw);
- vtxfmt = so_new(17, 0);
- so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw);
-
- inputs = vp->ir;
- for (hw = 0; hw < num_hw; hw++) {
- struct pipe_vertex_element *ve;
- struct pipe_vertex_buffer *vb;
-
- if (!(inputs & (1 << hw))) {
- so_data(vtxbuf, 0);
- so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
- continue;
- }
-
- ve = &nv40->vtxelt[hw];
- vb = &nv40->vtxbuf[ve->vertex_buffer_index];
-
- if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) {
- so_data(vtxbuf, 0);
- so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
- continue;
- }
-
- so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset,
- vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- 0, NV40TCL_VTXBUF_ADDRESS_DMA1);
- so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
- (nv40_vbo_ncomp(ve->src_format) <<
- NV40TCL_VTXFMT_SIZE_SHIFT) |
- nv40_vbo_type(ve->src_format)));
- }
-
- if (ib) {
- so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2);
- so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
- so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR,
- 0, NV40TCL_IDXBUF_FORMAT_DMA1);
- }
-
- so_emit(nv40->nvws, vtxfmt);
- so_emit(nv40->nvws, vtxbuf);
- so_ref (vtxbuf, &nv40->so_vtxbuf);
- so_ref (NULL, &vtxbuf);
- so_ref (NULL, &vtxfmt);
-}
-
-static boolean
-nv40_vbo_validate_state(struct nv40_context *nv40,
- struct pipe_buffer *ib, unsigned ib_format)
-{
- unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS;
-
- nv40_emit_hw_state(nv40);
- if (vdn || ib) {
- nv40_vbo_arrays_update(nv40, ib, ib_format);
- nv40->dirty &= ~NV40_NEW_ARRAYS;
- }
-
- so_emit_reloc_markers(nv40->nvws, nv40->so_vtxbuf);
-
- BEGIN_RING(curie, 0x1710, 1);
- OUT_RING (0); /* vtx cache flush */
-
- return TRUE;
-}
-
boolean
nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
{
struct nv40_context *nv40 = nv40_context(pipe);
unsigned nr;
- boolean ret;
- ret = nv40_vbo_validate_state(nv40, NULL, 0);
- if (!ret) {
- NOUVEAU_ERR("state validate failed\n");
- return FALSE;
- }
+ nv40_vbo_set_idxbuf(nv40, NULL, 0);
+ nv40_emit_hw_state(nv40);
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
OUT_RING (nvgl_primitive(mode));
@@ -302,14 +253,9 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
struct pipe_winsys *ws = pipe->winsys;
- boolean ret;
void *map;
- ret = nv40_vbo_validate_state(nv40, NULL, 0);
- if (!ret) {
- NOUVEAU_ERR("state validate failed\n");
- return FALSE;
- }
+ nv40_emit_hw_state(nv40);
map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ);
if (!ib) {
@@ -345,30 +291,12 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
static boolean
nv40_draw_elements_vbo(struct pipe_context *pipe,
- struct pipe_buffer *ib, unsigned ib_size,
unsigned mode, unsigned start, unsigned count)
{
struct nv40_context *nv40 = nv40_context(pipe);
- unsigned nr, type;
- boolean ret;
-
- switch (ib_size) {
- case 2:
- type = NV40TCL_IDXBUF_FORMAT_TYPE_U16;
- break;
- case 4:
- type = NV40TCL_IDXBUF_FORMAT_TYPE_U32;
- break;
- default:
- NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
- return FALSE;
- }
+ unsigned nr;
- ret = nv40_vbo_validate_state(nv40, ib, type);
- if (!ret) {
- NOUVEAU_ERR("failed state validation\n");
- return FALSE;
- }
+ nv40_emit_hw_state(nv40);
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
OUT_RING (nvgl_primitive(mode));
@@ -406,19 +334,92 @@ nv40_draw_elements(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
- /* 0x4497 doesn't support real index buffers, and there doesn't appear
- * to be support on any chipset for 8-bit indices.
- */
- if (nv40->hw->curie->grclass == NV44TCL || indexSize == 1) {
+ if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) {
+ nv40_draw_elements_vbo(pipe, mode, start, count);
+ } else {
nv40_draw_elements_inline(pipe, indexBuffer, indexSize,
mode, start, count);
- } else {
- nv40_draw_elements_vbo(pipe, indexBuffer, indexSize,
- mode, start, count);
}
pipe->flush(pipe, 0);
return TRUE;
}
+static boolean
+nv40_vbo_validate(struct nv40_context *nv40)
+{
+ struct nv40_vertex_program *vp = nv40->vertprog;
+ struct nouveau_stateobj *vtxbuf, *vtxfmt;
+ struct pipe_buffer *ib = nv40->idxbuf;
+ unsigned ib_format = nv40->idxbuf_format;
+ unsigned inputs, hw, num_hw;
+ unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+
+ inputs = vp->ir;
+ for (hw = 0; hw < 16 && inputs; hw++) {
+ if (inputs & (1 << hw)) {
+ num_hw = hw;
+ inputs &= ~(1 << hw);
+ }
+ }
+ num_hw++;
+
+ vtxbuf = so_new(20, 18);
+ so_method(vtxbuf, nv40->screen->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw);
+ vtxfmt = so_new(17, 0);
+ so_method(vtxfmt, nv40->screen->curie, NV40TCL_VTXFMT(0), num_hw);
+
+ inputs = vp->ir;
+ for (hw = 0; hw < num_hw; hw++) {
+ struct pipe_vertex_element *ve;
+ struct pipe_vertex_buffer *vb;
+
+ if (!(inputs & (1 << hw))) {
+ so_data(vtxbuf, 0);
+ so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
+ continue;
+ }
+
+ ve = &nv40->vtxelt[hw];
+ vb = &nv40->vtxbuf[ve->vertex_buffer_index];
+
+ if (!vb->pitch && nv40_vbo_static_attrib(nv40, hw, ve, vb)) {
+ so_data(vtxbuf, 0);
+ so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
+ continue;
+ }
+
+ so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset,
+ vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
+ 0, NV40TCL_VTXBUF_ADDRESS_DMA1);
+ so_data (vtxfmt, ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
+ (nv40_vbo_ncomp(ve->src_format) <<
+ NV40TCL_VTXFMT_SIZE_SHIFT) |
+ nv40_vbo_type(ve->src_format)));
+ }
+
+ if (ib) {
+ so_method(vtxbuf, nv40->screen->curie, NV40TCL_IDXBUF_ADDRESS, 2);
+ so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR,
+ 0, NV40TCL_IDXBUF_FORMAT_DMA1);
+ }
+
+ so_method(vtxbuf, nv40->screen->curie, 0x1710, 1);
+ so_data (vtxbuf, 0);
+
+ so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]);
+ nv40->state.dirty |= (1ULL << NV40_STATE_VTXBUF);
+ so_ref(vtxfmt, &nv40->state.hw[NV40_STATE_VTXFMT]);
+ nv40->state.dirty |= (1ULL << NV40_STATE_VTXFMT);
+ return FALSE;
+}
+
+struct nv40_state_entry nv40_state_vbo = {
+ .validate = nv40_vbo_validate,
+ .dirty = {
+ .pipe = NV40_NEW_ARRAYS,
+ .hw = 0,
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index 9f4738b830..5b7a343e55 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -558,7 +558,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc)
return TRUE;
}
-void
+static void
nv40_vertprog_translate(struct nv40_context *nv40,
struct nv40_vertex_program *vp)
{
@@ -631,24 +631,32 @@ out_err:
free(vpc);
}
-void
-nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp)
+static boolean
+nv40_vertprog_validate(struct nv40_context *nv40)
{
+ struct nv40_vertex_program *vp = nv40->vertprog;
+ struct pipe_buffer *constbuf =
+ nv40->constbuf[PIPE_SHADER_VERTEX];
struct nouveau_winsys *nvws = nv40->nvws;
struct pipe_winsys *ws = nv40->pipe.winsys;
boolean upload_code = FALSE, upload_data = FALSE;
int i;
/* Translate TGSI shader into hw bytecode */
+ if (vp->translated)
+ goto check_gpu_resources;
+
+ nv40_vertprog_translate(nv40, vp);
if (!vp->translated) {
- nv40_vertprog_translate(nv40, vp);
- if (!vp->translated)
- assert(0);
+ nv40->fallback |= NV40_FALLBACK_TNL;
+ return FALSE;
}
+check_gpu_resources:
/* Allocate hw vtxprog exec slots */
if (!vp->exec) {
- struct nouveau_resource *heap = nv40->hw->vp_exec_heap;
+ struct nouveau_resource *heap = nv40->screen->vp_exec_heap;
+ struct nouveau_stateobj *so;
uint vplen = vp->nr_insns;
if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) {
@@ -663,12 +671,20 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp)
assert(0);
}
+ so = so_new(5, 0);
+ so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1);
+ so_data (so, vp->exec->start);
+ so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2);
+ so_data (so, vp->ir);
+ so_data (so, vp->or);
+ so_ref(so, &vp->so);
+
upload_code = TRUE;
}
/* Allocate hw vtxprog const slots */
if (vp->nr_consts && !vp->data) {
- struct nouveau_resource *heap = nv40->hw->vp_data_heap;
+ struct nouveau_resource *heap = nv40->screen->vp_data_heap;
if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) {
while (heap->next && heap->size < vp->nr_consts) {
@@ -725,8 +741,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp)
if (vp->nr_consts) {
float *map = NULL;
- if (nv40->vertprog.constant_buf) {
- map = ws->buffer_map(ws, nv40->vertprog.constant_buf,
+ if (constbuf) {
+ map = ws->buffer_map(ws, constbuf,
PIPE_BUFFER_USAGE_CPU_READ);
}
@@ -747,9 +763,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp)
OUT_RINGp ((uint32_t *)vpd->value, 4);
}
- if (map) {
- ws->buffer_unmap(ws, nv40->vertprog.constant_buf);
- }
+ if (constbuf)
+ ws->buffer_unmap(ws, constbuf);
}
/* Upload vtxprog */
@@ -770,13 +785,12 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp)
}
}
- BEGIN_RING(curie, NV40TCL_VP_START_FROM_ID, 1);
- OUT_RING (vp->exec->start);
- BEGIN_RING(curie, NV40TCL_VP_ATTRIB_EN, 2);
- OUT_RING (vp->ir);
- OUT_RING (vp->or);
+ if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) {
+ so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]);
+ return TRUE;
+ }
- nv40->vertprog.active = vp;
+ return FALSE;
}
void
@@ -788,3 +802,11 @@ nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp)
free(vp->insns);
}
+struct nv40_state_entry nv40_state_vertprog = {
+ .validate = nv40_vertprog_validate,
+ .dirty = {
+ .pipe = NV40_NEW_VERTPROG,
+ .hw = NV40_STATE_VERTPROG,
+ }
+};
+
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile
index 68eb49ff2a..1c0b82887a 100644
--- a/src/gallium/drivers/nv50/Makefile
+++ b/src/gallium/drivers/nv50/Makefile
@@ -9,6 +9,7 @@ DRIVER_SOURCES = \
nv50_draw.c \
nv50_miptree.c \
nv50_query.c \
+ nv50_screen.c \
nv50_state.c \
nv50_surface.c \
nv50_vbo.c
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 3c5a54bfd3..c937b8de6d 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -4,85 +4,7 @@
#include "pipe/p_util.h"
#include "nv50_context.h"
-
-static boolean
-nv50_is_format_supported(struct pipe_context *pipe, enum pipe_format format,
- uint type)
-{
- return FALSE;
-}
-
-static const char *
-nv50_get_name(struct pipe_context *pipe)
-{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", nv50->chipset);
- return buffer;
-}
-
-static const char *
-nv50_get_vendor(struct pipe_context *pipe)
-{
- return "nouveau";
-}
-
-static int
-nv50_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 32;
- case PIPE_CAP_NPOT_TEXTURES:
- return 0;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 0;
- case PIPE_CAP_POINT_SPRITE:
- return 0;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 8;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 0;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 0;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13;
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 10;
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0;
- }
-}
-
-static float
-nv50_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 10.0;
- case PIPE_CAP_MAX_POINT_WIDTH:
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 64.0;
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 16.0;
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 4.0;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0.0;
- }
-}
+#include "nv50_screen.h"
static void
nv50_flush(struct pipe_context *pipe, unsigned flags)
@@ -134,9 +56,11 @@ nv50_init_hwctx(struct nv50_context *nv50, int tesla_class)
#define GRCLASS5097_CHIPSETS 0x00000000
#define GRCLASS8297_CHIPSETS 0x00000010
struct pipe_context *
-nv50_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
- unsigned chipset)
+nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
+ struct pipe_winsys *pipe_winsys = pscreen->winsys;
+ struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
+ unsigned chipset = nv50_screen(pscreen)->chipset;
struct nv50_context *nv50;
int tesla_class, ret;
@@ -173,13 +97,9 @@ nv50_create(struct pipe_winsys *pipe_winsys, struct nouveau_winsys *nvws,
}
nv50->pipe.winsys = pipe_winsys;
+ nv50->pipe.screen = pscreen;
nv50->pipe.destroy = nv50_destroy;
- nv50->pipe.is_format_supported = nv50_is_format_supported;
- nv50->pipe.get_name = nv50_get_name;
- nv50->pipe.get_vendor = nv50_get_vendor;
- nv50->pipe.get_param = nv50_get_param;
- nv50->pipe.get_paramf = nv50_get_paramf;
nv50->pipe.draw_arrays = nv50_draw_arrays;
nv50->pipe.draw_elements = nv50_draw_elements;
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index b99254f619..a529bf3c3e 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -38,6 +38,8 @@ extern void nv50_init_surface_functions(struct nv50_context *nv50);
extern void nv50_init_state_functions(struct nv50_context *nv50);
extern void nv50_init_query_functions(struct nv50_context *nv50);
+extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen);
+
/* nv50_draw.c */
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50);
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 0c034ed438..720d33fda9 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -1,25 +1,46 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
+#include "pipe/p_screen.h"
#include "nv50_context.h"
static struct pipe_texture *
-nv50_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt)
+nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
{
NOUVEAU_ERR("unimplemented\n");
return NULL;
}
static void
-nv50_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt)
+nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt)
{
NOUVEAU_ERR("unimplemented\n");
}
+static struct pipe_surface *
+nv50_miptree_surface(struct pipe_screen *pscreen, struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
+{
+ NOUVEAU_ERR("unimplemented\n");
+ return NULL;
+}
+
+void
+nv50_screen_init_miptree_functions(struct pipe_screen *pscreen)
+{
+ pscreen->texture_create = nv50_miptree_create;
+ pscreen->texture_release = nv50_miptree_release;
+ pscreen->get_tex_surface = nv50_miptree_surface;
+}
+
+static void
+nv50_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt)
+{
+}
+
void
nv50_init_miptree_functions(struct nv50_context *nv50)
{
- nv50->pipe.texture_create = nv50_miptree_create;
- nv50->pipe.texture_release = nv50_miptree_release;
+ nv50->pipe.texture_update = nv50_miptree_update;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
new file mode 100644
index 0000000000..f091779e3b
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -0,0 +1,119 @@
+#include "pipe/p_screen.h"
+#include "pipe/p_util.h"
+
+#include "nv50_context.h"
+#include "nv50_screen.h"
+
+static boolean
+nv50_screen_is_format_supported(struct pipe_screen *pscreen,
+ enum pipe_format format, uint type)
+{
+ return FALSE;
+}
+
+static const char *
+nv50_screen_get_name(struct pipe_screen *pscreen)
+{
+ struct nv50_screen *screen = nv50_screen(pscreen);
+ static char buffer[128];
+
+ snprintf(buffer, sizeof(buffer), "NV%02X", screen->chipset);
+ return buffer;
+}
+
+static const char *
+nv50_screen_get_vendor(struct pipe_screen *pscreen)
+{
+ return "nouveau";
+}
+
+static int
+nv50_screen_get_param(struct pipe_screen *pscreen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 32;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 0;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 0;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 0;
+ case PIPE_CAP_POINT_SPRITE:
+ return 0;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 8;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 0;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 0;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 13;
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 10;
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 13;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0;
+ }
+}
+
+static float
+nv50_screen_get_paramf(struct pipe_screen *pscreen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 10.0;
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 64.0;
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 16.0;
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 4.0;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0.0;
+ }
+}
+
+static void
+nv50_screen_destroy(struct pipe_screen *pscreen)
+{
+ FREE(pscreen);
+}
+
+struct pipe_screen *
+nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
+ unsigned chipset)
+{
+ struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
+
+ if (!screen)
+ return NULL;
+
+ screen->chipset = chipset;
+ screen->nvws = nvws;
+
+ screen->pipe.winsys = ws;
+
+ screen->pipe.destroy = nv50_screen_destroy;
+
+ screen->pipe.get_name = nv50_screen_get_name;
+ screen->pipe.get_vendor = nv50_screen_get_vendor;
+ screen->pipe.get_param = nv50_screen_get_param;
+ screen->pipe.get_paramf = nv50_screen_get_paramf;
+
+ screen->pipe.is_format_supported = nv50_screen_is_format_supported;
+
+ nv50_screen_init_miptree_functions(&screen->pipe);
+
+ return &screen->pipe;
+}
+
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
new file mode 100644
index 0000000000..d664816a03
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -0,0 +1,19 @@
+#ifndef __NV50_SCREEN_H__
+#define __NV50_SCREEN_H__
+
+#include "pipe/p_screen.h"
+
+struct nv50_screen {
+ struct pipe_screen pipe;
+
+ struct nouveau_winsys *nvws;
+ unsigned chipset;
+};
+
+static INLINE struct nv50_screen *
+nv50_screen(struct pipe_screen *screen)
+{
+ return (struct nv50_screen *)screen;
+}
+
+#endif
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index ca92ff02b8..39cf675a57 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -33,15 +33,6 @@
#include "pipe/p_inlines.h"
#include "util/p_tile.h"
-static struct pipe_surface *
-nv50_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
-{
- NOUVEAU_ERR("unimplemented\n");
- return NULL;
-}
-
static void
nv50_surface_copy(struct pipe_context *pipe, unsigned flip,
struct pipe_surface *dest, unsigned destx, unsigned desty,
@@ -69,7 +60,6 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
void
nv50_init_surface_functions(struct nv50_context *nv50)
{
- nv50->pipe.get_tex_surface = nv50_get_tex_surface;
nv50->pipe.surface_copy = nv50_surface_copy;
nv50->pipe.surface_fill = nv50_surface_fill;
}
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index 5479daf8ea..f32db35d58 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -1,10 +1,9 @@
-
TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = softpipe
-DRIVER_SOURCES = \
+C_SOURCES = \
sp_fs_exec.c \
sp_fs_sse.c \
sp_fs_llvm.c \
@@ -28,6 +27,7 @@ DRIVER_SOURCES = \
sp_quad_output.c \
sp_quad_stencil.c \
sp_quad_stipple.c \
+ sp_screen.c \
sp_state_blend.c \
sp_state_clip.c \
sp_state_derived.c \
@@ -41,12 +41,6 @@ DRIVER_SOURCES = \
sp_tile_cache.c \
sp_surface.c
-C_SOURCES = \
- $(COMMON_SOURCES) \
- $(DRIVER_SOURCES)
-
-ASM_SOURCES =
-
include ../../Makefile.template
symlinks:
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index d581ee8d3c..88c21ee3b0 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -5,6 +5,9 @@ env = env.Clone()
softpipe = env.ConvenienceLibrary(
target = 'softpipe',
source = [
+ 'sp_fs_exec.c',
+ 'sp_fs_sse.c',
+ 'sp_fs_llvm.c',
'sp_clear.c',
'sp_context.c',
'sp_draw_arrays.c',
@@ -25,6 +28,7 @@ softpipe = env.ConvenienceLibrary(
'sp_quad_stencil.c',
'sp_quad_stipple.c',
'sp_query.c',
+ 'sp_screen.c',
'sp_state_blend.c',
'sp_state_clip.c',
'sp_state_derived.c',
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 5e98f190bb..fa16ed94e8 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -48,29 +48,6 @@
/**
- * Query format support for creating a texture, drawing surface, etc.
- * \param format the format to test
- * \param type one of PIPE_TEXTURE, PIPE_SURFACE
- */
-static boolean
-softpipe_is_format_supported( struct pipe_context *pipe,
- enum pipe_format format, uint type )
-{
- switch (type) {
- case PIPE_TEXTURE:
- /* softpipe supports all texture formats */
- return TRUE;
- case PIPE_SURFACE:
- /* softpipe supports all (off-screen) surface formats */
- return TRUE;
- default:
- assert(0);
- return FALSE;
- }
-}
-
-
-/**
* Map any drawing surfaces which aren't already mapped
*/
void
@@ -143,76 +120,10 @@ static void softpipe_destroy( struct pipe_context *pipe )
}
-static const char *softpipe_get_name( struct pipe_context *pipe )
-{
- return "softpipe";
-}
-
-static const char *softpipe_get_vendor( struct pipe_context *pipe )
-{
- return "Tungsten Graphics, Inc.";
-}
-
-static int softpipe_get_param(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
- case PIPE_CAP_NPOT_TEXTURES:
- return 1;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 1;
- case PIPE_CAP_S3TC:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 0;
- case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 1;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 12; /* max 2Kx2K */
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 12; /* max 2Kx2K */
- default:
- return 0;
- }
-}
-
-static float softpipe_get_paramf(struct pipe_context *pipe, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 255.0; /* arbitrary */
-
- case PIPE_CAP_MAX_POINT_WIDTH:
- /* fall-through */
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 255.0; /* arbitrary */
-
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 0.0;
-
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 16.0; /* arbitrary */
-
- default:
- return 0;
- }
-}
-
-struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
- struct softpipe_winsys *softpipe_winsys )
+struct pipe_context *
+softpipe_create( struct pipe_screen *screen,
+ struct pipe_winsys *pipe_winsys,
+ struct softpipe_winsys *softpipe_winsys )
{
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
uint i;
@@ -226,15 +137,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
softpipe->pipe.winsys = pipe_winsys;
+ softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
- /* queries */
- softpipe->pipe.is_format_supported = softpipe_is_format_supported;
- softpipe->pipe.get_name = softpipe_get_name;
- softpipe->pipe.get_vendor = softpipe_get_vendor;
- softpipe->pipe.get_param = softpipe_get_param;
- softpipe->pipe.get_paramf = softpipe_get_paramf;
-
/* state setters */
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
@@ -279,11 +184,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
softpipe->pipe.flush = softpipe_flush;
softpipe_init_query_funcs( softpipe );
-
- /* textures */
- softpipe->pipe.texture_create = softpipe_texture_create;
- softpipe->pipe.texture_release = softpipe_texture_release;
- softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
+ softpipe_init_texture_funcs( softpipe );
/*
* Alloc caches for accessing drawing surfaces and textures.
@@ -327,6 +228,15 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
}
+ /* plug in AA line/point stages */
+ draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
+ draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
+
+#if USE_DRAW_STAGE_PSTIPPLE
+ /* Do polygon stipple w/ texture map + frag prog? */
+ draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
+#endif
+
sp_init_surface_functions(softpipe);
return &softpipe->pipe;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index b70d4fea85..feeafc7084 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -39,6 +39,13 @@
#include "sp_quad.h"
+/**
+ * This is a temporary variable for testing draw-stage polygon stipple.
+ * If zero, do stipple in sp_quad_stipple.c
+ */
+#define USE_DRAW_STAGE_PSTIPPLE 1
+
+
struct softpipe_winsys;
struct softpipe_vbuf_render;
struct draw_context;
@@ -68,7 +75,7 @@ struct softpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct softpipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 9ad30a7681..d5bd7a702f 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -44,9 +44,44 @@ struct sp_exec_fragment_shader {
+/**
+ * Compute quad X,Y,Z,W for the four fragments in a quad.
+ *
+ * This should really be part of the compiled shader.
+ */
+void
+sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
+ float x, float y,
+ struct tgsi_exec_vector *quadpos)
+{
+ uint chan;
+ /* do X */
+ quadpos->xyzw[0].f[0] = x;
+ quadpos->xyzw[0].f[1] = x + 1;
+ quadpos->xyzw[0].f[2] = x;
+ quadpos->xyzw[0].f[3] = x + 1;
+
+ /* do Y */
+ quadpos->xyzw[1].f[0] = y;
+ quadpos->xyzw[1].f[1] = y;
+ quadpos->xyzw[1].f[2] = y + 1;
+ quadpos->xyzw[1].f[3] = y + 1;
+
+ /* do Z and W for all fragments in the quad */
+ for (chan = 2; chan < 4; chan++) {
+ const float dadx = coef->dadx[chan];
+ const float dady = coef->dady[chan];
+ const float a0 = coef->a0[chan] + dadx * x + dady * y;
+ quadpos->xyzw[chan].f[0] = a0;
+ quadpos->xyzw[chan].f[1] = a0 + dadx;
+ quadpos->xyzw[chan].f[2] = a0 + dady;
+ quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
+ }
+}
+
static void
-exec_prepare( struct sp_fragment_shader *base,
+exec_prepare( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
struct tgsi_sampler *samplers )
{
@@ -63,7 +98,7 @@ exec_prepare( struct sp_fragment_shader *base,
* interface:
*/
static unsigned
-exec_run( struct sp_fragment_shader *base,
+exec_run( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
struct quad_header *quad )
{
diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c
index 22da471453..07d058155f 100644
--- a/src/gallium/drivers/softpipe/sp_fs_llvm.c
+++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c
@@ -96,7 +96,7 @@ shade_quad_llvm(struct quad_stage *qs,
if (qss->colorOutSlot >= 0) {
unsigned i;
/* XXX need to handle multiple color outputs someday */
- allvmrt(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot]
+ allvmrt(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
== TGSI_SEMANTIC_COLOR);
for (i = 0; i < QUAD_SIZE; ++i) {
quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0];
@@ -146,7 +146,7 @@ shade_quad_llvm(struct quad_stage *qs,
unsigned
-run_llvm_fs( struct sp_fragment_shader *base,
+run_llvm_fs( const struct sp_fragment_shader *base,
struct foo *machine )
{
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index d90066e025..8095d662ee 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -42,7 +42,7 @@
#if defined(__i386__) || defined(__386__)
-#include "x86/rtasm/x86sse.h"
+#include "rtasm/rtasm_x86sse.h"
/* Surely this should be defined somewhere in a tgsi header:
*/
@@ -63,41 +63,6 @@ struct sp_sse_fragment_shader {
};
-/**
- * Compute quad X,Y,Z,W for the four fragments in a quad.
- *
- * This should really be part of the compiled shader.
- */
-void
-sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
- float x, float y,
- struct tgsi_exec_vector *quadpos)
-{
- uint chan;
- /* do X */
- quadpos->xyzw[0].f[0] = x;
- quadpos->xyzw[0].f[1] = x + 1;
- quadpos->xyzw[0].f[2] = x;
- quadpos->xyzw[0].f[3] = x + 1;
-
- /* do Y */
- quadpos->xyzw[1].f[0] = y;
- quadpos->xyzw[1].f[1] = y;
- quadpos->xyzw[1].f[2] = y + 1;
- quadpos->xyzw[1].f[3] = y + 1;
-
- /* do Z and W for all fragments in the quad */
- for (chan = 2; chan < 4; chan++) {
- const float dadx = coef->dadx[chan];
- const float dady = coef->dady[chan];
- const float a0 = coef->a0[chan] + dadx * x + dady * y;
- quadpos->xyzw[chan].f[0] = a0;
- quadpos->xyzw[chan].f[1] = a0 + dadx;
- quadpos->xyzw[chan].f[2] = a0 + dady;
- quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
- }
-}
-
static void
fs_sse_prepare( struct sp_fragment_shader *base,
@@ -124,6 +89,9 @@ fs_sse_run( struct sp_fragment_shader *base,
(float)quad->x0, (float)quad->y0,
machine->Temps);
+ /* init kill mask */
+ machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0] = 0x0;
+
shader->func( machine->Inputs,
machine->Outputs,
machine->Consts,
diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c
index d73521ccbe..2feee5c485 100644
--- a/src/gallium/drivers/softpipe/sp_prim_setup.c
+++ b/src/gallium/drivers/softpipe/sp_prim_setup.c
@@ -476,33 +476,33 @@ static void tri_persp_coeff( struct setup_stage *setup,
* We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
*/
static void
-setup_fragcoord_coeff(struct setup_stage *setup)
+setup_fragcoord_coeff(struct setup_stage *setup, uint slot)
{
/*X*/
- setup->coef[0].a0[0] = 0;
- setup->coef[0].dadx[0] = 1.0;
- setup->coef[0].dady[0] = 0.0;
+ setup->coef[slot].a0[0] = 0;
+ setup->coef[slot].dadx[0] = 1.0;
+ setup->coef[slot].dady[0] = 0.0;
/*Y*/
if (setup->softpipe->rasterizer->origin_lower_left) {
/* y=0=bottom */
const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height;
- setup->coef[0].a0[1] = (float) (winHeight - 1);
- setup->coef[0].dady[1] = -1.0;
+ setup->coef[slot].a0[1] = (float) (winHeight - 1);
+ setup->coef[slot].dady[1] = -1.0;
}
else {
/* y=0=top */
- setup->coef[0].a0[1] = 0.0;
- setup->coef[0].dady[1] = 1.0;
+ setup->coef[slot].a0[1] = 0.0;
+ setup->coef[slot].dady[1] = 1.0;
}
- setup->coef[0].dadx[1] = 0.0;
+ setup->coef[slot].dadx[1] = 0.0;
/*Z*/
- setup->coef[0].a0[2] = setup->posCoef.a0[2];
- setup->coef[0].dadx[2] = setup->posCoef.dadx[2];
- setup->coef[0].dady[2] = setup->posCoef.dady[2];
+ setup->coef[slot].a0[2] = setup->posCoef.a0[2];
+ setup->coef[slot].dadx[2] = setup->posCoef.dadx[2];
+ setup->coef[slot].dady[2] = setup->posCoef.dady[2];
/*W*/
- setup->coef[0].a0[3] = setup->posCoef.a0[3];
- setup->coef[0].dadx[3] = setup->posCoef.dadx[3];
- setup->coef[0].dady[3] = setup->posCoef.dady[3];
+ setup->coef[slot].a0[3] = setup->posCoef.a0[3];
+ setup->coef[slot].dadx[3] = setup->posCoef.dadx[3];
+ setup->coef[slot].dady[3] = setup->posCoef.dady[3];
}
@@ -514,7 +514,7 @@ setup_fragcoord_coeff(struct setup_stage *setup)
static void setup_tri_coefficients( struct setup_stage *setup )
{
struct softpipe_context *softpipe = setup->softpipe;
- const struct pipe_shader_state *fs = &softpipe->fs->shader;
+ const struct sp_fragment_shader *spfs = softpipe->fs;
const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
uint fragSlot;
@@ -525,7 +525,7 @@ static void setup_tri_coefficients( struct setup_stage *setup )
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) {
const uint vertSlot = vinfo->src_index[fragSlot];
uint j;
@@ -543,14 +543,13 @@ static void setup_tri_coefficients( struct setup_stage *setup )
tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_POS:
- assert(fragSlot == 0);
- setup_fragcoord_coeff(setup);
+ setup_fragcoord_coeff(setup, fragSlot);
break;
default:
assert(0);
}
- if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
/* FOG.y = front/back facing XXX fix this */
setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing;
setup->coef[fragSlot].dadx[1] = 0.0;
@@ -758,7 +757,7 @@ static INLINE void
setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
{
struct softpipe_context *softpipe = setup->softpipe;
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
+ const struct sp_fragment_shader *spfs = softpipe->fs;
const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
uint fragSlot;
@@ -780,7 +779,7 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
/* setup interpolation for all the remaining attributes:
*/
- for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) {
const uint vertSlot = vinfo->src_index[fragSlot];
uint j;
@@ -798,15 +797,13 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_POS:
- assert(fragSlot == 0);
- assert(0); /* XXX fix this: */
- setup_fragcoord_coeff(setup);
+ setup_fragcoord_coeff(setup, fragSlot);
break;
default:
assert(0);
}
- if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
/* FOG.y = front/back facing XXX fix this */
setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing;
setup->coef[fragSlot].dadx[1] = 0.0;
@@ -970,7 +967,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
{
struct setup_stage *setup = setup_stage( stage );
struct softpipe_context *softpipe = setup->softpipe;
- const struct pipe_shader_state *fs = &softpipe->fs->shader;
+ const struct sp_fragment_shader *spfs = softpipe->fs;
const struct vertex_header *v0 = prim->v[0];
const int sizeAttr = setup->softpipe->psize_slot;
const float size
@@ -1005,7 +1002,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
const_coeff(setup, &setup->posCoef, 0, 2);
const_coeff(setup, &setup->posCoef, 0, 3);
- for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
+ for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) {
const uint vertSlot = vinfo->src_index[fragSlot];
uint j;
@@ -1022,15 +1019,13 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
&setup->coef[fragSlot], vertSlot, j);
break;
case INTERP_POS:
- assert(fragSlot == 0);
- assert(0); /* XXX fix this: */
- setup_fragcoord_coeff(setup);
+ setup_fragcoord_coeff(setup, fragSlot);
break;
default:
assert(0);
}
- if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
+ if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) {
/* FOG.y = front/back facing XXX fix this */
setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing;
setup->coef[fragSlot].dadx[1] = 0.0;
@@ -1168,9 +1163,13 @@ static void setup_begin( struct draw_stage *stage )
{
struct setup_stage *setup = setup_stage(stage);
struct softpipe_context *sp = setup->softpipe;
- const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
+ const struct sp_fragment_shader *fs = setup->softpipe->fs;
- setup->quad.nr_attrs = fs->num_inputs;
+ if (sp->dirty) {
+ softpipe_update_derived(sp);
+ }
+
+ setup->quad.nr_attrs = fs->info.num_inputs;
sp->quad.first->begin(sp->quad.first);
diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c
index 6bd468a51c..8603c1a367 100644
--- a/src/gallium/drivers/softpipe/sp_quad.c
+++ b/src/gallium/drivers/softpipe/sp_quad.c
@@ -56,11 +56,12 @@ sp_build_depth_stencil(
void
sp_build_quad_pipeline(struct softpipe_context *sp)
{
- boolean early_depth_test =
+ boolean early_depth_test =
sp->depth_stencil->depth.enabled &&
sp->framebuffer.zsbuf &&
!sp->depth_stencil->alpha.enabled &&
- sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION;
+ !sp->fs->info.uses_kill &&
+ !sp->fs->info.writes_z;
/* build up the pipeline in reverse order... */
@@ -112,7 +113,9 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
sp_push_quad_first( sp, sp->quad.earlyz );
}
+#if !USE_DRAW_STAGE_PSTIPPLE
if (sp->rasterizer->poly_stipple_enable) {
sp_push_quad_first( sp, sp->quad.polygon_stipple );
}
+#endif
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index cf1b1eff75..1fbb2e38c4 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -91,7 +91,7 @@ shade_quad(
/* store result color */
if (qss->colorOutSlot >= 0) {
/* XXX need to handle multiple color outputs someday */
- assert(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot]
+ assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
== TGSI_SEMANTIC_COLOR);
memcpy(
quad->outputs.color,
@@ -142,14 +142,14 @@ static void shade_begin(struct quad_stage *qs)
/* set TGSI sampler state that varies */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
qss->samplers[i].state = softpipe->sampler[i];
- qss->samplers[i].texture = &softpipe->texture[i]->base;
+ qss->samplers[i].texture = softpipe->texture[i];
}
/* find output slots for depth, color */
qss->colorOutSlot = -1;
qss->depthOutSlot = -1;
- for (i = 0; i < qss->stage.softpipe->fs->shader.num_outputs; i++) {
- switch (qss->stage.softpipe->fs->shader.output_semantic_name[i]) {
+ for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
+ switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
qss->depthOutSlot = i;
break;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
new file mode 100644
index 0000000000..1850a1ced3
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -0,0 +1,165 @@
+/**************************************************************************
+ *
+ * Copyright 2008 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.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
+#include "sp_texture.h"
+#include "sp_winsys.h"
+
+
+static const char *
+softpipe_get_vendor(struct pipe_screen *screen)
+{
+ return "Tungsten Graphics, Inc.";
+}
+
+
+static const char *
+softpipe_get_name(struct pipe_screen *screen)
+{
+ return "softpipe";
+}
+
+
+static int
+softpipe_get_param(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return 8;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 1;
+ case PIPE_CAP_S3TC:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 0;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return 1;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 12; /* max 2Kx2K */
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 8; /* max 128x128x128 */
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 12; /* max 2Kx2K */
+ default:
+ return 0;
+ }
+}
+
+
+static float
+softpipe_get_paramf(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 255.0; /* arbitrary */
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 255.0; /* arbitrary */
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 0.0;
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0; /* arbitrary */
+ default:
+ return 0;
+ }
+}
+
+
+/**
+ * Query format support for creating a texture, drawing surface, etc.
+ * \param format the format to test
+ * \param type one of PIPE_TEXTURE, PIPE_SURFACE
+ */
+static boolean
+softpipe_is_format_supported( struct pipe_screen *screen,
+ enum pipe_format format, uint type )
+{
+ switch (type) {
+ case PIPE_TEXTURE:
+ /* softpipe supports all texture formats */
+ return TRUE;
+ case PIPE_SURFACE:
+ /* softpipe supports all (off-screen) surface formats */
+ return TRUE;
+ default:
+ assert(0);
+ return FALSE;
+ }
+}
+
+
+static void
+softpipe_destroy_screen( struct pipe_screen *screen )
+{
+ FREE(screen);
+}
+
+
+/**
+ * Create a new pipe_screen object
+ * Note: we're not presently subclassing pipe_screen (no softpipe_screen).
+ */
+struct pipe_screen *
+softpipe_create_screen(struct pipe_winsys *winsys)
+{
+ struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+
+ if (!screen)
+ return NULL;
+
+ screen->winsys = winsys;
+
+ screen->destroy = softpipe_destroy_screen;
+
+ screen->get_name = softpipe_get_name;
+ screen->get_vendor = softpipe_get_vendor;
+ screen->get_param = softpipe_get_param;
+ screen->get_paramf = softpipe_get_paramf;
+ screen->is_format_supported = softpipe_is_format_supported;
+
+ softpipe_init_screen_texture_funcs(screen);
+
+ return screen;
+}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index ef8cf67d4c..3943d4ed2b 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -32,6 +32,7 @@
#define SP_STATE_H
#include "pipe/p_state.h"
+#include "tgsi/util/tgsi_scan.h"
#define SP_NEW_VIEWPORT 0x1
@@ -52,7 +53,6 @@
struct tgsi_sampler;
-struct tgsi_interp_coef;
struct tgsi_exec_machine;
@@ -61,16 +61,18 @@ struct tgsi_exec_machine;
* This is starting to look an awful lot like a quad pipeline stage...
*/
struct sp_fragment_shader {
- struct pipe_shader_state shader;
+ struct pipe_shader_state shader;
+
+ struct tgsi_shader_info info;
- void (*prepare)( struct sp_fragment_shader *shader,
+ void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct tgsi_sampler *samplers);
/* Run the shader - this interface will get cleaned up in the
* future:
*/
- unsigned (*run)( struct sp_fragment_shader *shader,
+ unsigned (*run)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct quad_header *quad );
diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c
index c797c0dd3b..4946c776e3 100644
--- a/src/gallium/drivers/softpipe/sp_state_clip.c
+++ b/src/gallium/drivers/softpipe/sp_state_clip.c
@@ -42,24 +42,16 @@ void softpipe_set_clip_state( struct pipe_context *pipe,
}
-
-/* Called when driver state tracker notices changes to the viewport
- * matrix:
- */
void softpipe_set_viewport_state( struct pipe_context *pipe,
const struct pipe_viewport_state *viewport )
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- softpipe->viewport = *viewport; /* struct copy */
- softpipe->dirty |= SP_NEW_VIEWPORT;
-
/* pass the viewport info to the draw module */
draw_set_viewport_state(softpipe->draw, viewport);
- /* Using tnl/ and vf/ modules is temporary while getting started.
- * Full pipe will have vertex shader, vertex fetch of its own.
- */
+ softpipe->viewport = *viewport; /* struct copy */
+ softpipe->dirty |= SP_NEW_VIEWPORT;
}
@@ -68,7 +60,9 @@ void softpipe_set_scissor_state( struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- memcpy( &softpipe->scissor, scissor, sizeof(*scissor) );
+ draw_flush(softpipe->draw);
+
+ softpipe->scissor = *scissor; /* struct copy */
softpipe->dirty |= SP_NEW_SCISSOR;
}
@@ -78,6 +72,8 @@ void softpipe_set_polygon_stipple( struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) );
+ draw_flush(softpipe->draw);
+
+ softpipe->poly_stipple = *stipple; /* struct copy */
softpipe->dirty |= SP_NEW_STIPPLE;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 9d8fd8b750..eafbaed4b9 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -35,30 +35,6 @@
/**
- * Search vertex program's outputs to find a match for the given
- * semantic name/index. Return the index of the output slot.
- *
- * Return 0 if not found. This will cause the fragment program to use
- * vertex attrib 0 (position) in the cases where the fragment program
- * attempts to use a missing vertex program output. This is an undefined
- * condition that users shouldn't hit anyway.
- */
-static int
-find_vs_output(const struct pipe_shader_state *vs,
- uint semantic_name,
- uint semantic_index)
-{
- uint i;
- for (i = 0; i < vs->num_outputs; i++) {
- if (vs->output_semantic_name[i] == semantic_name &&
- vs->output_semantic_index[i] == semantic_index)
- return i;
- }
- return 0;
-}
-
-
-/**
* Mark the current vertex layout as "invalid".
* We'll validate the vertex layout later, when we start to actually
* render a point or line or tri.
@@ -85,8 +61,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
if (vinfo->num_attribs == 0) {
/* compute vertex layout now */
- const struct pipe_shader_state *vs = &softpipe->vs->shader;
- const struct pipe_shader_state *fs = &softpipe->fs->shader;
+ const struct sp_fragment_shader *spfs = softpipe->fs;
const enum interp_mode colorInterp
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
uint i;
@@ -98,7 +73,8 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
vinfo_vbuf->num_attribs = 0;
draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
- vinfo_vbuf->size = 4 * vs->num_outputs
+ /* size in dwords or floats */
+ vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw)
+ sizeof(struct vertex_header) / 4;
}
@@ -107,29 +83,30 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
* from the vertex shader.
*/
vinfo->num_attribs = 0;
- for (i = 0; i < fs->num_inputs; i++) {
+ for (i = 0; i < spfs->info.num_inputs; i++) {
int src;
- switch (fs->input_semantic_name[i]) {
+ switch (spfs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
- src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+ src = draw_find_vs_output(softpipe->draw,
+ TGSI_SEMANTIC_POSITION, 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
break;
case TGSI_SEMANTIC_COLOR:
- src = find_vs_output(vs, TGSI_SEMANTIC_COLOR,
- fs->input_semantic_index[i]);
+ src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_COLOR,
+ spfs->info.input_semantic_index[i]);
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
break;
case TGSI_SEMANTIC_FOG:
- src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+ src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_FOG, 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
break;
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
- src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
- fs->input_semantic_index[i]);
+ src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_GENERIC,
+ spfs->info.input_semantic_index[i]);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
break;
@@ -138,7 +115,8 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
}
}
- softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+ softpipe->psize_slot = draw_find_vs_output(softpipe->draw,
+ TGSI_SEMANTIC_PSIZE, 0);
if (softpipe->psize_slot > 0) {
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
softpipe->psize_slot);
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index b0238f8173..eb641ed321 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -36,6 +36,7 @@
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "tgsi/util/tgsi_dump.h"
+#include "tgsi/util/tgsi_scan.h"
void *
@@ -45,20 +46,24 @@ softpipe_create_fs_state(struct pipe_context *pipe,
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_fragment_shader *state;
+ /* debug */
if (softpipe->dump_fs)
tgsi_dump(templ->tokens, 0);
+ /* codegen */
state = softpipe_create_fs_llvm( softpipe, templ );
- if (state)
- return state;
-
- state = softpipe_create_fs_sse( softpipe, templ );
- if (state)
- return state;
-
- state = softpipe_create_fs_exec( softpipe, templ );
+ if (!state) {
+ state = softpipe_create_fs_sse( softpipe, templ );
+ if (!state) {
+ state = softpipe_create_fs_exec( softpipe, templ );
+ }
+ }
assert(state);
+
+ /* get/save the summary info for this shader */
+ tgsi_scan_shader(templ->tokens, &state->info);
+
return state;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index 460adccec4..1d6dd17d1d 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -30,6 +30,7 @@
*/
#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
#include "draw/draw_context.h"
@@ -82,9 +83,9 @@ softpipe_set_sampler_texture(struct pipe_context *pipe,
draw_flush(softpipe->draw);
assert(unit < PIPE_MAX_SAMPLERS);
- softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */
+ pipe_texture_reference(&softpipe->texture[unit], texture);
- sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture);
+ sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture);
softpipe->dirty |= SP_NEW_TEXTURE;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index e2c6893e9f..124b18b708 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -27,7 +27,7 @@
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
*/
-#include "p_inlines.h"
+#include "pipe/p_inlines.h"
#include "sp_context.h"
#include "sp_state.h"
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 2f82fd6abe..0ced585c7f 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -332,6 +332,61 @@ 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)
+{
+ int i;
+ switch (wrapMode) {
+ case PIPE_TEX_WRAP_CLAMP:
+ i = ifloor(s);
+ return CLAMP(i, 0, (int) size-1);
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ /* fall-through */
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) );
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
+/**
+ * For RECT textures / unnormalized texcoords.
+ * 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)
+{
+ 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 = ifloor(s);
+ *i1 = *i0 + 1;
+ break;
+ 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 = ifloor(s);
+ *i1 = *i0 + 1;
+ if (*i1 > (int) size - 1)
+ *i1 = size - 1;
+ break;
+ default:
+ assert(0);
+ }
+ *a = FRAC(s);
+}
+
+
static unsigned
choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
{
@@ -415,15 +470,15 @@ compute_lambda(struct tgsi_sampler *sampler,
{
float rho, lambda;
+ assert(sampler->state->normalized_coords);
+
assert(s);
{
float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT];
dsdx = FABSF(dsdx);
dsdy = FABSF(dsdy);
- rho = MAX2(dsdx, dsdy);
- if (sampler->state->normalized_coords)
- rho *= sampler->texture->width[0];
+ rho = MAX2(dsdx, dsdy) * sampler->texture->width[0];
}
if (t) {
float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
@@ -431,9 +486,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float max;
dtdx = FABSF(dtdx);
dtdy = FABSF(dtdy);
- max = MAX2(dtdx, dtdy);
- if (sampler->state->normalized_coords)
- max *= sampler->texture->height[0];
+ max = MAX2(dtdx, dtdy) * sampler->texture->height[0];
rho = MAX2(rho, max);
}
if (p) {
@@ -442,9 +495,7 @@ compute_lambda(struct tgsi_sampler *sampler,
float max;
dpdx = FABSF(dpdx);
dpdy = FABSF(dpdy);
- max = MAX2(dpdx, dpdy);
- if (sampler->state->normalized_coords)
- max *= sampler->texture->depth[0];
+ max = MAX2(dpdx, dpdy) * sampler->texture->depth[0];
rho = MAX2(rho, max);
}
@@ -474,8 +525,24 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
{
if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
/* no mipmap selection needed */
- *imgFilter = sampler->state->mag_img_filter;
- *level0 = *level1 = (int) sampler->state->min_lod;
+ *level0 = *level1 = CLAMP((int) sampler->state->min_lod,
+ 0, (int) sampler->texture->last_level);
+
+ if (sampler->state->min_img_filter != sampler->state->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);
+ if (lambda <= 0.0) {
+ *imgFilter = sampler->state->mag_img_filter;
+ }
+ else {
+ *imgFilter = sampler->state->min_img_filter;
+ }
+ }
+ else {
+ *imgFilter = sampler->state->mag_img_filter;
+ }
}
else {
float lambda;
@@ -487,7 +554,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
/* vertex shader */
lambda = lodbias; /* not really a bias, but absolute LOD */
- if (lambda < 0.0) { /* XXX threshold depends on the filter */
+ if (lambda <= 0.0) { /* XXX threshold depends on the filter */
/* magnifying */
*imgFilter = sampler->state->mag_img_filter;
*level0 = *level1 = 0;
@@ -612,13 +679,10 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
choose_mipmap_levels(sampler, s, t, p, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
- if (sampler->state->normalized_coords) {
- width = sampler->texture->width[level0];
- height = sampler->texture->height[level0];
- }
- else {
- width = height = 1;
- }
+ assert(sampler->state->normalized_coords);
+
+ width = sampler->texture->width[level0];
+ height = sampler->texture->height[level0];
assert(width > 0);
@@ -749,14 +813,11 @@ sp_get_samples_3d(struct tgsi_sampler *sampler,
choose_mipmap_levels(sampler, s, t, p, lodbias,
&level0, &level1, &levelBlend, &imgFilter);
- if (sampler->state->normalized_coords) {
- width = sampler->texture->width[level0];
- height = sampler->texture->height[level0];
- depth = sampler->texture->depth[level0];
- }
- else {
- width = height = depth = 1;
- }
+ assert(sampler->state->normalized_coords);
+
+ width = sampler->texture->width[level0];
+ height = sampler->texture->height[level0];
+ depth = sampler->texture->depth[level0];
assert(width > 0);
assert(height > 0);
@@ -873,6 +934,73 @@ sp_get_samples_cube(struct tgsi_sampler *sampler,
}
+static void
+sp_get_samples_rect(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_2d_common(sampler, s, t, p, lodbias, rgba, faces);
+ static const uint face = 0;
+ const uint compare_func = sampler->state->compare_func;
+ unsigned level0, level1, j, imgFilter;
+ int width, height;
+ float levelBlend;
+
+ choose_mipmap_levels(sampler, s, t, p, lodbias,
+ &level0, &level1, &levelBlend, &imgFilter);
+
+ /* texture RECTS cannot be mipmapped */
+ assert(level0 == level1);
+
+ width = sampler->texture->width[level0];
+ height = sampler->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);
+ }
+ }
+ break;
+ case PIPE_TEX_FILTER_LINEAR:
+ 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]);
+ }
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
+
+
/**
* Called via tgsi_sampler::get_samples()
* Use the sampler's state setting to get a filtered RGBA value
@@ -898,15 +1026,21 @@ sp_get_samples(struct tgsi_sampler *sampler,
switch (sampler->texture->target) {
case PIPE_TEXTURE_1D:
+ assert(sampler->state->normalized_coords);
sp_get_samples_1d(sampler, s, t, p, lodbias, rgba);
break;
case PIPE_TEXTURE_2D:
- sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
+ if (sampler->state->normalized_coords)
+ sp_get_samples_2d(sampler, s, t, p, lodbias, rgba);
+ else
+ sp_get_samples_rect(sampler, s, t, p, lodbias, rgba);
break;
case PIPE_TEXTURE_3D:
+ assert(sampler->state->normalized_coords);
sp_get_samples_3d(sampler, s, t, p, lodbias, rgba);
break;
case PIPE_TEXTURE_CUBE:
+ assert(sampler->state->normalized_coords);
sp_get_samples_cube(sampler, s, t, p, lodbias, rgba);
break;
default:
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 6de7a9b543..c605ed925b 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -39,6 +39,7 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_texture.h"
+#include "sp_tile_cache.h"
/* Simple, maximally packed layout.
@@ -79,32 +80,38 @@ softpipe_texture_layout(struct softpipe_texture * spt)
}
-struct pipe_texture *
-softpipe_texture_create(struct pipe_context *pipe,
- const struct pipe_texture *templat)
+static struct pipe_texture *
+softpipe_texture_create_screen(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
+ struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
spt->base = *templat;
+ spt->base.refcount = 1;
+ spt->base.screen = screen;
softpipe_texture_layout(spt);
- spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- spt->buffer_size);
+ spt->buffer = ws->buffer_create(ws, 32,
+ PIPE_BUFFER_USAGE_PIXEL,
+ spt->buffer_size);
if (!spt->buffer) {
FREE(spt);
return NULL;
}
+ assert(spt->base.refcount == 1);
+
return &spt->base;
}
-void
-softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+static void
+softpipe_texture_release_screen(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -120,7 +127,7 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
- pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL);
+ pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
FREE(spt);
}
@@ -128,24 +135,22 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
}
-/**
- * Called via pipe->get_tex_surface()
- */
-struct pipe_surface *
-softpipe_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+static struct pipe_surface *
+softpipe_get_tex_surface_screen(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
{
+ struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps;
assert(level <= pt->last_level);
- ps = pipe->winsys->surface_alloc(pipe->winsys);
+ ps = ws->surface_alloc(ws);
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
- pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer);
+ pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
@@ -157,10 +162,41 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
(pt->compressed ? ps->height/4 : ps->height) *
ps->width * ps->cpp;
- } else {
+ }
+ else {
assert(face == 0);
assert(zslice == 0);
}
}
return ps;
}
+
+
+static void
+softpipe_texture_update(struct pipe_context *pipe,
+ struct pipe_texture *texture)
+{
+ struct softpipe_context *softpipe = softpipe_context(pipe);
+ uint unit;
+ for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) {
+ if (softpipe->texture[unit] == texture) {
+ sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
+ }
+ }
+}
+
+
+void
+softpipe_init_texture_funcs( struct softpipe_context *softpipe )
+{
+ softpipe->pipe.texture_update = softpipe_texture_update;
+}
+
+
+void
+softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
+{
+ screen->texture_create = softpipe_texture_create_screen;
+ screen->texture_release = softpipe_texture_release_screen;
+ screen->get_tex_surface = softpipe_get_tex_surface_screen;
+}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index fa646c0de9..a7322144e6 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -29,8 +29,12 @@
#define SP_TEXTURE_H
+#include "pipe/p_state.h"
+
+
struct pipe_context;
-struct pipe_texture;
+struct pipe_screen;
+struct softpipe_context;
struct softpipe_texture
@@ -54,18 +58,12 @@ softpipe_texture(struct pipe_texture *pt)
}
+extern void
+softpipe_init_texture_funcs( struct softpipe_context *softpipe );
-extern struct pipe_texture *
-softpipe_texture_create(struct pipe_context *pipe,
- const struct pipe_texture *templat);
extern void
-softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
-
-extern struct pipe_surface *
-softpipe_get_tex_surface(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice);
+softpipe_init_screen_texture_funcs(struct pipe_screen *screen);
#endif /* SP_TEXTURE */
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index dde3fabc81..4caf2dd3fc 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -212,14 +212,15 @@ sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
* Specify the texture to cache.
*/
void
-sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
+sp_tile_cache_set_texture(struct pipe_context *pipe,
+ struct softpipe_tile_cache *tc,
struct pipe_texture *texture)
{
uint i;
assert(!tc->surface);
- tc->texture = texture;
+ pipe_texture_reference(&tc->texture, texture);
if (tc->tex_surf_map) {
pipe_surface_unmap(tc->tex_surf);
@@ -358,30 +359,37 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
struct pipe_surface *ps = tc->surface;
int inuse = 0, pos;
- if (!ps || !ps->buffer)
- return;
-
- 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(pipe, ps,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
- tile->data.depth32, 0/*STRIDE*/);
- }
- else {
- pipe_put_tile_rgba(pipe, ps,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ if (ps && ps->buffer) {
+ /* caching a drawing surface */
+ 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(pipe, ps,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->data.depth32, 0/*STRIDE*/);
+ }
+ else {
+ pipe_put_tile_rgba(pipe, ps,
+ tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ (float *) tile->data.color);
+ }
+ tile->x = tile->y = -1; /* mark as empty */
+ inuse++;
}
- tile->x = tile->y = -1; /* mark as empty */
- inuse++;
}
- }
#if TILE_CLEAR_OPTIMIZATION
- sp_tile_cache_flush_clear(&softpipe->pipe, tc);
+ sp_tile_cache_flush_clear(&softpipe->pipe, tc);
#endif
+ }
+ else if (tc->texture) {
+ /* caching a texture, mark all entries as embpy */
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ tc->entries[pos].x = -1;
+ }
+ tc->tex_face = -1;
+ }
#if 0
debug_printf("flushed tiles in use: %d\n", inuse);
@@ -481,6 +489,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
struct softpipe_tile_cache *tc, int x, int y, int z,
int face, int level)
{
+ struct pipe_screen *screen = pipe->screen;
/* tile pos in framebuffer: */
const int tile_x = x & ~(TILE_SIZE - 1);
const int tile_y = y & ~(TILE_SIZE - 1);
@@ -506,7 +515,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
if (tc->tex_surf_map)
pipe_surface_unmap(tc->tex_surf);
- tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
+ tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z);
tc->tex_surf_map = pipe_surface_map(tc->tex_surf);
tc->tex_face = face;
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index 7fd1081286..2631e29a3a 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -80,7 +80,8 @@ extern void
sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
+sp_tile_cache_set_texture(struct pipe_context *pipe,
+ struct softpipe_tile_cache *tc,
struct pipe_texture *texture);
extern void
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
index d6b379f58c..fc372dba27 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_winsys.h
@@ -46,12 +46,18 @@ struct softpipe_winsys {
};
+struct pipe_screen;
struct pipe_winsys;
struct pipe_context;
-struct pipe_context *softpipe_create( struct pipe_winsys *,
+struct pipe_context *softpipe_create( struct pipe_screen *,
+ struct pipe_winsys *,
struct softpipe_winsys * );
+struct pipe_screen *
+softpipe_create_screen(struct pipe_winsys *);
+
+
#endif /* SP_WINSYS_H */