summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/cell/ppu/Makefile1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_buffer.c118
-rw-r--r--src/gallium/drivers/cell/ppu/cell_buffer.h (renamed from src/gallium/drivers/cell/ppu/cell_winsys.h)42
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c66
-rw-r--r--src/gallium/drivers/cell/ppu/cell_fence.c8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c22
-rw-r--r--src/gallium/drivers/cell/ppu/cell_public.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c49
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.h22
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c5
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c18
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_vertex.c42
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c147
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h19
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.h3
-rw-r--r--src/gallium/drivers/failover/fo_state.c65
-rw-r--r--src/gallium/drivers/failover/fo_state_emit.c10
-rw-r--r--src/gallium/drivers/i915/i915_context.c1
-rw-r--r--src/gallium/drivers/i915/i915_context.h21
-rw-r--r--src/gallium/drivers/i915/i915_debug_fp.c1
-rw-r--r--src/gallium/drivers/i915/i915_screen.c6
-rw-r--r--src/gallium/drivers/i915/i915_state.c38
-rw-r--r--src/gallium/drivers/i915/i915_texture.c141
-rw-r--r--src/gallium/drivers/i915/intel_winsys.h39
-rw-r--r--src/gallium/drivers/i965/brw_context.h5
-rw-r--r--src/gallium/drivers/i965/brw_draw_upload.c208
-rw-r--r--src/gallium/drivers/i965/brw_pipe_vertex.c247
-rw-r--r--src/gallium/drivers/i965/brw_screen.c6
-rw-r--r--src/gallium/drivers/i965/brw_screen.h13
-rw-r--r--src/gallium/drivers/i965/brw_screen_texture.c258
-rw-r--r--src/gallium/drivers/i965/brw_structs.h4
-rw-r--r--src/gallium/drivers/i965/brw_winsys.h32
-rw-r--r--src/gallium/drivers/identity/id_context.c128
-rw-r--r--src/gallium/drivers/identity/id_drm.c59
-rw-r--r--src/gallium/drivers/identity/id_objects.c18
-rw-r--r--src/gallium/drivers/identity/id_objects.h8
-rw-r--r--src/gallium/drivers/identity/id_screen.c137
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_public.h10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c31
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c21
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c129
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h18
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c35
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_format.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c51
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c79
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_winsys.h125
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c75
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h12
-rw-r--r--src/gallium/drivers/nouveau/nouveau_util.h100
-rw-r--r--src/gallium/drivers/nouveau/nv04_surface_2d.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_context.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_context.h9
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c7
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.h3
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c34
-rw-r--r--src/gallium/drivers/nv30/nv30_state.h4
-rw-r--r--src/gallium/drivers/nv30/nv30_transfer.c24
-rw-r--r--src/gallium/drivers/nv30/nv30_vbo.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_context.c1
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h10
-rw-r--r--src/gallium/drivers/nv40/nv40_miptree.c7
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c1
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.h3
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c34
-rw-r--r--src/gallium/drivers/nv40/nv40_state.h4
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c2
-rw-r--r--src/gallium/drivers/nv40/nv40_transfer.c23
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c8
-rw-r--r--src/gallium/drivers/nv50/Makefile3
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c44
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h100
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c40
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c326
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c34
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c39
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c436
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c35
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c21
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c1113
-rw-r--r--src/gallium/drivers/r300/Makefile3
-rw-r--r--src/gallium/drivers/r300/SConscript1
-rw-r--r--src/gallium/drivers/r300/r300_blit.c1
-rw-r--r--src/gallium/drivers/r300/r300_context.c24
-rw-r--r--src/gallium/drivers/r300/r300_context.h37
-rw-r--r--src/gallium/drivers/r300/r300_emit.c44
-rw-r--r--src/gallium/drivers/r300/r300_flush.c6
-rw-r--r--src/gallium/drivers/r300/r300_fs.c1
-rw-r--r--src/gallium/drivers/r300/r300_render.c43
-rw-r--r--src/gallium/drivers/r300/r300_screen.c78
-rw-r--r--src/gallium/drivers/r300/r300_screen.h22
-rw-r--r--src/gallium/drivers/r300/r300_state.c344
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c200
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h53
-rw-r--r--src/gallium/drivers/r300/r300_texture.c135
-rw-r--r--src/gallium/drivers/r300/r300_texture.h6
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c276
-rw-r--r--src/gallium/drivers/r300/r300_transfer.h33
-rw-r--r--src/gallium/drivers/r300/r300_vs.c163
-rw-r--r--src/gallium/drivers/r300/r300_vs.h13
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h5
-rw-r--r--src/gallium/drivers/softpipe/Makefile5
-rw-r--r--src/gallium/drivers/softpipe/SConscript5
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.c118
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.h (renamed from src/gallium/drivers/softpipe/sp_winsys.h)70
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c97
-rw-r--r--src/gallium/drivers/softpipe/sp_fence.c70
-rw-r--r--src/gallium/drivers/softpipe/sp_fence.h40
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c80
-rw-r--r--src/gallium/drivers/softpipe/sp_public.h10
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c54
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h17
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c18
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c36
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c94
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c33
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c151
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h22
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c41
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.c245
-rw-r--r--src/gallium/drivers/svga/svga_context.h8
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c38
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c183
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.h5
-rw-r--r--src/gallium/drivers/svga/svga_state_need_swtnl.c9
-rw-r--r--src/gallium/drivers/svga/svga_state_rss.c13
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c8
-rw-r--r--src/gallium/drivers/svga/svga_state_vs.c4
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c4
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h33
-rw-r--r--src/gallium/drivers/svga/svgadump/svga_shader_dump.c4
-rw-r--r--src/gallium/drivers/trace/tr_context.c228
-rw-r--r--src/gallium/drivers/trace/tr_drm.c67
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c1
-rw-r--r--src/gallium/drivers/trace/tr_public.h45
-rw-r--r--src/gallium/drivers/trace/tr_rbug.c16
-rw-r--r--src/gallium/drivers/trace/tr_screen.c221
-rw-r--r--src/gallium/drivers/trace/tr_screen.h4
-rw-r--r--src/gallium/drivers/trace/tr_texture.c21
-rw-r--r--src/gallium/drivers/trace/tr_texture.h10
170 files changed, 4595 insertions, 4274 deletions
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile
index c92f8e5cba..8769b826b5 100644
--- a/src/gallium/drivers/cell/ppu/Makefile
+++ b/src/gallium/drivers/cell/ppu/Makefile
@@ -21,6 +21,7 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a
SOURCES = \
cell_batch.c \
+ cell_buffer.c \
cell_clear.c \
cell_context.c \
cell_draw_arrays.c \
diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.c b/src/gallium/drivers/cell/ppu/cell_buffer.c
new file mode 100644
index 0000000000..f56a28d62e
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_buffer.c
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "cell_screen.h"
+#include "cell_buffer.h"
+
+
+static void *
+cell_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct cell_buffer *cell_buf = cell_buffer(buf);
+ return cell_buf->data;
+}
+
+
+static void
+cell_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+cell_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct cell_buffer *sbuf = cell_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+cell_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct cell_buffer *buffer = CALLOC_STRUCT(cell_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+cell_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct cell_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(cell_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+void
+cell_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = cell_buffer_create;
+ screen->user_buffer_create = cell_user_buffer_create;
+ screen->buffer_map = cell_buffer_map;
+ screen->buffer_unmap = cell_buffer_unmap;
+ screen->buffer_destroy = cell_buffer_destroy;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.h b/src/gallium/drivers/cell/ppu/cell_buffer.h
index e227e065ff..ef0a8a70e5 100644
--- a/src/gallium/drivers/cell/ppu/cell_winsys.h
+++ b/src/gallium/drivers/cell/ppu/cell_buffer.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2009 VMware, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,38 +10,46 @@
* 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
+ * IN NO EVENT SHALL VMWARE 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_WINSYS_H
-#define CELL_WINSYS_H
+#ifndef SP_BUFFER_H
+#define SP_BUFFER_H
#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
-/**
- * Very simple winsys at this time.
- * Will probably eventually add SPU control info.
- */
-struct cell_winsys
+struct cell_buffer
{
- uint dummy;
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
};
+/** Cast wrapper */
+static INLINE struct cell_buffer *
+cell_buffer( struct pipe_buffer *buf )
+{
+ return (struct cell_buffer *)buf;
+}
+
+
+void
+cell_init_screen_buffer_funcs(struct pipe_screen *screen);
-#endif
+#endif /* SP_BUFFER_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 5bff9869fd..f6cb1fc9be 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -36,7 +36,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_screen.h"
#include "draw/draw_context.h"
@@ -137,7 +136,7 @@ cell_create_context(struct pipe_screen *screen,
memset(cell, 0, sizeof(*cell));
cell->winsys = NULL; /* XXX: fixme - get this from screen? */
- cell->pipe.winsys = screen->winsys;
+ cell->pipe.winsys = NULL;
cell->pipe.screen = screen;
cell->pipe.priv = priv;
cell->pipe.destroy = cell_destroy_context;
@@ -159,6 +158,7 @@ cell_create_context(struct pipe_screen *screen,
cell_init_shader_functions(cell);
cell_init_surface_functions(cell);
cell_init_vertex_functions(cell);
+ cell_init_texture_transfer_funcs(cell);
cell->draw = cell_draw_create(cell);
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index a77cc5b906..28f80b82cd 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -34,7 +34,7 @@
#include "pipe/p_defines.h"
#include "draw/draw_vertex.h"
#include "draw/draw_vbuf.h"
-#include "cell_winsys.h"
+/*#include "cell_winsys.h"*/
#include "cell/common.h"
#include "rtasm/rtasm_ppc_spe.h"
#include "tgsi/tgsi_scan.h"
@@ -93,6 +93,11 @@ struct cell_buffer_list
struct cell_buffer_node *head;
};
+struct cell_velems_state
+{
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+}
/**
* Per-context state, subclass of pipe_context.
@@ -110,6 +115,7 @@ struct cell_context
const struct pipe_rasterizer_state *rasterizer;
const struct cell_vertex_shader_state *vs;
const struct cell_fragment_shader_state *fs;
+ const struct cell_velems_state *velems;
struct spe_function logic_op;
@@ -125,8 +131,6 @@ struct cell_context
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- uint num_vertex_elements;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index bffd0fac6f..15d4e8338f 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -33,48 +33,18 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_state.h"
#include "cell_flush.h"
+#include "cell_buffer.h"
#include "draw/draw_context.h"
-static void
-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] && sp->constants[i]->size) {
- sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i],
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, sp->mapped_constants[i],
- sp->constants[i]->size);
- }
- }
-
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0,
- sp->mapped_constants[PIPE_SHADER_VERTEX],
- sp->constants[PIPE_SHADER_VERTEX]->size);
-}
-
-static void
-cell_unmap_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] && sp->constants[i]->size)
- ws->buffer_unmap(ws, sp->constants[i]);
- sp->mapped_constants[i] = NULL;
- }
-}
@@ -93,33 +63,27 @@ cell_draw_range_elements(struct pipe_context *pipe,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
{
- struct cell_context *sp = cell_context(pipe);
- struct draw_context *draw = sp->draw;
+ struct cell_context *cell = cell_context(pipe);
+ struct draw_context *draw = cell->draw;
unsigned i;
- if (sp->dirty)
- cell_update_derived( sp );
+ if (cell->dirty)
+ cell_update_derived( cell );
#if 0
- cell_map_surfaces(sp);
+ cell_map_surfaces(cell);
#endif
- cell_map_constant_buffers(sp);
/*
* Map vertex buffers
*/
- for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf = pipe_buffer_map(pipe->screen,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
+ for (i = 0; i < cell->num_vertex_buffers; i++) {
+ void *buf = cell_buffer(cell->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes = pipe_buffer_map(pipe->screen,
- indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = cell_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -134,17 +98,19 @@ cell_draw_range_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < sp->num_vertex_buffers; i++) {
+ for (i = 0; i < cell->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe_buffer_unmap(pipe->screen, indexBuffer);
}
- /* Note: leave drawing surfaces mapped */
- cell_unmap_constant_buffers(sp);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
}
diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c
index e10071529a..035ef41b89 100644
--- a/src/gallium/drivers/cell/ppu/cell_fence.c
+++ b/src/gallium/drivers/cell/ppu/cell_fence.c
@@ -92,7 +92,6 @@ cell_add_buffer_to_list(struct cell_context *cell,
struct cell_buffer_list *list,
struct pipe_buffer *buffer)
{
- struct pipe_screen *ps = cell->pipe.screen;
struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node);
/* create new list node which references the buffer, insert at head */
if (node) {
@@ -157,8 +156,13 @@ cell_add_fenced_textures(struct cell_context *cell)
printf("Adding texture %p buffer %p to list\n",
ct, ct->tiled_buffer[level]);
#endif
- if (ct->buffer)
+#if 00
+ /* XXX this needs to be fixed/restored!
+ * Maybe keep pointers to textures, not buffers.
+ */
+ if (ct->base.buffer)
cell_add_buffer_to_list(cell, list, ct->buffer);
+#endif
}
}
}
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 3d8b4409c7..dce10ae7f8 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -292,17 +292,23 @@ cell_set_sampler_textures(struct pipe_context *pipe,
static void
cell_map_surfaces(struct cell_context *cell)
{
+#if 0
struct pipe_screen *screen = cell->pipe.screen;
+#endif
uint i;
for (i = 0; i < 1; i++) {
struct pipe_surface *ps = cell->framebuffer.cbufs[i];
if (ps) {
struct cell_texture *ct = cell_texture(ps->texture);
+#if 0
cell->cbuf_map[i] = screen->buffer_map(screen,
ct->buffer,
(PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE));
+#else
+ cell->cbuf_map[i] = ct->data;
+#endif
}
}
@@ -310,10 +316,14 @@ cell_map_surfaces(struct cell_context *cell)
struct pipe_surface *ps = cell->framebuffer.zsbuf;
if (ps) {
struct cell_texture *ct = cell_texture(ps->texture);
+#if 0
cell->zsbuf_map = screen->buffer_map(screen,
ct->buffer,
(PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE));
+#else
+ cell->zsbuf_map = ct->data;
+#endif
}
}
}
@@ -325,17 +335,17 @@ cell_map_surfaces(struct cell_context *cell)
static void
cell_unmap_surfaces(struct cell_context *cell)
{
- struct pipe_screen *screen = cell->pipe.screen;
+ /*struct pipe_screen *screen = cell->pipe.screen;*/
uint i;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
struct pipe_surface *ps = cell->framebuffer.cbufs[i];
if (ps && cell->cbuf_map[i]) {
- struct cell_texture *ct = cell_texture(ps->texture);
+ /*struct cell_texture *ct = cell_texture(ps->texture);*/
assert(ps->texture);
- assert(ct->buffer);
+ /*assert(ct->buffer);*/
- screen->buffer_unmap(screen, ct->buffer);
+ /*screen->buffer_unmap(screen, ct->buffer);*/
cell->cbuf_map[i] = NULL;
}
}
@@ -343,8 +353,8 @@ cell_unmap_surfaces(struct cell_context *cell)
{
struct pipe_surface *ps = cell->framebuffer.zsbuf;
if (ps && cell->zsbuf_map) {
- struct cell_texture *ct = cell_texture(ps->texture);
- screen->buffer_unmap(screen, ct->buffer);
+ /*struct cell_texture *ct = cell_texture(ps->texture);*/
+ /*screen->buffer_unmap(screen, ct->buffer);*/
cell->zsbuf_map = NULL;
}
}
diff --git a/src/gallium/drivers/cell/ppu/cell_public.h b/src/gallium/drivers/cell/ppu/cell_public.h
new file mode 100644
index 0000000000..7e2e093565
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_public.h
@@ -0,0 +1,10 @@
+#ifndef CELL_PUBLIC_H
+#define CELL_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+cell_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index a43f8638dc..31fd963d19 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -28,7 +28,6 @@
#include "util/u_memory.h"
#include "util/u_simple_screen.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
@@ -36,7 +35,10 @@
#include "cell_context.h"
#include "cell_screen.h"
#include "cell_texture.h"
-#include "cell_winsys.h"
+#include "cell_buffer.h"
+#include "cell_public.h"
+
+#include "state_tracker/sw_winsys.h"
static const char *
@@ -134,19 +136,28 @@ cell_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
- /* cell supports most formats, XXX for now anyway */
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+
if (format == PIPE_FORMAT_DXT5_RGBA ||
format == PIPE_FORMAT_A8B8G8R8_SRGB)
return FALSE;
- else
- return TRUE;
+
+ if (tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if (!winsys->is_displaytarget_format_supported(winsys, format))
+ return FALSE;
+ }
+
+ /* This is often a lie. Pull in logic from llvmpipe to fix.
+ */
+ return TRUE;
}
static void
cell_destroy_screen( struct pipe_screen *screen )
{
- struct pipe_winsys *winsys = screen->winsys;
+ struct cell_screen *sp_screen = cell_screen(screen);
+ struct sw_winsys *winsys = sp_screen->winsys;
if(winsys->destroy)
winsys->destroy(winsys);
@@ -155,32 +166,34 @@ cell_destroy_screen( struct pipe_screen *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)
+cell_create_screen(struct sw_winsys *winsys)
{
- struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+ struct cell_screen *screen = CALLOC_STRUCT(cell_screen);
if (!screen)
return NULL;
screen->winsys = winsys;
+ screen->base.winsys = NULL;
- screen->destroy = cell_destroy_screen;
+ screen->base.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;
- screen->context_create = cell_create_context;
+ screen->base.get_name = cell_get_name;
+ screen->base.get_vendor = cell_get_vendor;
+ screen->base.get_param = cell_get_param;
+ screen->base.get_paramf = cell_get_paramf;
+ screen->base.is_format_supported = cell_is_format_supported;
+ screen->base.context_create = cell_create_context;
- cell_init_screen_texture_funcs(screen);
- u_simple_screen_init(screen);
+ cell_init_screen_texture_funcs(&screen->base);
+ cell_init_screen_buffer_funcs(&screen->base);
- return screen;
+ return &screen->base;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.h b/src/gallium/drivers/cell/ppu/cell_screen.h
index c7e15889d6..baff9d3b7d 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.h
+++ b/src/gallium/drivers/cell/ppu/cell_screen.h
@@ -30,12 +30,26 @@
#define CELL_SCREEN_H
-struct pipe_screen;
-struct pipe_winsys;
+#include "pipe/p_screen.h"
+struct sw_winsys;
-extern struct pipe_screen *
-cell_create_screen(struct pipe_winsys *winsys);
+struct cell_screen {
+ struct pipe_screen base;
+
+ struct sw_winsys *winsys;
+
+ /* Increments whenever textures are modified. Contexts can track
+ * this.
+ */
+ unsigned timestamp;
+};
+
+static INLINE struct cell_screen *
+cell_screen( struct pipe_screen *pipe )
+{
+ return (struct cell_screen *)pipe;
+}
#endif /* CELL_SCREEN_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index a59c7828ac..424e2628a9 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -245,16 +245,13 @@ cell_emit_state(struct cell_context *cell)
uint i, j;
float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float)));
uint32_t *ibuf = (uint32_t *) buf;
- const float *constants = pipe_buffer_map(cell->pipe.screen,
- cell->constants[shader],
- PIPE_BUFFER_USAGE_CPU_READ);
+ const float *constants = cell->mapped_constants[shader];
ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS;
ibuf[4] = num_const;
j = 8;
for (i = 0; i < num_const; i++) {
buf[j++] = constants[i];
}
- pipe_buffer_unmap(cell->pipe.screen, cell->constants[shader]);
}
if (cell->dirty & (CELL_NEW_FRAMEBUFFER |
diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c
index 9b2f86fdfb..9e29ddc2d4 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -28,13 +28,13 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "util/u_simple_screen.h"
#include "draw/draw_context.h"
#include "tgsi/tgsi_parse.h"
#include "cell_context.h"
#include "cell_state.h"
#include "cell_gen_fp.h"
+#include "cell_buffer.h"
/** cast wrapper */
@@ -183,17 +183,29 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs)
static void
cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_buffer *constants)
{
struct cell_context *cell = cell_context(pipe);
+ unsigned size = constants ? constants->size : 0;
+ const void *data = constants ? cell_buffer(constants)->data : NULL;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
+ if (cell->constants[shader] == constants)
+ return;
+
draw_flush(cell->draw);
/* note: reference counting */
- pipe_buffer_reference(&cell->constants[shader], buf);
+ pipe_buffer_reference(&cell->constants[shader], constants);
+
+ if(shader == PIPE_SHADER_VERTEX) {
+ draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0,
+ data, size);
+ }
+
+ cell->mapped_constants[shader] = data;
if (shader == PIPE_SHADER_VERTEX)
cell->dirty |= CELL_NEW_VS_CONSTANTS;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
index fbe55c8472..9510ea9ac2 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
@@ -32,24 +32,44 @@
#include "cell_context.h"
#include "cell_state.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
-static void
-cell_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+void *
+cell_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
- struct cell_context *cell = cell_context(pipe);
-
+ struct cell_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct cell_velems_state *) MALLOC(sizeof(struct cell_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+void
+cell_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct cell_context *cell = cell_context(pipe);
+ struct cell_velems_state *cell_velems = (struct cell_velems_state *) velems;
- memcpy(cell->vertex_element, elements, count * sizeof(elements[0]));
- cell->num_vertex_elements = count;
+ cell->velems = cell_velems;
cell->dirty |= CELL_NEW_VERTEX;
- draw_set_vertex_elements(cell->draw, count, elements);
+ if (cell_velems)
+ draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem);
+}
+
+void
+cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
}
@@ -75,5 +95,7 @@ void
cell_init_vertex_functions(struct cell_context *cell)
{
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
- cell->pipe.set_vertex_elements = cell_set_vertex_elements;
+ cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
+ cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
+ cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index fad290dfa0..c65c3b4f88 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -34,20 +34,23 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
-#include "util/u_simple_screen.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "cell_context.h"
+#include "cell_screen.h"
#include "cell_state.h"
#include "cell_texture.h"
+#include "state_tracker/sw_winsys.h"
-static void
-cell_texture_layout(struct cell_texture *ct)
+
+static boolean
+cell_texture_layout(struct pipe_screen *screen,
+ struct cell_texture *ct)
{
struct pipe_texture *pt = &ct->base;
unsigned level;
@@ -83,9 +86,34 @@ cell_texture_layout(struct cell_texture *ct)
height = u_minify(height, 1);
depth = u_minify(depth, 1);
}
+
+ ct->data = align_malloc(ct->buffer_size, 16);
+
+ return ct->data != NULL;
}
+/**
+ * Texture layout for simple color buffers.
+ */
+static boolean
+cell_displaytarget_layout(struct pipe_screen *screen,
+ struct cell_texture * ct)
+{
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+
+ /* Round up the surface size to a multiple of the tile size?
+ */
+ ct->dt = winsys->displaytarget_create(winsys,
+ ct->base.format,
+ ct->base.width0,
+ ct->base.height0,
+ 16,
+ &ct->dt_stride );
+
+ return ct->dt != NULL;
+}
+
static struct pipe_texture *
cell_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
@@ -98,31 +126,46 @@ cell_texture_create(struct pipe_screen *screen,
pipe_reference_init(&ct->base.reference, 1);
ct->base.screen = screen;
- cell_texture_layout(ct);
+ /* Create both a displaytarget (linear) and regular texture
+ * (twiddled). Convert twiddled->linear at flush_frontbuffer time.
+ */
+ if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if (!cell_displaytarget_layout(screen, ct))
+ goto fail;
+ }
- ct->buffer = screen->buffer_create(screen, 32, PIPE_BUFFER_USAGE_PIXEL,
- ct->buffer_size);
+ if (!cell_texture_layout(screen, ct))
+ goto fail;
- if (!ct->buffer) {
- FREE(ct);
- return NULL;
+ return &ct->base;
+
+fail:
+ if (ct->dt) {
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+ winsys->displaytarget_destroy(winsys, ct->dt);
}
- return &ct->base;
+ FREE(ct);
+
+ return NULL;
}
static void
cell_texture_destroy(struct pipe_texture *pt)
{
+ struct cell_screen *screen = cell_screen(pt->screen);
+ struct sw_winsys *winsys = screen->winsys;
struct cell_texture *ct = cell_texture(pt);
- if (ct->mapped) {
- pipe_buffer_unmap(ct->buffer->screen, ct->buffer);
- ct->mapped = NULL;
+ if (ct->dt) {
+ /* display target */
+ winsys->displaytarget_destroy(winsys, ct->dt);
}
- pipe_buffer_reference(&ct->buffer, NULL);
+ align_free(ct->data);
FREE(ct);
}
@@ -312,7 +355,7 @@ cell_tex_surface_destroy(struct pipe_surface *surf)
* back out for glGetTexImage).
*/
static struct pipe_transfer *
-cell_get_tex_transfer(struct pipe_screen *screen,
+cell_get_tex_transfer(struct pipe_context *ctx,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
@@ -359,7 +402,7 @@ cell_get_tex_transfer(struct pipe_screen *screen,
static void
-cell_tex_transfer_destroy(struct pipe_transfer *t)
+cell_tex_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *t)
{
struct cell_transfer *transfer = cell_transfer(t);
/* Effectively do the texture_update work here - if texture images
@@ -376,7 +419,7 @@ cell_tex_transfer_destroy(struct pipe_transfer *t)
* Return pointer to texture image data in linear layout.
*/
static void *
-cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
+cell_transfer_map(struct pipe_context *ctx, struct pipe_transfer *transfer)
{
struct cell_transfer *ctrans = cell_transfer(transfer);
struct pipe_texture *pt = transfer->texture;
@@ -389,10 +432,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
assert(transfer->texture);
- if (!ct->mapped) {
- /* map now */
- ct->mapped = pipe_buffer_map(screen, ct->buffer,
- pipe_transfer_buffer_flags(transfer));
+ if (ct->mapped == NULL) {
+ ct->mapped = ct->data;
}
/*
@@ -430,7 +471,7 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
* to tiled data.
*/
static void
-cell_transfer_unmap(struct pipe_screen *screen,
+cell_transfer_unmap(struct pipe_context *ctx,
struct pipe_transfer *transfer)
{
struct cell_transfer *ctrans = cell_transfer(transfer);
@@ -442,9 +483,8 @@ cell_transfer_unmap(struct pipe_screen *screen,
const uint stride = ct->stride[level];
if (!ct->mapped) {
- /* map now */
- ct->mapped = pipe_buffer_map(screen, ct->buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ assert(0);
+ return;
}
if (transfer->usage & PIPE_TRANSFER_WRITE) {
@@ -467,6 +507,50 @@ cell_transfer_unmap(struct pipe_screen *screen,
}
+
+/* This used to be overriden by the co-state tracker, but really needs
+ * to be active with sw_winsys.
+ *
+ * Contrasting with llvmpipe and softpipe, this is the only place
+ * where we use the ct->dt display target in any real sense.
+ *
+ * Basically just untwiddle our local data into the linear
+ * displaytarget.
+ */
+static void
+cell_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct cell_screen *screen = cell_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct cell_texture *ct = cell_texture(surface->texture);
+
+ if (!ct->dt)
+ return;
+
+ /* Need to untwiddle from our internal representation here:
+ */
+ {
+ unsigned *map = winsys->displaytarget_map(winsys, ct->dt,
+ (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE));
+ unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]);
+
+ untwiddle_image_uint(surface->width,
+ surface->height,
+ TILE_SIZE,
+ map,
+ ct->dt_stride,
+ src);
+
+ winsys->displaytarget_unmap(winsys, ct->dt);
+ }
+
+ winsys->displaytarget_display(winsys, ct->dt, context_private);
+}
+
+
void
cell_init_screen_texture_funcs(struct pipe_screen *screen)
{
@@ -476,9 +560,14 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen)
screen->get_tex_surface = cell_get_tex_surface;
screen->tex_surface_destroy = cell_tex_surface_destroy;
- screen->get_tex_transfer = cell_get_tex_transfer;
- screen->tex_transfer_destroy = cell_tex_transfer_destroy;
+ screen->flush_frontbuffer = cell_flush_frontbuffer;
+}
- screen->transfer_map = cell_transfer_map;
- screen->transfer_unmap = cell_transfer_unmap;
+void
+cell_init_texture_transfer_funcs(struct cell_context *cell)
+{
+ cell->pipe.get_tex_transfer = cell_get_tex_transfer;
+ cell->pipe.tex_transfer_destroy = cell_tex_transfer_destroy;
+ cell->pipe.transfer_map = cell_transfer_map;
+ cell->pipe.transfer_unmap = cell_transfer_unmap;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h
index 3ffc0bfdb5..ac0b916775 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.h
+++ b/src/gallium/drivers/cell/ppu/cell_texture.h
@@ -28,6 +28,7 @@
#ifndef CELL_TEXTURE_H
#define CELL_TEXTURE_H
+#include "cell/common.h"
struct cell_context;
struct pipe_texture;
@@ -43,8 +44,20 @@ struct cell_texture
unsigned long level_offset[CELL_MAX_TEXTURE_LEVELS];
unsigned long stride[CELL_MAX_TEXTURE_LEVELS];
- /** The tiled texture data is held in this buffer */
- struct pipe_buffer *buffer;
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
+ */
+ struct sw_displaytarget *dt;
+ unsigned dt_stride;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
+ */
+ void *data;
+
+ /* Size of the linear buffer??
+ */
unsigned long buffer_size;
/** The buffer above, mapped. This is the memory from which the
@@ -82,5 +95,7 @@ cell_transfer(struct pipe_transfer *pt)
extern void
cell_init_screen_texture_funcs(struct pipe_screen *screen);
+extern void
+cell_init_texture_transfer_funcs(struct cell_context *cell);
#endif /* CELL_TEXTURE_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
index cf8cd41159..3d389d6ea3 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
@@ -31,7 +31,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_math.h"
#include "cell_context.h"
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 2ccc5d3e60..659e40cbf0 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -27,7 +27,6 @@
#include "pipe/p_defines.h"
-#include "util/u_simple_screen.h"
#include "util/u_memory.h"
#include "pipe/p_context.h"
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index bb1a168ea7..4a754465bb 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -78,6 +78,7 @@ struct failover_context {
const struct fo_state *rasterizer;
const struct fo_state *fragment_shader;
const struct fo_state *vertex_shader;
+ const struct fo_state *vertex_elements;
struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref;
@@ -89,10 +90,8 @@ struct failover_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
- uint num_vertex_elements;
void *sw_sampler_state[PIPE_MAX_SAMPLERS];
void *hw_sampler_state[PIPE_MAX_SAMPLERS];
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index 970606a3f5..0247fb803b 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -255,9 +255,52 @@ failover_delete_vs_state(struct pipe_context *pipe,
free(state);
}
+
+
+static void *
+failover_create_vertex_elements_state( struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *velems )
+{
+ struct fo_state *state = malloc(sizeof(struct fo_state));
+ struct failover_context *failover = failover_context(pipe);
+
+ state->sw_state = failover->sw->create_vertex_elements_state(failover->sw, count, velems);
+ state->hw_state = failover->hw->create_vertex_elements_state(failover->hw, count, velems);
+
+ return state;
+}
+
+static void
+failover_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems )
+{
+ struct failover_context *failover = failover_context(pipe);
+ struct fo_state *state = (struct fo_state*)velems;
+
+ failover->vertex_elements = state;
+ failover->dirty |= FO_NEW_VERTEX_ELEMENT;
+ failover->sw->bind_vertex_elements_state( failover->sw, velems );
+ failover->hw->bind_vertex_elements_state( failover->hw, velems );
+}
+
+static void
+failover_delete_vertex_elements_state( struct pipe_context *pipe,
+ void *velems )
+{
+ struct fo_state *state = (struct fo_state*)velems;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->delete_vertex_elements_state(failover->sw, state->sw_state);
+ failover->hw->delete_vertex_elements_state(failover->hw, state->hw_state);
+ state->sw_state = 0;
+ state->hw_state = 0;
+ free(state);
+}
+
static void
failover_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
+ const struct pipe_poly_stipple *stipple )
{
struct failover_context *failover = failover_context(pipe);
@@ -490,22 +533,6 @@ failover_set_vertex_buffers(struct pipe_context *pipe,
}
-static void
-failover_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *vertex_elements)
-{
- struct failover_context *failover = failover_context(pipe);
-
- memcpy(failover->vertex_elements, vertex_elements,
- count * sizeof(vertex_elements[0]));
-
- failover->dirty |= FO_NEW_VERTEX_ELEMENT;
- failover->num_vertex_elements = count;
- failover->sw->set_vertex_elements( failover->sw, count, vertex_elements );
- failover->hw->set_vertex_elements( failover->hw, count, vertex_elements );
-}
-
void
failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
@@ -543,6 +570,9 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.create_vs_state = failover_create_vs_state;
failover->pipe.bind_vs_state = failover_bind_vs_state;
failover->pipe.delete_vs_state = failover_delete_vs_state;
+ failover->pipe.create_vertex_elements_state = failover_create_vertex_elements_state;
+ failover->pipe.bind_vertex_elements_state = failover_bind_vertex_elements_state;
+ failover->pipe.delete_vertex_elements_state = failover_delete_vertex_elements_state;
failover->pipe.set_blend_color = failover_set_blend_color;
failover->pipe.set_stencil_ref = failover_set_stencil_ref;
@@ -554,6 +584,5 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
- failover->pipe.set_vertex_elements = failover_set_vertex_elements;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
}
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index 5c00080842..09ca194497 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -81,6 +81,10 @@ failover_state_emit( struct failover_context *failover )
failover->sw->bind_vs_state( failover->sw,
failover->vertex_shader->sw_state );
+ if (failover->dirty & FO_NEW_VERTEX_ELEMENT)
+ failover->sw->bind_vertex_elements_state( failover->sw,
+ failover->vertex_elements->sw_state );
+
if (failover->dirty & FO_NEW_STIPPLE)
failover->sw->set_polygon_stipple( failover->sw, &failover->poly_stipple );
@@ -116,11 +120,5 @@ failover_state_emit( struct failover_context *failover )
failover->vertex_buffers );
}
- if (failover->dirty & FO_NEW_VERTEX_ELEMENT) {
- failover->sw->set_vertex_elements( failover->sw,
- failover->num_vertex_elements,
- failover->vertex_elements );
- }
-
failover->dirty = 0;
}
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 3d45a22b7e..130519ffa5 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -221,6 +221,7 @@ i915_create_context(struct pipe_screen *screen, void *priv)
i915_init_surface_functions(i915);
i915_init_state_functions(i915);
i915_init_flush_functions(i915);
+ i915_init_texture_functions(i915);
draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base);
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index da769e7b29..039165b63f 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -148,7 +148,7 @@ struct i915_state
/** Describes the current hardware vertex layout */
struct vertex_info vertex_info;
-
+
unsigned id; /* track lost context events */
};
@@ -187,6 +187,14 @@ struct i915_sampler_state {
unsigned maxlod;
};
+struct i915_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
+#define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
+#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+
struct i915_texture {
struct pipe_texture base;
@@ -199,7 +207,7 @@ struct i915_texture {
unsigned sw_tiled; /**< tiled with software flags */
unsigned hw_tiled; /**< tiled with hardware fences */
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS];
/* Explicitly store the offset of each image for each cube face or
* depth value. Pretty much have to accept that hardware formats
@@ -207,7 +215,7 @@ struct i915_texture {
* compute the offsets of depth/cube images within a mipmap level,
* so have to store them as a lookup table:
*/
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
+ unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; /**< array [depth] of offsets */
/* The data is held here:
*/
@@ -247,7 +255,6 @@ struct i915_context
unsigned num_samplers;
unsigned num_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
struct intel_batchbuffer *batch;
@@ -343,6 +350,12 @@ struct pipe_context *i915_create_context(struct pipe_screen *screen,
/***********************************************************************
+ * i915_texture.c
+ */
+void i915_init_texture_functions(struct i915_context *i915 );
+
+
+/***********************************************************************
* Inline conversion functions. These are better-typed than the
* macros used previously:
*/
diff --git a/src/gallium/drivers/i915/i915_debug_fp.c b/src/gallium/drivers/i915/i915_debug_fp.c
index 066e7392d1..f41c51f299 100644
--- a/src/gallium/drivers/i915/i915_debug_fp.c
+++ b/src/gallium/drivers/i915/i915_debug_fp.c
@@ -28,7 +28,6 @@
#include "i915_reg.h"
#include "i915_debug.h"
-#include "util/u_simple_screen.h"
#include "util/u_debug.h"
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 72bd263550..e5bf4a20bd 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -116,11 +116,11 @@ i915_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
+ return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return I915_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
+ return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 62169918e2..377d8425a5 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -742,21 +742,45 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(i915->draw, count, buffers);
}
-static void i915_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+static void *
+i915_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct i915_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+static void
+i915_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct i915_context *i915 = i915_context(pipe);
+ struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
+
/* Because we change state before the draw_set_vertex_buffers call
* we need a flush here, just to be sure.
*/
draw_flush(i915->draw);
- i915->num_vertex_elements = count;
/* pass-through to draw module */
- draw_set_vertex_elements(i915->draw, count, elements);
+ if (i915_velems) {
+ draw_set_vertex_elements(i915->draw,
+ i915_velems->count, i915_velems->velem);
+ }
}
+static void
+i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
i915_init_state_functions( struct i915_context *i915 )
@@ -782,6 +806,9 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.create_vs_state = i915_create_vs_state;
i915->base.bind_vs_state = i915_bind_vs_state;
i915->base.delete_vs_state = i915_delete_vs_state;
+ i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
+ i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
+ i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
i915->base.set_blend_color = i915_set_blend_color;
i915->base.set_stencil_ref = i915_set_stencil_ref;
@@ -794,5 +821,4 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_fragment_sampler_textures = i915_set_sampler_textures;
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
- i915->base.set_vertex_elements = i915_set_vertex_elements;
}
diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c
index 7ba222c78b..b252fb5330 100644
--- a/src/gallium/drivers/i915/i915_texture.c
+++ b/src/gallium/drivers/i915/i915_texture.c
@@ -96,7 +96,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
unsigned nr_images,
unsigned w, unsigned h, unsigned d)
{
- assert(level < PIPE_MAX_TEXTURE_LEVELS);
+ assert(level < Elements(tex->nr_images));
tex->nr_images[level] = nr_images;
@@ -219,12 +219,12 @@ i915_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
/* used for scanouts that need special layouts */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
- /* for shared buffers we use something very like scanout */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ /* shared buffers needs to be compatible with X servers */
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@@ -369,12 +369,12 @@ i945_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
/* used for scanouts that need special layouts */
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
- /* for shared buffers we use some very like scanout */
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ /* shared buffers needs to be compatible with X servers */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@@ -642,7 +642,7 @@ i915_texture_create(struct pipe_screen *screen,
/* for scanouts and cursors, cursors arn't scanouts */
- if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64)
+ if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64)
buf_usage = INTEL_NEW_SCANOUT;
else
buf_usage = INTEL_NEW_TEXTURE;
@@ -673,19 +673,24 @@ fail:
}
static struct pipe_texture *
-i915_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+i915_texture_from_handle(struct pipe_screen * screen,
+ const struct pipe_texture *templat,
+ struct winsys_handle *whandle)
{
-#if 0
+ struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex;
+ struct intel_winsys *iws = is->iws;
+ struct intel_buffer *buffer;
+ unsigned stride;
+
assert(screen);
+ buffer = iws->buffer_from_handle(iws, whandle, &stride);
+
/* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
+ if (templat->target != PIPE_TEXTURE_2D ||
+ templat->last_level != 0 ||
+ templat->depth0 != 1) {
return NULL;
}
@@ -693,23 +698,33 @@ i915_texture_blanket(struct pipe_screen * screen,
if (!tex)
return NULL;
- tex->base = *base;
+ tex->base = *templat;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
- tex->stride = stride[0];
+ tex->stride = stride;
- i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
+ i915_miptree_set_level_info(tex, 0, 1, templat->width0, templat->height0, 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
- pipe_buffer_reference(&tex->buffer, buffer);
+ tex->buffer = buffer;
return &tex->base;
-#else
- return NULL;
-#endif
}
+static boolean
+i915_texture_get_handle(struct pipe_screen * screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct i915_screen *is = i915_screen(screen);
+ struct i915_texture *tex = (struct i915_texture *)texture;
+ struct intel_winsys *iws = is->iws;
+
+ return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride);
+}
+
+
static void
i915_texture_destroy(struct pipe_texture *pt)
{
@@ -723,7 +738,7 @@ i915_texture_destroy(struct pipe_texture *pt)
iws->buffer_destroy(iws, tex->buffer);
- for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ for (i = 0; i < Elements(tex->image_offset); i++)
if (tex->image_offset[i])
FREE(tex->image_offset[i]);
@@ -780,12 +795,12 @@ i915_tex_surface_destroy(struct pipe_surface *surf)
/*
- * Screen transfer functions
+ * Texture transfer functions
*/
-static struct pipe_transfer*
-i915_get_tex_transfer(struct pipe_screen *screen,
+static struct pipe_transfer *
+i915_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage, unsigned x, unsigned y,
@@ -822,7 +837,7 @@ i915_get_tex_transfer(struct pipe_screen *screen,
}
static void *
-i915_transfer_map(struct pipe_screen *screen,
+i915_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
@@ -844,7 +859,7 @@ i915_transfer_map(struct pipe_screen *screen,
}
static void
-i915_transfer_unmap(struct pipe_screen *screen,
+i915_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
@@ -853,7 +868,8 @@ i915_transfer_unmap(struct pipe_screen *screen,
}
static void
-i915_tex_transfer_destroy(struct pipe_transfer *trans)
+i915_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *trans)
{
pipe_texture_reference(&trans->texture, NULL);
FREE(trans);
@@ -864,67 +880,22 @@ i915_tex_transfer_destroy(struct pipe_transfer *trans)
* Other texture functions
*/
+void
+i915_init_texture_functions(struct i915_context *i915 )
+{
+ i915->base.get_tex_transfer = i915_get_tex_transfer;
+ i915->base.transfer_map = i915_transfer_map;
+ i915->base.transfer_unmap = i915_transfer_unmap;
+ i915->base.tex_transfer_destroy = i915_tex_transfer_destroy;
+}
void
i915_init_screen_texture_functions(struct i915_screen *is)
{
is->base.texture_create = i915_texture_create;
- is->base.texture_blanket = i915_texture_blanket;
+ is->base.texture_from_handle = i915_texture_from_handle;
+ is->base.texture_get_handle = i915_texture_get_handle;
is->base.texture_destroy = i915_texture_destroy;
is->base.get_tex_surface = i915_get_tex_surface;
is->base.tex_surface_destroy = i915_tex_surface_destroy;
- is->base.get_tex_transfer = i915_get_tex_transfer;
- is->base.transfer_map = i915_transfer_map;
- is->base.transfer_unmap = i915_transfer_unmap;
- is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
-}
-
-struct pipe_texture *
-i915_texture_blanket_intel(struct pipe_screen *screen,
- struct pipe_texture *base,
- unsigned stride,
- struct intel_buffer *buffer)
-{
- struct i915_texture *tex;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- tex = CALLOC_STRUCT(i915_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- tex->stride = stride;
-
- i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
- i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
-
- tex->buffer = buffer;
-
- return &tex->base;
-}
-
-boolean
-i915_get_texture_buffer_intel(struct pipe_texture *texture,
- struct intel_buffer **buffer,
- unsigned *stride)
-{
- struct i915_texture *tex = (struct i915_texture *)texture;
-
- if (!texture)
- return FALSE;
-
- *stride = tex->stride;
- *buffer = tex->buffer;
-
- return TRUE;
}
diff --git a/src/gallium/drivers/i915/intel_winsys.h b/src/gallium/drivers/i915/intel_winsys.h
index b3a802b0e2..00fd0c1efe 100644
--- a/src/gallium/drivers/i915/intel_winsys.h
+++ b/src/gallium/drivers/i915/intel_winsys.h
@@ -33,6 +33,7 @@ struct intel_buffer;
struct intel_batchbuffer;
struct pipe_texture;
struct pipe_fence_handle;
+struct winsys_handle;
enum intel_buffer_usage
{
@@ -129,6 +130,25 @@ struct intel_winsys {
enum intel_buffer_type type);
/**
+ * Creates a buffer from a handle.
+ * Used to implement pipe_screen::texture_from_handle.
+ * Also provides the stride information needed for the
+ * texture via the stride argument.
+ */
+ struct intel_buffer *(*buffer_from_handle)(struct intel_winsys *iws,
+ struct winsys_handle *whandle,
+ unsigned *stride);
+
+ /**
+ * Used to implement pipe_screen::texture_get_handle.
+ * The winsys might need the stride information.
+ */
+ boolean (*buffer_get_handle)(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride);
+
+ /**
* Fence a buffer with a fence reg.
* Not to be confused with pipe_fence_handle.
*/
@@ -204,23 +224,4 @@ struct intel_winsys {
struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
-/**
- * Get the intel_winsys buffer backing the texture.
- *
- * TODO UGLY
- */
-boolean i915_get_texture_buffer_intel(struct pipe_texture *texture,
- struct intel_buffer **buffer,
- unsigned *stride);
-
-/**
- * Wrap a intel_winsys buffer with a texture blanket.
- *
- * TODO UGLY
- */
-struct pipe_texture * i915_texture_blanket_intel(struct pipe_screen *screen,
- struct pipe_texture *tmplt,
- unsigned pitch,
- struct intel_buffer *buffer);
-
#endif
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
index 12cfa7b049..f5b1a06576 100644
--- a/src/gallium/drivers/i965/brw_context.h
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -351,7 +351,7 @@ struct brw_vs_prog_data {
/* Size == 0 if output either not written, or always [0,0,0,1]
*/
-struct brw_vs_ouput_sizes {
+struct brw_vs_output_sizes {
GLubyte output_size[PIPE_MAX_SHADER_OUTPUTS];
};
@@ -546,14 +546,13 @@ struct brw_context
const struct brw_blend_state *blend;
const struct brw_rasterizer_state *rast;
const struct brw_depth_stencil_state *zstencil;
+ const struct brw_vertex_element_packet *velems;
const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
unsigned num_samplers;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- unsigned num_vertex_elements;
unsigned num_textures;
unsigned num_vertex_buffers;
diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c
index 9f136eec71..0820ba20a0 100644
--- a/src/gallium/drivers/i965/brw_draw_upload.c
+++ b/src/gallium/drivers/i965/brw_draw_upload.c
@@ -42,141 +42,6 @@
-static unsigned brw_translate_surface_format( unsigned id )
-{
- switch (id) {
- case PIPE_FORMAT_R64_FLOAT:
- return BRW_SURFACEFORMAT_R64_FLOAT;
- case PIPE_FORMAT_R64G64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64_FLOAT;
- case PIPE_FORMAT_R64G64B64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
- case PIPE_FORMAT_R64G64B64A64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
-
- case PIPE_FORMAT_R32_FLOAT:
- return BRW_SURFACEFORMAT_R32_FLOAT;
- case PIPE_FORMAT_R32G32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32_FLOAT;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
-
- case PIPE_FORMAT_R32_UNORM:
- return BRW_SURFACEFORMAT_R32_UNORM;
- case PIPE_FORMAT_R32G32_UNORM:
- return BRW_SURFACEFORMAT_R32G32_UNORM;
- case PIPE_FORMAT_R32G32B32_UNORM:
- return BRW_SURFACEFORMAT_R32G32B32_UNORM;
- case PIPE_FORMAT_R32G32B32A32_UNORM:
- return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
-
- case PIPE_FORMAT_R32_USCALED:
- return BRW_SURFACEFORMAT_R32_USCALED;
- case PIPE_FORMAT_R32G32_USCALED:
- return BRW_SURFACEFORMAT_R32G32_USCALED;
- case PIPE_FORMAT_R32G32B32_USCALED:
- return BRW_SURFACEFORMAT_R32G32B32_USCALED;
- case PIPE_FORMAT_R32G32B32A32_USCALED:
- return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
-
- case PIPE_FORMAT_R32_SNORM:
- return BRW_SURFACEFORMAT_R32_SNORM;
- case PIPE_FORMAT_R32G32_SNORM:
- return BRW_SURFACEFORMAT_R32G32_SNORM;
- case PIPE_FORMAT_R32G32B32_SNORM:
- return BRW_SURFACEFORMAT_R32G32B32_SNORM;
- case PIPE_FORMAT_R32G32B32A32_SNORM:
- return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
-
- case PIPE_FORMAT_R32_SSCALED:
- return BRW_SURFACEFORMAT_R32_SSCALED;
- case PIPE_FORMAT_R32G32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32_SSCALED;
- case PIPE_FORMAT_R32G32B32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
- case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
-
- case PIPE_FORMAT_R16_UNORM:
- return BRW_SURFACEFORMAT_R16_UNORM;
- case PIPE_FORMAT_R16G16_UNORM:
- return BRW_SURFACEFORMAT_R16G16_UNORM;
- case PIPE_FORMAT_R16G16B16_UNORM:
- return BRW_SURFACEFORMAT_R16G16B16_UNORM;
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
-
- case PIPE_FORMAT_R16_USCALED:
- return BRW_SURFACEFORMAT_R16_USCALED;
- case PIPE_FORMAT_R16G16_USCALED:
- return BRW_SURFACEFORMAT_R16G16_USCALED;
- case PIPE_FORMAT_R16G16B16_USCALED:
- return BRW_SURFACEFORMAT_R16G16B16_USCALED;
- case PIPE_FORMAT_R16G16B16A16_USCALED:
- return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
-
- case PIPE_FORMAT_R16_SNORM:
- return BRW_SURFACEFORMAT_R16_SNORM;
- case PIPE_FORMAT_R16G16_SNORM:
- return BRW_SURFACEFORMAT_R16G16_SNORM;
- case PIPE_FORMAT_R16G16B16_SNORM:
- return BRW_SURFACEFORMAT_R16G16B16_SNORM;
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
-
- case PIPE_FORMAT_R16_SSCALED:
- return BRW_SURFACEFORMAT_R16_SSCALED;
- case PIPE_FORMAT_R16G16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16_SSCALED;
- case PIPE_FORMAT_R16G16B16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
-
- case PIPE_FORMAT_R8_UNORM:
- return BRW_SURFACEFORMAT_R8_UNORM;
- case PIPE_FORMAT_R8G8_UNORM:
- return BRW_SURFACEFORMAT_R8G8_UNORM;
- case PIPE_FORMAT_R8G8B8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8_UNORM;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
-
- case PIPE_FORMAT_R8_USCALED:
- return BRW_SURFACEFORMAT_R8_USCALED;
- case PIPE_FORMAT_R8G8_USCALED:
- return BRW_SURFACEFORMAT_R8G8_USCALED;
- case PIPE_FORMAT_R8G8B8_USCALED:
- return BRW_SURFACEFORMAT_R8G8B8_USCALED;
- case PIPE_FORMAT_R8G8B8A8_USCALED:
- return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
-
- case PIPE_FORMAT_R8_SNORM:
- return BRW_SURFACEFORMAT_R8_SNORM;
- case PIPE_FORMAT_R8G8_SNORM:
- return BRW_SURFACEFORMAT_R8G8_SNORM;
- case PIPE_FORMAT_R8G8B8_SNORM:
- return BRW_SURFACEFORMAT_R8G8B8_SNORM;
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
- case PIPE_FORMAT_R8_SSCALED:
- return BRW_SURFACEFORMAT_R8_SSCALED;
- case PIPE_FORMAT_R8G8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8_SSCALED;
- case PIPE_FORMAT_R8G8B8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
- case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
-
- default:
- assert(0);
- return 0;
- }
-}
-
static unsigned get_index_type(int type)
{
switch (type) {
@@ -315,75 +180,16 @@ static int brw_emit_vertex_buffers( struct brw_context *brw )
-
static int brw_emit_vertex_elements(struct brw_context *brw)
{
- GLuint nr = brw->curr.num_vertex_elements;
- GLuint i;
+ const struct brw_vertex_element_packet *brw_velems = brw->curr.velems;
+ unsigned size = brw_velems->header.length + 2;
+ /* why is this here */
brw_emit_query_begin(brw);
- /* If the VS doesn't read any inputs (calculating vertex position from
- * a state variable for some reason, for example), emit a single pad
- * VERTEX_ELEMENT struct and bail.
- *
- * The stale VB state stays in place, but they don't do anything unless
- * a VE loads from them.
- */
- if (nr == 0) {
- BEGIN_BATCH(3, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
- OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
- (0 << BRW_VE0_SRC_OFFSET_SHIFT));
- OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
- ADVANCE_BATCH();
- return 0;
- }
-
- /* Now emit vertex element (VEP) state packets.
- *
- */
- BEGIN_BATCH(1 + nr * 2, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr * 2) - 2));
- for (i = 0; i < nr; i++) {
- const struct pipe_vertex_element *input = &brw->curr.vertex_element[i];
- uint32_t format = brw_translate_surface_format( input->src_format );
- uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
-
- switch (input->nr_components) {
- case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
- break;
- }
-
- OUT_BATCH((input->vertex_buffer_index << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (format << BRW_VE0_FORMAT_SHIFT) |
- (input->src_offset << BRW_VE0_SRC_OFFSET_SHIFT));
+ brw_batchbuffer_data(brw->batch, brw_velems, size * 4, IGNORE_CLIPRECTS);
- if (BRW_IS_IGDNG(brw))
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT));
- else
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
- ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
- }
- ADVANCE_BATCH();
return 0;
}
@@ -396,10 +202,11 @@ static int brw_emit_vertices( struct brw_context *brw )
if (ret)
return ret;
+ /* XXX should separate this? */
ret = brw_emit_vertex_elements( brw );
if (ret)
return ret;
-
+
return 0;
}
@@ -407,7 +214,8 @@ static int brw_emit_vertices( struct brw_context *brw )
const struct brw_tracked_state brw_vertices = {
.dirty = {
.mesa = (PIPE_NEW_INDEX_RANGE |
- PIPE_NEW_VERTEX_BUFFER),
+ PIPE_NEW_VERTEX_BUFFER |
+ PIPE_NEW_VERTEX_ELEMENT),
.brw = BRW_NEW_BATCH,
.cache = 0,
},
diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c
index e3c48e3149..d6a840857e 100644
--- a/src/gallium/drivers/i965/brw_pipe_vertex.c
+++ b/src/gallium/drivers/i965/brw_pipe_vertex.c
@@ -1,22 +1,251 @@
#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
-static void brw_set_vertex_elements( struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements )
+
+static unsigned brw_translate_surface_format( unsigned id )
+{
+ switch (id) {
+ case PIPE_FORMAT_R64_FLOAT:
+ return BRW_SURFACEFORMAT_R64_FLOAT;
+ case PIPE_FORMAT_R64G64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64_FLOAT;
+ case PIPE_FORMAT_R64G64B64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
+ case PIPE_FORMAT_R64G64B64A64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
+
+ case PIPE_FORMAT_R32_FLOAT:
+ return BRW_SURFACEFORMAT_R32_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32_FLOAT;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+ case PIPE_FORMAT_R32_UNORM:
+ return BRW_SURFACEFORMAT_R32_UNORM;
+ case PIPE_FORMAT_R32G32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32_UNORM;
+ case PIPE_FORMAT_R32G32B32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32B32_UNORM;
+ case PIPE_FORMAT_R32G32B32A32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
+
+ case PIPE_FORMAT_R32_USCALED:
+ return BRW_SURFACEFORMAT_R32_USCALED;
+ case PIPE_FORMAT_R32G32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32_USCALED;
+ case PIPE_FORMAT_R32G32B32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32B32_USCALED;
+ case PIPE_FORMAT_R32G32B32A32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
+
+ case PIPE_FORMAT_R32_SNORM:
+ return BRW_SURFACEFORMAT_R32_SNORM;
+ case PIPE_FORMAT_R32G32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32_SNORM;
+ case PIPE_FORMAT_R32G32B32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32B32_SNORM;
+ case PIPE_FORMAT_R32G32B32A32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
+
+ case PIPE_FORMAT_R32_SSCALED:
+ return BRW_SURFACEFORMAT_R32_SSCALED;
+ case PIPE_FORMAT_R32G32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32_SSCALED;
+ case PIPE_FORMAT_R32G32B32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
+ case PIPE_FORMAT_R32G32B32A32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
+
+ case PIPE_FORMAT_R16_UNORM:
+ return BRW_SURFACEFORMAT_R16_UNORM;
+ case PIPE_FORMAT_R16G16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16_UNORM;
+ case PIPE_FORMAT_R16G16B16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16B16_UNORM;
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
+
+ case PIPE_FORMAT_R16_USCALED:
+ return BRW_SURFACEFORMAT_R16_USCALED;
+ case PIPE_FORMAT_R16G16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16_USCALED;
+ case PIPE_FORMAT_R16G16B16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16B16_USCALED;
+ case PIPE_FORMAT_R16G16B16A16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
+
+ case PIPE_FORMAT_R16_SNORM:
+ return BRW_SURFACEFORMAT_R16_SNORM;
+ case PIPE_FORMAT_R16G16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16_SNORM;
+ case PIPE_FORMAT_R16G16B16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16B16_SNORM;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
+
+ case PIPE_FORMAT_R16_SSCALED:
+ return BRW_SURFACEFORMAT_R16_SSCALED;
+ case PIPE_FORMAT_R16G16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16_SSCALED;
+ case PIPE_FORMAT_R16G16B16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
+ case PIPE_FORMAT_R16G16B16A16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
+
+ case PIPE_FORMAT_R8_UNORM:
+ return BRW_SURFACEFORMAT_R8_UNORM;
+ case PIPE_FORMAT_R8G8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8_UNORM;
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8_UNORM;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+
+ case PIPE_FORMAT_R8_USCALED:
+ return BRW_SURFACEFORMAT_R8_USCALED;
+ case PIPE_FORMAT_R8G8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8_USCALED;
+ case PIPE_FORMAT_R8G8B8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8B8_USCALED;
+ case PIPE_FORMAT_R8G8B8A8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
+
+ case PIPE_FORMAT_R8_SNORM:
+ return BRW_SURFACEFORMAT_R8_SNORM;
+ case PIPE_FORMAT_R8G8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8_SNORM;
+ case PIPE_FORMAT_R8G8B8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8_SNORM;
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+ case PIPE_FORMAT_R8_SSCALED:
+ return BRW_SURFACEFORMAT_R8_SSCALED;
+ case PIPE_FORMAT_R8G8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8_SSCALED;
+ case PIPE_FORMAT_R8G8B8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
+ case PIPE_FORMAT_R8G8B8A8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
+
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void brw_translate_vertex_elements(struct brw_context *brw,
+ struct brw_vertex_element_packet *brw_velems,
+ const struct pipe_vertex_element *attribs,
+ unsigned count)
+{
+ unsigned i;
+
+ /* If the VS doesn't read any inputs (calculating vertex position from
+ * a state variable for some reason, for example), emit a single pad
+ * VERTEX_ELEMENT struct and bail.
+ *
+ * The stale VB state stays in place, but they don't do anything unless
+ * a VE loads from them.
+ */
+ brw_velems->header.opcode = CMD_VERTEX_ELEMENT;
+
+ if (count == 0) {
+ brw_velems->header.length = 1;
+ brw_velems->ve[0].ve0.src_offset = 0;
+ brw_velems->ve[0].ve0.src_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+ brw_velems->ve[0].ve0.valid = 1;
+ brw_velems->ve[0].ve0.vertex_buffer_index = 0;
+ brw_velems->ve[0].ve1.dst_offset = 0;
+ brw_velems->ve[0].ve1.vfcomponent0 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent1 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent2 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+ return;
+ }
+
+
+ /* Now emit vertex element (VEP) state packets.
+ *
+ */
+ brw_velems->header.length = (1 + count * 2) - 2;
+ for (i = 0; i < count; i++) {
+ const struct pipe_vertex_element *input = &attribs[i];
+ unsigned nr_components = util_format_get_nr_components(input->src_format);
+
+ uint32_t format = brw_translate_surface_format( input->src_format );
+ uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
+
+ switch (nr_components) {
+ case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+ break;
+ }
+
+ brw_velems->ve[i].ve0.src_offset = input->src_offset;
+ brw_velems->ve[i].ve0.src_format = format;
+ brw_velems->ve[i].ve0.valid = 1;
+ brw_velems->ve[i].ve0.vertex_buffer_index = input->vertex_buffer_index;
+ brw_velems->ve[i].ve1.vfcomponent0 = comp0;
+ brw_velems->ve[i].ve1.vfcomponent1 = comp1;
+ brw_velems->ve[i].ve1.vfcomponent2 = comp2;
+ brw_velems->ve[i].ve1.vfcomponent3 = comp3;
+
+ if (BRW_IS_IGDNG(brw))
+ brw_velems->ve[i].ve1.dst_offset = 0;
+ else
+ brw_velems->ve[i].ve1.dst_offset = i * 4;
+ }
+}
+
+static void* brw_create_vertex_elements_state( struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs )
{
+ /* note: for the brw_swtnl.c code (if ever we need draw fallback) we'd also need
+ to store the original data */
struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_element_packet *velems;
+ assert(count <= BRW_VEP_MAX);
+ velems = (struct brw_vertex_element_packet *) MALLOC(sizeof(struct brw_vertex_element_packet));
+ if (velems) {
+ brw_translate_vertex_elements(brw, velems, attribs, count);
+ }
+ return velems;
+}
- memcpy(brw->curr.vertex_element, elements, count * sizeof(elements[0]));
- brw->curr.num_vertex_elements = count;
+static void brw_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_element_packet *brw_velems = (struct brw_vertex_element_packet *) velems;
+
+ brw->curr.velems = brw_velems;
brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT;
}
+static void brw_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
+
static void brw_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_buffer *buffers)
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct brw_context *brw = brw_context(pipe);
unsigned i;
@@ -49,7 +278,9 @@ void
brw_pipe_vertex_init( struct brw_context *brw )
{
brw->base.set_vertex_buffers = brw_set_vertex_buffers;
- brw->base.set_vertex_elements = brw_set_vertex_elements;
+ brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
+ brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
+ brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 66f3aad8b2..cef83ffea8 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -174,11 +174,11 @@ brw_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
+ return BRW_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return BRW_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
+ return BRW_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h
index 7226d9228b..e3a7c64d48 100644
--- a/src/gallium/drivers/i965/brw_screen.h
+++ b/src/gallium/drivers/i965/brw_screen.h
@@ -100,6 +100,9 @@ struct brw_surface
};
+#define BRW_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
+#define BRW_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+
struct brw_texture
{
@@ -107,9 +110,9 @@ struct brw_texture
struct brw_winsys_buffer *bo;
struct brw_surface_state ss;
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
- unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned *image_offset[BRW_MAX_TEXTURE_2D_LEVELS];
+ unsigned nr_images[BRW_MAX_TEXTURE_2D_LEVELS];
+ unsigned level_offset[BRW_MAX_TEXTURE_2D_LEVELS];
boolean compressed;
unsigned brw_target;
@@ -178,6 +181,10 @@ void brw_update_texture( struct brw_screen *brw_screen,
struct brw_texture *tex );
+/* brw_screen_texture.h
+ */
+struct brw_context;
+void brw_tex_init( struct brw_context *brw );
void brw_screen_tex_init( struct brw_screen *brw_screen );
void brw_screen_tex_surface_init( struct brw_screen *brw_screen );
diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c
index e38fdf1869..cadcb7cee2 100644
--- a/src/gallium/drivers/i965/brw_screen_texture.c
+++ b/src/gallium/drivers/i965/brw_screen_texture.c
@@ -37,6 +37,8 @@
#include "brw_defines.h"
#include "brw_structs.h"
#include "brw_winsys.h"
+#include "brw_context.h"
+
@@ -231,8 +233,8 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
goto fail;
- if (templ->tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ if (templ->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
buffer_type = BRW_BUFFER_TYPE_SCANOUT;
}
else {
@@ -303,14 +305,121 @@ fail:
return NULL;
}
-static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen,
- const struct pipe_texture *templ,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+static struct pipe_texture *
+brw_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle)
{
+ struct brw_screen *bscreen = brw_screen(screen);
+ struct brw_texture *tex;
+ struct brw_winsys_buffer *buffer;
+ unsigned tiling;
+ unsigned pitch;
+
+ if (templ->target != PIPE_TEXTURE_2D ||
+ templ->last_level != 0 ||
+ templ->depth0 != 1)
+ return NULL;
+
+ if (util_format_is_compressed(templ->format))
+ return NULL;
+
+ tex = CALLOC_STRUCT(brw_texture);
+ if (!tex)
+ return NULL;
+
+ if (bscreen->sws->bo_from_handle(bscreen->sws, whandle, &pitch, &tiling, &buffer) != PIPE_OK)
+ goto fail;
+
+ memcpy(&tex->base, templ, sizeof *templ);
+ pipe_reference_init(&tex->base.reference, 1);
+ tex->base.screen = screen;
+
+ /* XXX: cpp vs. blocksize
+ */
+ tex->cpp = util_format_get_blocksize(tex->base.format);
+ tex->tiling = tiling;
+
+ make_empty_list(&tex->views[0]);
+ make_empty_list(&tex->views[1]);
+
+ if (!brw_texture_layout(bscreen, tex))
+ goto fail;
+
+ /* XXX Maybe some more checks? */
+ if ((pitch / tex->cpp) < tex->pitch)
+ goto fail;
+
+ tex->pitch = pitch / tex->cpp;
+
+ tex->bo = buffer;
+
+ /* fix this warning */
+#if 0
+ if (tex->size > buffer->size)
+ goto fail;
+#endif
+
+ tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
+ tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
+ assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
+
+ /* This is ok for all textures with channel width 8bit or less:
+ */
+/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+
+
+ /* XXX: what happens when tex->bo->offset changes???
+ */
+ tex->ss.ss1.base_addr = 0; /* reloc */
+ tex->ss.ss2.mip_count = tex->base.last_level;
+ tex->ss.ss2.width = tex->base.width0 - 1;
+ tex->ss.ss2.height = tex->base.height0 - 1;
+
+ switch (tex->tiling) {
+ case BRW_TILING_NONE:
+ tex->ss.ss3.tiled_surface = 0;
+ tex->ss.ss3.tile_walk = 0;
+ break;
+ case BRW_TILING_X:
+ tex->ss.ss3.tiled_surface = 1;
+ tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+ break;
+ case BRW_TILING_Y:
+ tex->ss.ss3.tiled_surface = 1;
+ tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+ break;
+ }
+
+ tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
+ tex->ss.ss3.depth = tex->base.depth0 - 1;
+
+ tex->ss.ss4.min_lod = 0;
+
+ return &tex->base;
+
+fail:
+ FREE(tex);
return NULL;
}
+static boolean
+brw_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct brw_screen *bscreen = brw_screen(screen);
+ struct brw_texture *tex = brw_texture(texture);
+ unsigned stride;
+
+ stride = tex->pitch * tex->cpp;
+
+ return bscreen->sws->bo_get_handle(tex->bo, whandle, stride);
+}
+
+
+
static void brw_texture_destroy(struct pipe_texture *pt)
{
struct brw_texture *tex = brw_texture(pt);
@@ -372,7 +481,7 @@ boolean brw_is_texture_referenced_by_bo( struct brw_screen *brw_screen,
*/
static struct pipe_transfer*
-brw_get_tex_transfer(struct pipe_screen *screen,
+brw_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage, unsigned x, unsigned y,
@@ -407,11 +516,11 @@ brw_get_tex_transfer(struct pipe_screen *screen,
}
static void *
-brw_transfer_map(struct pipe_screen *screen,
+brw_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct brw_texture *tex = brw_texture(transfer->texture);
- struct brw_winsys_screen *sws = brw_screen(screen)->sws;
+ struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws;
char *map;
unsigned usage = transfer->usage;
@@ -434,146 +543,37 @@ brw_transfer_map(struct pipe_screen *screen,
}
static void
-brw_transfer_unmap(struct pipe_screen *screen,
+brw_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct brw_texture *tex = brw_texture(transfer->texture);
- struct brw_winsys_screen *sws = brw_screen(screen)->sws;
+ struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws;
sws->bo_unmap(tex->bo);
}
static void
-brw_tex_transfer_destroy(struct pipe_transfer *trans)
+brw_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *trans)
{
pipe_texture_reference(&trans->texture, NULL);
FREE(trans);
}
-/*
- * Functions exported to the winsys
- */
-
-boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
- struct brw_winsys_buffer **buffer,
- unsigned *stride)
-{
- struct brw_texture *tex = brw_texture(texture);
-
- *buffer = tex->bo;
- if (stride)
- *stride = tex->pitch * tex->cpp;
-
- return TRUE;
-}
-
-struct pipe_texture *
-brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
- const struct pipe_texture *templ,
- unsigned pitch,
- unsigned tiling,
- struct brw_winsys_buffer *buffer)
+void brw_tex_init( struct brw_context *brw )
{
- struct brw_screen *bscreen = brw_screen(screen);
- struct brw_texture *tex;
- GLuint format;
-
- if (templ->target != PIPE_TEXTURE_2D ||
- templ->last_level != 0 ||
- templ->depth0 != 1)
- return NULL;
-
- if (util_format_is_compressed(templ->format))
- return NULL;
-
- tex = CALLOC_STRUCT(brw_texture);
- if (!tex)
- return NULL;
-
- memcpy(&tex->base, templ, sizeof *templ);
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- /* XXX: cpp vs. blocksize
- */
- tex->cpp = util_format_get_blocksize(tex->base.format);
- tex->tiling = tiling;
-
- make_empty_list(&tex->views[0]);
- make_empty_list(&tex->views[1]);
-
- if (!brw_texture_layout(bscreen, tex))
- goto fail;
-
- /* XXX Maybe some more checks? */
- if ((pitch / tex->cpp) < tex->pitch)
- goto fail;
-
- tex->pitch = pitch / tex->cpp;
-
- tex->bo = buffer;
-
- /* fix this warning */
-#if 0
- if (tex->size > buffer->size)
- goto fail;
-#endif
-
- tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
-
- format = translate_tex_format(tex->base.format);
- assert(format != BRW_SURFACEFORMAT_INVALID);
- tex->ss.ss0.surface_format = format;
-
- /* This is ok for all textures with channel width 8bit or less:
- */
-/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
-
-
- /* XXX: what happens when tex->bo->offset changes???
- */
- tex->ss.ss1.base_addr = 0; /* reloc */
- tex->ss.ss2.mip_count = tex->base.last_level;
- tex->ss.ss2.width = tex->base.width0 - 1;
- tex->ss.ss2.height = tex->base.height0 - 1;
-
- switch (tex->tiling) {
- case BRW_TILING_NONE:
- tex->ss.ss3.tiled_surface = 0;
- tex->ss.ss3.tile_walk = 0;
- break;
- case BRW_TILING_X:
- tex->ss.ss3.tiled_surface = 1;
- tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
- break;
- case BRW_TILING_Y:
- tex->ss.ss3.tiled_surface = 1;
- tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
- break;
- }
-
- tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
- tex->ss.ss3.depth = tex->base.depth0 - 1;
-
- tex->ss.ss4.min_lod = 0;
-
- return &tex->base;
-
-fail:
- FREE(tex);
- return NULL;
+ brw->base.get_tex_transfer = brw_get_tex_transfer;
+ brw->base.transfer_map = brw_transfer_map;
+ brw->base.transfer_unmap = brw_transfer_unmap;
+ brw->base.tex_transfer_destroy = brw_tex_transfer_destroy;
}
void brw_screen_tex_init( struct brw_screen *brw_screen )
{
brw_screen->base.is_format_supported = brw_is_format_supported;
brw_screen->base.texture_create = brw_texture_create;
+ brw_screen->base.texture_from_handle = brw_texture_from_handle;
+ brw_screen->base.texture_get_handle = brw_texture_get_handle;
brw_screen->base.texture_destroy = brw_texture_destroy;
- brw_screen->base.texture_blanket = brw_texture_blanket;
- brw_screen->base.get_tex_transfer = brw_get_tex_transfer;
- brw_screen->base.transfer_map = brw_transfer_map;
- brw_screen->base.transfer_unmap = brw_transfer_unmap;
- brw_screen->base.tex_transfer_destroy = brw_tex_transfer_destroy;
}
diff --git a/src/gallium/drivers/i965/brw_structs.h b/src/gallium/drivers/i965/brw_structs.h
index bf10bc04de..e97ddeb5e1 100644
--- a/src/gallium/drivers/i965/brw_structs.h
+++ b/src/gallium/drivers/i965/brw_structs.h
@@ -28,7 +28,7 @@
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
-
+
#ifndef BRW_STRUCTS_H
#define BRW_STRUCTS_H
@@ -1149,7 +1149,7 @@ struct brw_vertex_element_state
GLuint valid:1;
GLuint vertex_buffer_index:5;
} ve0;
-
+
struct
{
GLuint dst_offset:8;
diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h
index c82d00f4a4..f30c7f1813 100644
--- a/src/gallium/drivers/i965/brw_winsys.h
+++ b/src/gallium/drivers/i965/brw_winsys.h
@@ -162,6 +162,16 @@ struct brw_winsys_screen {
unsigned alignment,
struct brw_winsys_buffer **bo_out);
+ enum pipe_error (*bo_from_handle)(struct brw_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ unsigned *stride,
+ unsigned *tiling,
+ struct brw_winsys_buffer **bo_out);
+
+ enum pipe_error (*bo_get_handle)(struct brw_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride);
+
/* Destroy a buffer when our refcount goes to zero:
*/
void (*bo_destroy)(struct brw_winsys_buffer *buffer);
@@ -257,28 +267,6 @@ bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf)
struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id);
-/**
- * Get the brw_winsys buffer backing the texture.
- *
- * TODO UGLY
- */
-struct pipe_texture;
-boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
- struct brw_winsys_buffer **buffer,
- unsigned *stride);
-
-/**
- * Wrap a brw_winsys buffer with a texture blanket.
- *
- * TODO UGLY
- */
-struct pipe_texture *
-brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
- const struct pipe_texture *template,
- unsigned pitch,
- unsigned tiling,
- struct brw_winsys_buffer *buffer);
-
/*************************************************************************
* Cooperative dumping between winsys and driver. TODO: make this
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 8248b2a413..26770d6b1e 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -377,6 +377,42 @@ identity_delete_vs_state(struct pipe_context *_pipe,
vs);
}
+
+static void *
+identity_create_vertex_elements_state(struct pipe_context *_pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *vertex_elements)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ return pipe->create_vertex_elements_state(pipe,
+ num_elements,
+ vertex_elements);
+}
+
+static void
+identity_bind_vertex_elements_state(struct pipe_context *_pipe,
+ void *velems)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->bind_vertex_elements_state(pipe,
+ velems);
+}
+
+static void
+identity_delete_vertex_elements_state(struct pipe_context *_pipe,
+ void *velems)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->delete_vertex_elements_state(pipe,
+ velems);
+}
+
static void
identity_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *blend_color)
@@ -563,20 +599,6 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers,
buffers);
}
-
-static void
-identity_set_vertex_elements(struct pipe_context *_pipe,
- unsigned num_elements,
- const struct pipe_vertex_element *vertex_elements)
-{
- struct identity_context *id_pipe = identity_context(_pipe);
- struct pipe_context *pipe = id_pipe->pipe;
-
- pipe->set_vertex_elements(pipe,
- num_elements,
- vertex_elements);
-}
-
static void
identity_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *_dst,
@@ -689,6 +711,76 @@ identity_is_buffer_referenced(struct pipe_context *_pipe,
buffer);
}
+
+
+static struct pipe_transfer *
+identity_context_get_tex_transfer(struct pipe_context *_context,
+ struct pipe_texture *_texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x,
+ unsigned y,
+ unsigned w,
+ unsigned h)
+{
+ struct identity_context *id_context = identity_context(_context);
+ struct identity_texture *id_texture = identity_texture(_texture);
+ struct pipe_context *context = id_context->pipe;
+ struct pipe_texture *texture = id_texture->texture;
+ struct pipe_transfer *result;
+
+ result = context->get_tex_transfer(context,
+ texture,
+ face,
+ level,
+ zslice,
+ usage,
+ x,
+ y,
+ w,
+ h);
+
+ if (result)
+ return identity_transfer_create(id_context, id_texture, result);
+ return NULL;
+}
+
+static void
+identity_context_tex_transfer_destroy(struct pipe_context *_pipe,
+ struct pipe_transfer *_transfer)
+{
+ identity_transfer_destroy(identity_context(_pipe),
+ identity_transfer(_transfer));
+}
+
+static void *
+identity_context_transfer_map(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct identity_context *id_context = identity_context(_context);
+ struct identity_transfer *id_transfer = identity_transfer(_transfer);
+ struct pipe_context *context = id_context->pipe;
+ struct pipe_transfer *transfer = id_transfer->transfer;
+
+ return context->transfer_map(context,
+ transfer);
+}
+
+static void
+identity_context_transfer_unmap(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct identity_context *id_context = identity_context(_context);
+ struct identity_transfer *id_transfer = identity_transfer(_transfer);
+ struct pipe_context *context = id_context->pipe;
+ struct pipe_transfer *transfer = id_transfer->transfer;
+
+ context->transfer_unmap(context,
+ transfer);
+}
+
struct pipe_context *
identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
{
@@ -733,6 +825,9 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.create_vs_state = identity_create_vs_state;
id_pipe->base.bind_vs_state = identity_bind_vs_state;
id_pipe->base.delete_vs_state = identity_delete_vs_state;
+ id_pipe->base.create_vertex_elements_state = identity_create_vertex_elements_state;
+ id_pipe->base.bind_vertex_elements_state = identity_bind_vertex_elements_state;
+ id_pipe->base.delete_vertex_elements_state = identity_delete_vertex_elements_state;
id_pipe->base.set_blend_color = identity_set_blend_color;
id_pipe->base.set_stencil_ref = identity_set_stencil_ref;
id_pipe->base.set_clip_state = identity_set_clip_state;
@@ -744,13 +839,16 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures;
id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
- id_pipe->base.set_vertex_elements = identity_set_vertex_elements;
id_pipe->base.surface_copy = identity_surface_copy;
id_pipe->base.surface_fill = identity_surface_fill;
id_pipe->base.clear = identity_clear;
id_pipe->base.flush = identity_flush;
id_pipe->base.is_texture_referenced = identity_is_texture_referenced;
id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced;
+ id_pipe->base.get_tex_transfer = identity_context_get_tex_transfer;
+ id_pipe->base.tex_transfer_destroy = identity_context_tex_transfer_destroy;
+ id_pipe->base.transfer_map = identity_context_transfer_map;
+ id_pipe->base.transfer_unmap = identity_context_transfer_unmap;
id_pipe->pipe = pipe;
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index f258c38cd7..936ccc444a 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -63,62 +63,6 @@ identity_drm_create_screen(struct drm_api *_api, int fd,
return identity_screen_create(screen);
}
-
-static struct pipe_texture *
-identity_drm_texture_from_shared_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct drm_api *api = id_api->api;
- struct pipe_texture *result;
-
- result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
-
- result = identity_texture_create(identity_screen(_screen), result);
-
- return result;
-}
-
-static boolean
-identity_drm_shared_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
-
- return api->shared_handle_from_texture(api, screen, texture, stride, handle);
-}
-
-static boolean
-identity_drm_local_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
-
- return api->local_handle_from_texture(api, screen, texture, stride, handle);
-}
-
static void
identity_drm_destroy(struct drm_api *_api)
{
@@ -145,9 +89,6 @@ identity_drm_create(struct drm_api *api)
id_api->base.name = api->name;
id_api->base.driver_name = api->driver_name;
id_api->base.create_screen = identity_drm_create_screen;
- id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle;
- id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture;
- id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture;
id_api->base.destroy = identity_drm_destroy;
id_api->api = api;
diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c
index 2b1a60c1bf..d37fb0042e 100644
--- a/src/gallium/drivers/identity/id_objects.c
+++ b/src/gallium/drivers/identity/id_objects.c
@@ -30,6 +30,7 @@
#include "id_screen.h"
#include "id_objects.h"
+#include "id_context.h"
struct pipe_buffer *
identity_buffer_create(struct identity_screen *id_screen,
@@ -142,7 +143,8 @@ identity_surface_destroy(struct identity_surface *id_surface)
struct pipe_transfer *
-identity_transfer_create(struct identity_texture *id_texture,
+identity_transfer_create(struct identity_context *id_context,
+ struct identity_texture *id_texture,
struct pipe_transfer *transfer)
{
struct identity_transfer *id_transfer;
@@ -159,25 +161,25 @@ identity_transfer_create(struct identity_texture *id_texture,
memcpy(&id_transfer->base, transfer, sizeof(struct pipe_transfer));
id_transfer->base.texture = NULL;
- pipe_texture_reference(&id_transfer->base.texture, &id_texture->base);
id_transfer->transfer = transfer;
+
+ pipe_texture_reference(&id_transfer->base.texture, &id_texture->base);
assert(id_transfer->base.texture == &id_texture->base);
return &id_transfer->base;
error:
- transfer->texture->screen->tex_transfer_destroy(transfer);
+ id_context->pipe->tex_transfer_destroy(id_context->pipe, transfer);
return NULL;
}
void
-identity_transfer_destroy(struct identity_transfer *id_transfer)
+identity_transfer_destroy(struct identity_context *id_context,
+ struct identity_transfer *id_transfer)
{
- struct identity_screen *id_screen = identity_screen(id_transfer->base.texture->screen);
- struct pipe_screen *screen = id_screen->screen;
-
pipe_texture_reference(&id_transfer->base.texture, NULL);
- screen->tex_transfer_destroy(id_transfer->transfer);
+ id_context->pipe->tex_transfer_destroy(id_context->pipe,
+ id_transfer->transfer);
FREE(id_transfer);
}
diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h
index 77cc719079..7333ecfb7f 100644
--- a/src/gallium/drivers/identity/id_objects.h
+++ b/src/gallium/drivers/identity/id_objects.h
@@ -35,6 +35,7 @@
#include "id_screen.h"
+struct identity_context;
struct identity_buffer
{
@@ -64,6 +65,7 @@ struct identity_transfer
{
struct pipe_transfer base;
+ struct pipe_context *pipe;
struct pipe_transfer *transfer;
};
@@ -177,11 +179,13 @@ void
identity_surface_destroy(struct identity_surface *id_surface);
struct pipe_transfer *
-identity_transfer_create(struct identity_texture *id_texture,
+identity_transfer_create(struct identity_context *id_context,
+ struct identity_texture *id_texture,
struct pipe_transfer *transfer);
void
-identity_transfer_destroy(struct identity_transfer *id_transfer);
+identity_transfer_destroy(struct identity_context *id_context,
+ struct identity_transfer *id_transfer);
struct pipe_video_surface *
identity_video_surface_create(struct identity_screen *id_screen,
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index b85492114a..419b146578 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -135,27 +135,40 @@ identity_screen_texture_create(struct pipe_screen *_screen,
}
static struct pipe_texture *
-identity_screen_texture_blanket(struct pipe_screen *_screen,
- const struct pipe_texture *templat,
- const unsigned *stride,
- struct pipe_buffer *_buffer)
+identity_screen_texture_from_handle(struct pipe_screen *_screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_buffer *id_buffer = identity_buffer(_buffer);
struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *buffer = id_buffer->buffer;
struct pipe_texture *result;
- result = screen->texture_blanket(screen,
- templat,
- stride,
- buffer);
+ /* TODO trace call */
- if (result)
- return identity_texture_create(id_screen, result);
- return NULL;
+ result = screen->texture_from_handle(screen, templ, handle);
+
+ result = identity_texture_create(identity_screen(_screen), result);
+
+ return result;
}
+static boolean
+identity_screen_texture_get_handle(struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ struct winsys_handle *handle)
+{
+ struct identity_screen *id_screen = identity_screen(_screen);
+ struct identity_texture *id_texture = identity_texture(_texture);
+ struct pipe_screen *screen = id_screen->screen;
+ struct pipe_texture *texture = id_texture->texture;
+
+ /* TODO trace call */
+
+ return screen->texture_get_handle(screen, texture, handle);
+}
+
+
+
static void
identity_screen_texture_destroy(struct pipe_texture *_texture)
{
@@ -194,71 +207,6 @@ identity_screen_tex_surface_destroy(struct pipe_surface *_surface)
identity_surface_destroy(identity_surface(_surface));
}
-static struct pipe_transfer *
-identity_screen_get_tex_transfer(struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned face,
- unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x,
- unsigned y,
- unsigned w,
- unsigned h)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct pipe_transfer *result;
-
- result = screen->get_tex_transfer(screen,
- texture,
- face,
- level,
- zslice,
- usage,
- x,
- y,
- w,
- h);
-
- if (result)
- return identity_transfer_create(id_texture, result);
- return NULL;
-}
-
-static void
-identity_screen_tex_transfer_destroy(struct pipe_transfer *_transfer)
-{
- identity_transfer_destroy(identity_transfer(_transfer));
-}
-
-static void *
-identity_screen_transfer_map(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_transfer *id_transfer = identity_transfer(_transfer);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_transfer *transfer = id_transfer->transfer;
-
- return screen->transfer_map(screen,
- transfer);
-}
-
-static void
-identity_screen_transfer_unmap(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_transfer *id_transfer = identity_transfer(_transfer);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_transfer *transfer = id_transfer->transfer;
-
- screen->transfer_unmap(screen,
- transfer);
-}
static struct pipe_buffer *
identity_screen_buffer_create(struct pipe_screen *_screen,
@@ -298,31 +246,6 @@ identity_screen_user_buffer_create(struct pipe_screen *_screen,
return NULL;
}
-static struct pipe_buffer *
-identity_screen_surface_buffer_create(struct pipe_screen *_screen,
- unsigned width,
- unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *result;
-
- result = screen->surface_buffer_create(screen,
- width,
- height,
- format,
- usage,
- tex_usage,
- stride);
-
- if (result)
- return identity_buffer_create(id_screen, result);
- return NULL;
-}
static void *
identity_screen_buffer_map(struct pipe_screen *_screen,
@@ -495,17 +418,13 @@ identity_screen_create(struct pipe_screen *screen)
id_screen->base.is_format_supported = identity_screen_is_format_supported;
id_screen->base.context_create = identity_screen_context_create;
id_screen->base.texture_create = identity_screen_texture_create;
- id_screen->base.texture_blanket = identity_screen_texture_blanket;
+ id_screen->base.texture_from_handle = identity_screen_texture_from_handle;
+ id_screen->base.texture_get_handle = identity_screen_texture_get_handle;
id_screen->base.texture_destroy = identity_screen_texture_destroy;
id_screen->base.get_tex_surface = identity_screen_get_tex_surface;
id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy;
- id_screen->base.get_tex_transfer = identity_screen_get_tex_transfer;
- id_screen->base.tex_transfer_destroy = identity_screen_tex_transfer_destroy;
- id_screen->base.transfer_map = identity_screen_transfer_map;
- id_screen->base.transfer_unmap = identity_screen_transfer_unmap;
id_screen->base.buffer_create = identity_screen_buffer_create;
id_screen->base.user_buffer_create = identity_screen_user_buffer_create;
- id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create;
if (screen->buffer_map)
id_screen->base.buffer_map = identity_screen_buffer_map;
if (screen->buffer_map_range)
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 41ac1cee72..89c06ea3ad 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -55,7 +55,7 @@ testprogs := lp_test_format \
LIBS += $(GL_LIB_DEPS) -L. -lllvmpipe -L../../auxiliary/ -lgallium
-$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a
- $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group
+#$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a
+# $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group
-default: $(testprogs)
+#default: $(testprogs)
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c
index 9eda972081..6e0f37393e 100644
--- a/src/gallium/drivers/llvmpipe/lp_buffer.c
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.c
@@ -30,7 +30,6 @@
#include "util/u_memory.h"
#include "util/u_math.h"
-#include "lp_winsys.h"
#include "lp_screen.h"
#include "lp_buffer.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index e31ae6a3fc..945e3e0558 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -145,6 +145,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
+ llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
+ llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
+ llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
+
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
@@ -157,7 +161,6 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
- llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements;
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
@@ -170,6 +173,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced;
llvmpipe_init_query_funcs( llvmpipe );
+ llvmpipe_init_context_texture_funcs( &llvmpipe->pipe );
/*
* Create drawing context and plug our rendering stage into it.
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 955c7eb8e0..217ec59b68 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -46,6 +46,7 @@ struct lp_fragment_shader;
struct lp_vertex_shader;
struct lp_blend_state;
struct setup_context;
+struct lp_velems_state;
struct llvmpipe_context {
struct pipe_context pipe; /**< base class */
@@ -58,6 +59,7 @@ struct llvmpipe_context {
const struct pipe_rasterizer_state *rasterizer;
struct lp_fragment_shader *fs;
const struct lp_vertex_shader *vs;
+ const struct lp_velems_state *velems;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -71,13 +73,11 @@ struct llvmpipe_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
unsigned num_textures;
unsigned num_vertex_samplers;
unsigned num_vertex_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of LP_NEW_x flags */
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index bf832433be..1b4e889935 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -79,12 +79,12 @@ llvmpipe_flush( struct pipe_context *pipe,
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no);
- debug_dump_surface(filename, llvmpipe->framebuffer.cbufs[i]);
+ debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[0]);
}
if (0) {
util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no);
- debug_dump_surface(filename, llvmpipe->framebuffer.zsbuf);
+ debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf);
}
++frame_no;
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index bacff500d6..5887613120 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -57,8 +57,11 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
- elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
- elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
+ elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
+ LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_2D_LEVELS);
+ elem_types[LP_JIT_TEXTURE_DATA] =
+ LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+ LP_MAX_TEXTURE_2D_LEVELS);
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
@@ -74,9 +77,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
screen->target, texture_type,
LP_JIT_TEXTURE_LAST_LEVEL);
- LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, stride,
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
screen->target, texture_type,
- LP_JIT_TEXTURE_STRIDE);
+ LP_JIT_TEXTURE_ROW_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
screen->target, texture_type,
LP_JIT_TEXTURE_DATA);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 0ebb2826fa..13167ae3bf 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -39,6 +39,7 @@
#include "gallivm/lp_bld_struct.h"
#include "pipe/p_state.h"
+#include "lp_texture.h"
struct llvmpipe_screen;
@@ -50,8 +51,8 @@ struct lp_jit_texture
uint32_t height;
uint32_t depth;
uint32_t last_level;
- uint32_t stride;
- const void *data;
+ uint32_t row_stride[LP_MAX_TEXTURE_2D_LEVELS];
+ const void *data[LP_MAX_TEXTURE_2D_LEVELS];
};
@@ -60,7 +61,7 @@ enum {
LP_JIT_TEXTURE_HEIGHT,
LP_JIT_TEXTURE_DEPTH,
LP_JIT_TEXTURE_LAST_LEVEL,
- LP_JIT_TEXTURE_STRIDE,
+ LP_JIT_TEXTURE_ROW_STRIDE,
LP_JIT_TEXTURE_DATA
};
diff --git a/src/gallium/drivers/llvmpipe/lp_public.h b/src/gallium/drivers/llvmpipe/lp_public.h
new file mode 100644
index 0000000000..ec6b660b48
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_public.h
@@ -0,0 +1,10 @@
+#ifndef LP_PUBLIC_H
+#define LP_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+llvmpipe_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 72492c0f0c..505cb21503 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -397,7 +397,7 @@ end:
static boolean
lp_scene_map_buffers( struct lp_scene *scene )
{
- struct pipe_screen *screen = scene->pipe->screen;
+ struct pipe_context *pipe = scene->pipe;
struct pipe_surface *cbuf, *zsbuf;
int i;
@@ -409,7 +409,7 @@ lp_scene_map_buffers( struct lp_scene *scene )
for (i = 0; i < scene->fb.nr_cbufs; i++) {
cbuf = scene->fb.cbufs[i];
if (cbuf) {
- scene->cbuf_transfer[i] = screen->get_tex_transfer(screen,
+ scene->cbuf_transfer[i] = pipe->get_tex_transfer(pipe,
cbuf->texture,
cbuf->face,
cbuf->level,
@@ -421,7 +421,7 @@ lp_scene_map_buffers( struct lp_scene *scene )
if (!scene->cbuf_transfer[i])
goto fail;
- scene->cbuf_map[i] = screen->transfer_map(screen,
+ scene->cbuf_map[i] = pipe->transfer_map(pipe,
scene->cbuf_transfer[i]);
if (!scene->cbuf_map[i])
goto fail;
@@ -432,7 +432,7 @@ lp_scene_map_buffers( struct lp_scene *scene )
*/
zsbuf = scene->fb.zsbuf;
if (zsbuf) {
- scene->zsbuf_transfer = screen->get_tex_transfer(screen,
+ scene->zsbuf_transfer = pipe->get_tex_transfer(pipe,
zsbuf->texture,
zsbuf->face,
zsbuf->level,
@@ -444,7 +444,7 @@ lp_scene_map_buffers( struct lp_scene *scene )
if (!scene->zsbuf_transfer)
goto fail;
- scene->zsbuf_map = screen->transfer_map(screen,
+ scene->zsbuf_map = pipe->transfer_map(pipe,
scene->zsbuf_transfer);
if (!scene->zsbuf_map)
goto fail;
@@ -469,25 +469,25 @@ fail:
static void
lp_scene_unmap_buffers( struct lp_scene *scene )
{
- struct pipe_screen *screen = scene->pipe->screen;
+ struct pipe_context *pipe = scene->pipe;
unsigned i;
for (i = 0; i < scene->fb.nr_cbufs; i++) {
if (scene->cbuf_map[i])
- screen->transfer_unmap(screen, scene->cbuf_transfer[i]);
+ pipe->transfer_unmap(pipe, scene->cbuf_transfer[i]);
if (scene->cbuf_transfer[i])
- screen->tex_transfer_destroy(scene->cbuf_transfer[i]);
+ pipe->tex_transfer_destroy(pipe, scene->cbuf_transfer[i]);
scene->cbuf_transfer[i] = NULL;
scene->cbuf_map[i] = NULL;
}
if (scene->zsbuf_map)
- screen->transfer_unmap(screen, scene->zsbuf_transfer);
+ pipe->transfer_unmap(pipe, scene->zsbuf_transfer);
if (scene->zsbuf_transfer)
- screen->tex_transfer_destroy(scene->zsbuf_transfer);
+ pipe->tex_transfer_destroy(pipe, scene->zsbuf_transfer);
scene->zsbuf_transfer = NULL;
scene->zsbuf_map = NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index f84ede675b..5093f58bb1 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -34,11 +34,13 @@
#include "lp_texture.h"
#include "lp_buffer.h"
#include "lp_fence.h"
-#include "lp_winsys.h"
#include "lp_jit.h"
#include "lp_screen.h"
#include "lp_context.h"
#include "lp_debug.h"
+#include "lp_public.h"
+
+#include "state_tracker/sw_winsys.h"
#ifdef DEBUG
int LP_DEBUG = 0;
@@ -107,11 +109,11 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13; /* max 4Kx4K */
+ return LP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 9; /* max 256x256x256 */
+ return LP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13; /* max 4Kx4K */
+ return LP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
@@ -167,7 +169,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
unsigned geom_flags )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
const struct util_format_description *format_desc;
format_desc = util_format_description(format);
@@ -238,18 +240,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
}
-static struct pipe_buffer *
-llvmpipe_surface_buffer_create(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned tex_usage,
- unsigned usage,
- unsigned *stride)
-{
- /* This function should never be used */
- assert(0);
- return NULL;
-}
static void
@@ -258,7 +248,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
void *context_private)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
assert(texture->dt);
@@ -271,7 +261,7 @@ static void
llvmpipe_destroy_screen( struct pipe_screen *_screen )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
lp_jit_screen_cleanup(screen);
@@ -288,7 +278,7 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
* Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
*/
struct pipe_screen *
-llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
+llvmpipe_create_screen(struct sw_winsys *winsys)
{
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
@@ -309,7 +299,6 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
screen->base.get_paramf = llvmpipe_get_paramf;
screen->base.is_format_supported = llvmpipe_is_format_supported;
- screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
screen->base.context_create = llvmpipe_create_context;
screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index 4a1b4d6f3e..d977f98cfa 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -34,23 +34,21 @@
#ifndef LP_SCREEN_H
#define LP_SCREEN_H
-#include <llvm-c/Core.h>
-#include <llvm-c/Analysis.h>
-#include <llvm-c/Target.h>
+#include "os/os_llvm.h"
#include <llvm-c/ExecutionEngine.h>
#include "pipe/p_screen.h"
#include "pipe/p_defines.h"
-struct llvmpipe_winsys;
+struct sw_winsys;
struct llvmpipe_screen
{
struct pipe_screen base;
- struct llvmpipe_winsys *winsys;
+ struct sw_winsys *winsys;
LLVMModuleRef module;
LLVMExecutionEngineRef engine;
@@ -76,4 +74,5 @@ llvmpipe_screen( struct pipe_screen *pipe )
}
+
#endif /* LP_SCREEN_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index b0713c3b71..c870f89d01 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -46,7 +46,7 @@
#include "lp_rast.h"
#include "lp_setup_context.h"
#include "lp_screen.h"
-#include "lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
@@ -471,20 +471,27 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
jit_tex->height = tex->height0;
jit_tex->depth = tex->depth0;
jit_tex->last_level = tex->last_level;
- jit_tex->stride = lp_tex->stride[0];
- if(!lp_tex->dt) {
- jit_tex->data = lp_tex->data;
+ if (!lp_tex->dt) {
+ /* regular texture - setup array of mipmap level pointers */
+ int j;
+ for (j = 0; j <= tex->last_level; j++) {
+ jit_tex->data[j] =
+ (ubyte *) lp_tex->data + lp_tex->level_offset[j];
+ jit_tex->row_stride[j] = lp_tex->stride[j];
+ }
}
else {
+ /* display target texture/surface */
/*
* XXX: Where should this be unmapped?
*/
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
- jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
+ struct sw_winsys *winsys = screen->winsys;
+ jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
PIPE_BUFFER_USAGE_CPU_READ);
- assert(jit_tex->data);
+ jit_tex->row_stride[0] = lp_tex->stride[0];
+ assert(jit_tex->data[0]);
}
/* the scene references this texture */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
index 24291da91e..671e74465c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
@@ -231,57 +231,29 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
+ for (i = 3; i < nr; i += 4) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride));
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ for (i = 3; i < nr; i += 2) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
@@ -415,57 +387,28 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 3; i < nr; i += 4) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- setup->triangle( setup,
-
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 3; i < nr; i += 2) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 9beba32271..a5a1a72074 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -31,7 +31,7 @@
#ifndef LP_STATE_H
#define LP_STATE_H
-#include <llvm-c/Core.h>
+#include "os/os_llvm.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
@@ -119,6 +119,10 @@ struct lp_vertex_shader {
struct draw_vertex_shader *draw_data;
};
+struct lp_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
void *
@@ -176,8 +180,14 @@ void *llvmpipe_create_vs_state(struct pipe_context *,
void llvmpipe_bind_vs_state(struct pipe_context *, void *);
void llvmpipe_delete_vs_state(struct pipe_context *, void *);
+void *llvmpipe_create_vertex_elements_state(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+void llvmpipe_bind_vertex_elements_state(struct pipe_context *, void *);
+void llvmpipe_delete_vertex_elements_state(struct pipe_context *, void *);
+
void llvmpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
+ const struct pipe_poly_stipple * );
void llvmpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
@@ -194,10 +204,6 @@ llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void llvmpipe_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-
void llvmpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index c4b79dd415..9a8de0edfd 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -40,7 +40,7 @@
* - depth/stencil test (stencil TBI)
* - blending
*
- * This file has only the glue to assembly the fragment pipeline. The actual
+ * This file has only the glue to assemble the fragment pipeline. The actual
* plumbing of converting Gallium state into LLVM IR is done elsewhere, in the
* lp_bld_*.[ch] files, and in a complete generic and reusable way. Here we
* muster the LLVM JIT execution engine to create a function that follows an
@@ -95,6 +95,9 @@
#include "lp_tex_sample.h"
+#include <llvm-c/Analysis.h>
+
+
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index 57ac25ea0c..f6427aa908 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -35,24 +35,41 @@
#include "draw/draw_context.h"
+void *
+llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct lp_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct lp_velems_state *) MALLOC(sizeof(struct lp_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
void
-llvmpipe_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *attribs)
+llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ struct lp_velems_state *lp_velems = (struct lp_velems_state *) velems;
- assert(count <= PIPE_MAX_ATTRIBS);
-
- memcpy(llvmpipe->vertex_element, attribs,
- count * sizeof(struct pipe_vertex_element));
- llvmpipe->num_vertex_elements = count;
+ llvmpipe->velems = lp_velems;
llvmpipe->dirty |= LP_NEW_VERTEX;
- draw_set_vertex_elements(llvmpipe->draw, count, attribs);
+ if (velems)
+ draw_set_vertex_elements(llvmpipe->draw, lp_velems->count, lp_velems->velem);
}
+void
+llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h
index a9b99945f9..1df9897898 100644
--- a/src/gallium/drivers/llvmpipe/lp_test.h
+++ b/src/gallium/drivers/llvmpipe/lp_test.h
@@ -41,7 +41,7 @@
#include <stdio.h>
#include <float.h>
-#include <llvm-c/Core.h>
+#include "os/os_llvm.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index d05157991b..2c4d7fb6e1 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include <llvm-c/Core.h>
+#include "os/os_llvm.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
index cb59a94464..799df182b6 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
@@ -29,7 +29,7 @@
#define LP_TEX_SAMPLE_H
-#include <llvm-c/Core.h>
+#include "os/os_llvm.h"
struct lp_sampler_static_state;
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 632462460a..662508af61 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -51,10 +51,11 @@
/**
- * This provides the bridge between the sampler state store in lp_jit_context
- * and lp_jit_texture and the sampler code generator. It provides the
- * texture layout information required by the texture sampler code generator
- * in terms of the state stored in lp_jit_context and lp_jit_texture in runtime.
+ * This provides the bridge between the sampler state store in
+ * lp_jit_context and lp_jit_texture and the sampler code
+ * generator. It provides the texture layout information required by
+ * the texture sampler code generator in terms of the state stored in
+ * lp_jit_context and lp_jit_texture in runtime.
*/
struct llvmpipe_sampler_dynamic_state
{
@@ -79,6 +80,9 @@ struct lp_llvm_sampler_soa
/**
* Fetch the specified member of the lp_jit_texture structure.
+ * \param emit_load if TRUE, emit the LLVM load instruction to actually
+ * fetch the field's value. Otherwise, just emit the
+ * GEP code to address the field.
*
* @sa http://llvm.org/docs/GetElementPtr.html
*/
@@ -87,9 +91,11 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
LLVMBuilderRef builder,
unsigned unit,
unsigned member_index,
- const char *member_name)
+ const char *member_name,
+ boolean emit_load)
{
- struct llvmpipe_sampler_dynamic_state *state = (struct llvmpipe_sampler_dynamic_state *)base;
+ struct llvmpipe_sampler_dynamic_state *state =
+ (struct llvmpipe_sampler_dynamic_state *)base;
LLVMValueRef indices[4];
LLVMValueRef ptr;
LLVMValueRef res;
@@ -107,7 +113,10 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
- res = LLVMBuildLoad(builder, ptr, "");
+ if (emit_load)
+ res = LLVMBuildLoad(builder, ptr, "");
+ else
+ res = ptr;
lp_build_name(res, "context.texture%u.%s", unit, member_name);
@@ -116,28 +125,30 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
/**
- * Helper macro to instantiate the functions that generate the code to fetch
- * the members of lp_jit_texture to fulfill the sampler code generator requests.
+ * Helper macro to instantiate the functions that generate the code to
+ * fetch the members of lp_jit_texture to fulfill the sampler code
+ * generator requests.
*
- * This complexity is the price we have to pay to keep the texture sampler code
- * generator a reusable module without dependencies to llvmpipe internals.
+ * This complexity is the price we have to pay to keep the texture
+ * sampler code generator a reusable module without dependencies to
+ * llvmpipe internals.
*/
-#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
+#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \
static LLVMValueRef \
lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
LLVMBuilderRef builder, \
unsigned unit) \
{ \
- return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
+ return lp_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
}
-LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH)
-LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT)
-LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH)
-LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL)
-LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE)
-LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA)
+LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE)
+LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
+LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
+LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
static void
@@ -193,7 +204,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
sampler->dynamic_state.base.height = lp_llvm_texture_height;
sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
- sampler->dynamic_state.base.stride = lp_llvm_texture_stride;
+ sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
sampler->dynamic_state.static_state = static_state;
sampler->dynamic_state.context_ptr = context_ptr;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 7f45635542..f2c6dbd088 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -42,7 +42,7 @@
#include "lp_screen.h"
#include "lp_texture.h"
#include "lp_tile_size.h"
-#include "lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
/**
@@ -93,7 +93,7 @@ static boolean
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
struct llvmpipe_texture *lpt)
{
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
/* Round up the surface size to a multiple of the tile size to
* avoid tile clipping.
@@ -125,7 +125,8 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
lpt->base.screen = &screen->base;
if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
if (!llvmpipe_displaytarget_layout(screen, lpt))
goto fail;
}
@@ -142,43 +143,6 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
}
-static struct pipe_texture *
-llvmpipe_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- /* FIXME */
-#if 0
- struct llvmpipe_texture *lpt;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- lpt = CALLOC_STRUCT(llvmpipe_texture);
- if (!lpt)
- return NULL;
-
- lpt->base = *base;
- pipe_reference_init(&lpt->base.reference, 1);
- lpt->base.screen = screen;
- lpt->stride[0] = stride[0];
-
- pipe_buffer_reference(&lpt->buffer, buffer);
-
- return &lpt->base;
-#else
- debug_printf("llvmpipe_texture_blanket() not implemented!");
- return NULL;
-#endif
-}
-
-
static void
llvmpipe_texture_destroy(struct pipe_texture *pt)
{
@@ -187,7 +151,7 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
if (lpt->dt) {
/* display target */
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpt->dt);
}
else {
@@ -279,7 +243,7 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
static struct pipe_transfer *
-llvmpipe_get_tex_transfer(struct pipe_screen *screen,
+llvmpipe_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
@@ -330,7 +294,8 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
static void
-llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
+llvmpipe_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
/* Effectively do the texture_update work here - if texture images
* needed post-processing to put them into hardware layout, this is
@@ -343,10 +308,10 @@ llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
static void *
-llvmpipe_transfer_map( struct pipe_screen *_screen,
+llvmpipe_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
- struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
ubyte *map, *xfer_map;
struct llvmpipe_texture *lpt;
enum pipe_format format;
@@ -357,7 +322,7 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
if (lpt->dt) {
/* display target */
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
map = winsys->displaytarget_map(winsys, lpt->dt,
pipe_transfer_buffer_flags(transfer));
@@ -387,10 +352,10 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
static void
-llvmpipe_transfer_unmap(struct pipe_screen *screen,
- struct pipe_transfer *transfer)
+llvmpipe_transfer_unmap(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
- struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen);
+ struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
struct llvmpipe_texture *lpt;
assert(transfer->texture);
@@ -398,7 +363,7 @@ llvmpipe_transfer_unmap(struct pipe_screen *screen,
if (lpt->dt) {
/* display target */
- struct llvmpipe_winsys *winsys = lp_screen->winsys;
+ struct sw_winsys *winsys = lp_screen->winsys;
winsys->displaytarget_unmap(winsys, lpt->dt);
}
}
@@ -408,14 +373,18 @@ void
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = llvmpipe_texture_create;
- screen->texture_blanket = llvmpipe_texture_blanket;
screen->texture_destroy = llvmpipe_texture_destroy;
screen->get_tex_surface = llvmpipe_get_tex_surface;
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
+}
+
- screen->get_tex_transfer = llvmpipe_get_tex_transfer;
- screen->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
- screen->transfer_map = llvmpipe_transfer_map;
- screen->transfer_unmap = llvmpipe_transfer_unmap;
+void
+llvmpipe_init_context_texture_funcs(struct pipe_context *pipe)
+{
+ pipe->get_tex_transfer = llvmpipe_get_tex_transfer;
+ pipe->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
+ pipe->transfer_map = llvmpipe_transfer_map;
+ pipe->transfer_unmap = llvmpipe_transfer_unmap;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 87c905bc02..94b667abf3 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -32,24 +32,29 @@
#include "pipe/p_state.h"
+#define LP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K for now */
+#define LP_MAX_TEXTURE_3D_LEVELS 10 /* 512 x 512 x 512 for now */
+
+
struct pipe_context;
struct pipe_screen;
struct llvmpipe_context;
-struct llvmpipe_displaytarget;
+
+struct sw_displaytarget;
struct llvmpipe_texture
{
struct pipe_texture base;
- unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long level_offset[LP_MAX_TEXTURE_2D_LEVELS];
+ unsigned stride[LP_MAX_TEXTURE_2D_LEVELS];
/**
* Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
* usage.
*/
- struct llvmpipe_displaytarget *dt;
+ struct sw_displaytarget *dt;
/**
* Malloc'ed data for regular textures, or a mapping to dt above.
@@ -93,5 +98,7 @@ llvmpipe_transfer(struct pipe_transfer *pt)
extern void
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
+extern void
+llvmpipe_init_context_texture_funcs(struct pipe_context *pipe);
#endif /* LP_TEXTURE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h
deleted file mode 100644
index ce11fa9304..0000000000
--- a/src/gallium/drivers/llvmpipe/lp_winsys.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007-2009 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * @file
- * llvmpipe public interface.
- */
-
-
-#ifndef LP_WINSYS_H
-#define LP_WINSYS_H
-
-
-#include "pipe/p_compiler.h" /* for boolean */
-#include "pipe/p_format.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct pipe_screen;
-struct pipe_context;
-
-
-/**
- * Opaque pointer.
- */
-struct llvmpipe_displaytarget;
-
-
-/**
- * This is the interface that llvmpipe expects any window system
- * hosting it to implement.
- *
- * llvmpipe is for the most part a self sufficient driver. The only thing it
- * does not know is how to display a surface.
- */
-struct llvmpipe_winsys
-{
- void
- (*destroy)( struct llvmpipe_winsys *ws );
-
- boolean
- (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
- enum pipe_format format );
-
- /**
- * Allocate storage for a render target.
- *
- * Often surfaces which are meant to be blitted to the front screen (i.e.,
- * display targets) must be allocated with special characteristics, memory
- * pools, or obtained directly from the windowing system.
- *
- * This callback is invoked by the pipe_screen when creating a texture marked
- * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
- * storage.
- */
- struct llvmpipe_displaytarget *
- (*displaytarget_create)( struct llvmpipe_winsys *ws,
- enum pipe_format format,
- unsigned width, unsigned height,
- unsigned alignment,
- unsigned *stride );
-
- void *
- (*displaytarget_map)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- unsigned flags );
-
- void
- (*displaytarget_unmap)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt );
-
- /**
- * @sa pipe_screen:flush_frontbuffer.
- *
- * This call will likely become asynchronous eventually.
- */
- void
- (*displaytarget_display)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- void *context_private );
-
- void
- (*displaytarget_destroy)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt );
-};
-
-
-
-struct pipe_screen *
-llvmpipe_create_screen( struct llvmpipe_winsys * );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LP_WINSYS_H */
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 3c2f771b51..b1ad686022 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -4,6 +4,7 @@
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_format.h"
#include <stdio.h>
#include <errno.h>
@@ -12,6 +13,9 @@
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
+/* XXX this should go away */
+#include "state_tracker/drm_api.h"
+
static const char *
nouveau_screen_get_name(struct pipe_screen *pscreen)
{
@@ -120,7 +124,7 @@ nouveau_screen_map_flags(unsigned pipe)
if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
flags |= NOUVEAU_BO_NOWAIT;
else
- if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
+ if (pipe & PIPE_BUFFER_USAGE_UNSYNCHRONIZED)
flags |= NOUVEAU_BO_NOSYNC;
return flags;
@@ -231,6 +235,72 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
return 0;
}
+
+/*
+ * Both texture_{from|get}_handle use drm api defines directly which they
+ * shouldn't do. The problem is that from|get are pipe functions and as
+ * such they should be defined in the pipe level. If nouveau had a propper
+ * winsys interface we would have added from|get to that interface using
+ * the winsys_handle struct as done with other drivers. However this code
+ * calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
+ * we need to translate the handle into something they understand.
+ */
+static struct pipe_texture *
+nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle)
+{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ struct pipe_texture *pt;
+ struct pipe_buffer *pb;
+ int ret;
+
+ pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
+ if (!pb)
+ return NULL;
+
+ ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
+ if (ret) {
+ debug_printf("%s: ref name 0x%08x failed with %d\n",
+ __func__, whandle->handle, ret);
+ FREE(pb);
+ return NULL;
+ }
+
+ pipe_reference_init(&pb->reference, 1);
+ pb->screen = pscreen;
+ pb->alignment = 0;
+ pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ pb->size = nouveau_bo(pb)->size;
+ pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ,
+ &whandle->stride, pb);
+ pipe_buffer_reference(&pb, NULL);
+ return pt;
+}
+
+static boolean
+nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
+
+ if (!mt || !mt->bo)
+ return false;
+
+ whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ return nouveau_bo_handle_get(mt->bo, &whandle->handle) == 0;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = mt->bo->handle;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@@ -258,6 +328,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
pscreen->fence_signalled = nouveau_screen_fence_signalled;
pscreen->fence_finish = nouveau_screen_fence_finish;
+ pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
+ pscreen->texture_get_handle = nouveau_screen_texture_get_handle;
+
return 0;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index a7927d88df..f4a7a2bc23 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -6,6 +6,18 @@ struct nouveau_screen {
struct nouveau_device *device;
struct nouveau_channel *channel;
+ /**
+ * Create a new texture object, using the given template info, but on top of
+ * existing memory.
+ *
+ * It is assumed that the buffer data is layed out according to the expected
+ * by the hardware. NULL will be returned if any inconsistency is found.
+ */
+ struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
+ const struct pipe_texture *templat,
+ const unsigned *stride,
+ struct pipe_buffer *buffer);
+
int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen,
struct pipe_buffer *pb, unsigned usage);
};
diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h
index a10114beab..7f16e31c3f 100644
--- a/src/gallium/drivers/nouveau/nouveau_util.h
+++ b/src/gallium/drivers/nouveau/nouveau_util.h
@@ -88,4 +88,104 @@ static INLINE unsigned log2i(unsigned i)
return r;
}
+struct u_split_prim {
+ void *priv;
+ void (*emit)(void *priv, unsigned start, unsigned count);
+ void (*edge)(void *priv, boolean enabled);
+
+ unsigned mode;
+ unsigned start;
+ unsigned p_start;
+ unsigned p_end;
+
+ int repeat_first:1;
+ int close_first:1;
+ int edgeflag_off:1;
+};
+
+static inline void
+u_split_prim_init(struct u_split_prim *s,
+ unsigned mode, unsigned start, unsigned count)
+{
+ if (mode == PIPE_PRIM_LINE_LOOP) {
+ s->mode = PIPE_PRIM_LINE_STRIP;
+ s->close_first = 1;
+ } else {
+ s->mode = mode;
+ s->close_first = 0;
+ }
+ s->start = start;
+ s->p_start = start;
+ s->p_end = start + count;
+ s->edgeflag_off = 0;
+ s->repeat_first = 0;
+}
+
+static INLINE boolean
+u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
+{
+ int repeat = 0;
+
+ if (s->repeat_first) {
+ s->emit(s->priv, s->start, 1);
+ max_verts--;
+ if (s->edgeflag_off) {
+ s->edge(s->priv, TRUE);
+ s->edgeflag_off = FALSE;
+ }
+ }
+
+ if (s->p_start + s->close_first + max_verts >= s->p_end) {
+ s->emit(s->priv, s->p_start, s->p_end - s->p_start);
+ if (s->close_first)
+ s->emit(s->priv, s->start, 1);
+ return TRUE;
+ }
+
+ switch (s->mode) {
+ case PIPE_PRIM_LINES:
+ max_verts &= ~1;
+ break;
+ case PIPE_PRIM_LINE_STRIP:
+ repeat = 1;
+ break;
+ case PIPE_PRIM_POLYGON:
+ max_verts--;
+ s->emit(s->priv, s->p_start, max_verts);
+ s->edge(s->priv, FALSE);
+ s->emit(s->priv, s->p_start + max_verts, 1);
+ s->p_start += max_verts;
+ s->repeat_first = TRUE;
+ s->edgeflag_off = TRUE;
+ return FALSE;
+ case PIPE_PRIM_TRIANGLES:
+ max_verts = max_verts - (max_verts % 3);
+ break;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ /* to ensure winding stays correct, always split
+ * on an even number of generated triangles
+ */
+ max_verts = max_verts & ~1;
+ repeat = 2;
+ break;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ s->repeat_first = TRUE;
+ repeat = 1;
+ break;
+ case PIPE_PRIM_QUADS:
+ max_verts &= ~3;
+ break;
+ case PIPE_PRIM_QUAD_STRIP:
+ max_verts &= ~1;
+ repeat = 2;
+ break;
+ default:
+ break;
+ }
+
+ s->emit (s->priv, s->p_start, max_verts);
+ s->p_start += (max_verts - repeat);
+ return FALSE;
+}
+
#endif
diff --git a/src/gallium/drivers/nouveau/nv04_surface_2d.c b/src/gallium/drivers/nouveau/nv04_surface_2d.c
index b074547c4d..93114465d5 100644
--- a/src/gallium/drivers/nouveau/nv04_surface_2d.c
+++ b/src/gallium/drivers/nouveau/nv04_surface_2d.c
@@ -518,7 +518,6 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d
ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_GPU_READ;
}
- struct nv40_screen* screen = (struct nv40_screen*)pscreen;
ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
struct pipe_texture templ;
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
index 279b74445c..825c167b01 100644
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ b/src/gallium/drivers/nv30/nv30_context.c
@@ -74,6 +74,7 @@ nv30_create(struct pipe_screen *pscreen, void *priv)
nv30_init_query_functions(nv30);
nv30_init_surface_functions(nv30);
nv30_init_state_functions(nv30);
+ nv30_init_transfer_functions(nv30);
/* Create, configure, and install fallback swtnl path */
nv30->draw = draw_create();
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index ea259aadf3..4a164f3b1f 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -107,6 +107,11 @@ struct nv30_state {
struct nouveau_stateobj *hw[NV30_STATE_MAX];
};
+struct nv30_vtxelt_state {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+};
+
struct nv30_context {
struct pipe_context pipe;
@@ -142,8 +147,7 @@ struct nv30_context {
unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
+ struct nv30_vtxelt_state *vtxelt;
};
static INLINE struct nv30_context *
@@ -163,6 +167,7 @@ struct nv30_state_entry {
extern void nv30_init_state_functions(struct nv30_context *nv30);
extern void nv30_init_surface_functions(struct nv30_context *nv30);
extern void nv30_init_query_functions(struct nv30_context *nv30);
+extern void nv30_init_transfer_functions(struct nv30_context *nv30);
extern void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen);
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index 697b1b92ff..bfa27b632f 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -18,7 +18,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@@ -78,7 +78,7 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
- if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
+ if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
@@ -232,8 +232,9 @@ void
nv30_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv30_miptree_create;
- pscreen->texture_blanket = nv30_miptree_blanket;
pscreen->texture_destroy = nv30_miptree_destroy;
pscreen->get_tex_surface = nv30_miptree_surface_new;
pscreen->tex_surface_destroy = nv30_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv30_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 85433d2095..db24335b7c 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -214,7 +214,6 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->context_create = nv30_create;
nv30_screen_init_miptree_functions(pscreen);
- nv30_screen_init_transfer_functions(pscreen);
/* 3D object */
switch (dev->chipset & 0xf0) {
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
index 8591cd31ca..b7856cdf00 100644
--- a/src/gallium/drivers/nv30/nv30_screen.h
+++ b/src/gallium/drivers/nv30/nv30_screen.h
@@ -35,7 +35,4 @@ nv30_screen(struct pipe_screen *screen)
return (struct nv30_screen *)screen;
}
-void
-nv30_screen_init_transfer_functions(struct pipe_screen *pscreen);
-
#endif
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index d911c80707..24b15a63ac 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -669,15 +669,34 @@ nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
}
+static void *
+nv30_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv30_vtxelt_state *cso = CALLOC_STRUCT(nv30_vtxelt_state);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+/* nv30_vtxelt_construct(cso);*/
+
+ return (void *)cso;
+}
+
static void
-nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv30_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv30_context *nv30 = nv30_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv30->vtxelt, ve, sizeof(*ve) * count);
- nv30->vtxelt_nr = count;
+static void
+nv30_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv30_context *nv30 = nv30_context(pipe);
+ nv30->vtxelt = hwcso;
nv30->dirty |= NV30_NEW_ARRAYS;
/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
}
@@ -722,7 +741,10 @@ nv30_init_state_functions(struct nv30_context *nv30)
nv30->pipe.set_scissor_state = nv30_set_scissor_state;
nv30->pipe.set_viewport_state = nv30_set_viewport_state;
+ nv30->pipe.create_vertex_elements_state = nv30_vtxelts_state_create;
+ nv30->pipe.delete_vertex_elements_state = nv30_vtxelts_state_delete;
+ nv30->pipe.bind_vertex_elements_state = nv30_vtxelts_state_bind;
+
nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers;
- nv30->pipe.set_vertex_elements = nv30_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h
index e42e872de7..66c26360cb 100644
--- a/src/gallium/drivers/nv30/nv30_state.h
+++ b/src/gallium/drivers/nv30/nv30_state.h
@@ -70,6 +70,8 @@ struct nv30_fragment_program {
struct nouveau_stateobj *so;
};
+#define NV30_MAX_TEXTURE_LEVELS 16
+
struct nv30_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
@@ -80,7 +82,7 @@ struct nv30_miptree {
struct {
uint pitch;
uint *image_offset;
- } level[PIPE_MAX_TEXTURE_LEVELS];
+ } level[NV30_MAX_TEXTURE_LEVELS];
};
#endif
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
index 3aeda51ea1..cfc109bb74 100644
--- a/src/gallium/drivers/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nv30/nv30_transfer.c
@@ -33,11 +33,12 @@ nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
}
static struct pipe_transfer *
-nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+nv30_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv30_miptree *mt = (struct nv30_miptree *)pt;
struct nv30_transfer *tx;
struct pipe_texture tx_tex_template, *tx_tex;
@@ -117,12 +118,13 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
static void
-nv30_transfer_del(struct pipe_transfer *ptx)
+nv30_transfer_del(struct pipe_context *pcontext,
+ struct pipe_transfer *ptx)
{
struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = ptx->texture->screen;
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv30_screen *nvscreen = nv30_screen(pscreen);
struct pipe_surface *dst;
@@ -145,8 +147,9 @@ nv30_transfer_del(struct pipe_transfer *ptx)
}
static void *
-nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv30_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
@@ -160,8 +163,9 @@ nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
static void
-nv30_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv30_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
@@ -169,10 +173,10 @@ nv30_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
void
-nv30_screen_init_transfer_functions(struct pipe_screen *pscreen)
+nv30_init_transfer_functions(struct nv30_context *nv30)
{
- pscreen->get_tex_transfer = nv30_transfer_new;
- pscreen->tex_transfer_destroy = nv30_transfer_del;
- pscreen->transfer_map = nv30_transfer_map;
- pscreen->transfer_unmap = nv30_transfer_unmap;
+ nv30->pipe.get_tex_transfer = nv30_transfer_new;
+ nv30->pipe.tex_transfer_destroy = nv30_transfer_del;
+ nv30->pipe.transfer_map = nv30_transfer_map;
+ nv30->pipe.transfer_unmap = nv30_transfer_unmap;
}
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
index e48823a913..f3856bb5a5 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nv30/nv30_vbo.c
@@ -492,16 +492,16 @@ nv30_vbo_validate(struct nv30_context *nv30)
int hw;
vtxbuf = so_new(3, 17, 18);
- so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt_nr);
+ so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0);
- so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt_nr);
+ so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt->num_elements);
- for (hw = 0; hw < nv30->vtxelt_nr; hw++) {
+ for (hw = 0; hw < nv30->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb;
unsigned type, ncomp;
- ve = &nv30->vtxelt[hw];
+ ve = &nv30->vtxelt->pipe[hw];
vb = &nv30->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) {
diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c
index 65dc73e88b..e828f17643 100644
--- a/src/gallium/drivers/nv40/nv40_context.c
+++ b/src/gallium/drivers/nv40/nv40_context.c
@@ -74,6 +74,7 @@ nv40_create(struct pipe_screen *pscreen, void *priv)
nv40_init_query_functions(nv40);
nv40_init_surface_functions(nv40);
nv40_init_state_functions(nv40);
+ nv40_init_transfer_functions(nv40);
/* Create, configure, and install fallback swtnl path */
nv40->draw = draw_create();
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index 97fb6a2ef9..cb5d9e2d9d 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -107,6 +107,12 @@ struct nv40_state {
struct nouveau_stateobj *hw[NV40_STATE_MAX];
};
+
+struct nv40_vtxelt_state {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+};
+
struct nv40_context {
struct pipe_context pipe;
@@ -157,8 +163,7 @@ struct nv40_context {
unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
+ struct nv40_vtxelt_state *vtxelt;
};
static INLINE struct nv40_context *
@@ -178,6 +183,7 @@ struct nv40_state_entry {
extern void nv40_init_state_functions(struct nv40_context *nv40);
extern void nv40_init_surface_functions(struct nv40_context *nv40);
extern void nv40_init_query_functions(struct nv40_context *nv40);
+extern void nv40_init_transfer_functions(struct nv40_context *nv40);
extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen);
diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c
index 85d7e1f197..62e97bcea4 100644
--- a/src/gallium/drivers/nv40/nv40_miptree.c
+++ b/src/gallium/drivers/nv40/nv40_miptree.c
@@ -20,7 +20,7 @@ nv40_miptree_layout(struct nv40_miptree *mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@@ -80,7 +80,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
- if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
+ if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
@@ -227,9 +227,10 @@ void
nv40_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv40_miptree_create;
- pscreen->texture_blanket = nv40_miptree_blanket;
pscreen->texture_destroy = nv40_miptree_destroy;
pscreen->get_tex_surface = nv40_miptree_surface_new;
pscreen->tex_surface_destroy = nv40_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv40_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index b216c5e38c..dbcc33d8d9 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -201,7 +201,6 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->context_create = nv40_create;
nv40_screen_init_miptree_functions(pscreen);
- nv40_screen_init_transfer_functions(pscreen);
/* 3D object */
switch (dev->chipset & 0xf0) {
diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h
index 9437aa050d..2765ab764a 100644
--- a/src/gallium/drivers/nv40/nv40_screen.h
+++ b/src/gallium/drivers/nv40/nv40_screen.h
@@ -34,7 +34,4 @@ nv40_screen(struct pipe_screen *screen)
return (struct nv40_screen *)screen;
}
-void
-nv40_screen_init_transfer_functions(struct pipe_screen *pscreen);
-
#endif
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 4f28675e64..ee471e6ce4 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -684,15 +684,34 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
+static void *
+nv40_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv40_vtxelt_state *cso = CALLOC_STRUCT(nv40_vtxelt_state);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+/* nv40_vtxelt_construct(cso);*/
+
+ return (void *)cso;
+}
+
static void
-nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv40_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv40_context *nv40 = nv40_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv40->vtxelt, ve, sizeof(*ve) * count);
- nv40->vtxelt_nr = count;
+static void
+nv40_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv40_context *nv40 = nv40_context(pipe);
+ nv40->vtxelt = hwcso;
nv40->dirty |= NV40_NEW_ARRAYS;
nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
@@ -737,7 +756,10 @@ nv40_init_state_functions(struct nv40_context *nv40)
nv40->pipe.set_scissor_state = nv40_set_scissor_state;
nv40->pipe.set_viewport_state = nv40_set_viewport_state;
+ nv40->pipe.create_vertex_elements_state = nv40_vtxelts_state_create;
+ nv40->pipe.delete_vertex_elements_state = nv40_vtxelts_state_delete;
+ nv40->pipe.bind_vertex_elements_state = nv40_vtxelts_state_bind;
+
nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers;
- nv40->pipe.set_vertex_elements = nv40_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h
index 192074e747..e2e69420ea 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nv40/nv40_state.h
@@ -73,6 +73,8 @@ struct nv40_fragment_program {
struct nouveau_stateobj *so;
};
+#define NV40_MAX_TEXTURE_LEVELS 16
+
struct nv40_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
@@ -83,7 +85,7 @@ struct nv40_miptree {
struct {
uint pitch;
uint *image_offset;
- } level[PIPE_MAX_TEXTURE_LEVELS];
+ } level[NV40_MAX_TEXTURE_LEVELS];
};
#endif
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 8990f303ce..297d71f4fa 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -174,7 +174,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40)
if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
- draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
+ draw_set_vertex_elements(draw, nv40->vtxelt->num_elements, nv40->vtxelt->pipe);
}
nv40_state_do_validate(nv40, swtnl_states);
diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c
index 0462a042c3..c552a68113 100644
--- a/src/gallium/drivers/nv40/nv40_transfer.c
+++ b/src/gallium/drivers/nv40/nv40_transfer.c
@@ -33,11 +33,12 @@ nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
}
static struct pipe_transfer *
-nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+nv40_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv40_miptree *mt = (struct nv40_miptree *)pt;
struct nv40_transfer *tx;
struct pipe_texture tx_tex_template, *tx_tex;
@@ -117,12 +118,12 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
static void
-nv40_transfer_del(struct pipe_transfer *ptx)
+nv40_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = ptx->texture->screen;
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv40_screen *nvscreen = nv40_screen(pscreen);
struct pipe_surface *dst;
@@ -145,8 +146,9 @@ nv40_transfer_del(struct pipe_transfer *ptx)
}
static void *
-nv40_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv40_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture;
@@ -160,8 +162,9 @@ nv40_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
static void
-nv40_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv40_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture;
@@ -169,10 +172,10 @@ nv40_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
void
-nv40_screen_init_transfer_functions(struct pipe_screen *pscreen)
+nv40_init_transfer_functions(struct nv40_context *nv40)
{
- pscreen->get_tex_transfer = nv40_transfer_new;
- pscreen->tex_transfer_destroy = nv40_transfer_del;
- pscreen->transfer_map = nv40_transfer_map;
- pscreen->transfer_unmap = nv40_transfer_unmap;
+ nv40->pipe.get_tex_transfer = nv40_transfer_new;
+ nv40->pipe.tex_transfer_destroy = nv40_transfer_del;
+ nv40->pipe.transfer_map = nv40_transfer_map;
+ nv40->pipe.transfer_unmap = nv40_transfer_unmap;
}
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index 7812460d2e..fabdf4bf23 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -493,16 +493,16 @@ nv40_vbo_validate(struct nv40_context *nv40)
int hw;
vtxbuf = so_new(3, 17, 18);
- so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr);
+ so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0);
- so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr);
+ so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt->num_elements);
- for (hw = 0; hw < nv40->vtxelt_nr; hw++) {
+ for (hw = 0; hw < nv40->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb;
unsigned type, ncomp;
- ve = &nv40->vtxelt[hw];
+ ve = &nv40->vtxelt->pipe[hw];
vb = &nv40->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) {
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile
index 612aea28a3..5d622e1c13 100644
--- a/src/gallium/drivers/nv50/Makefile
+++ b/src/gallium/drivers/nv50/Makefile
@@ -16,6 +16,7 @@ C_SOURCES = \
nv50_surface.c \
nv50_tex.c \
nv50_transfer.c \
- nv50_vbo.c
+ nv50_vbo.c \
+ nv50_push.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index e0b2d2880b..8afc95c9fc 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -36,7 +36,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned mode = 0, i;
- if (!nv50_state_validate(nv50))
+ if (!nv50_state_validate(nv50, 64))
return;
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 7be12fcdef..aa14e17872 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -46,43 +46,13 @@ static void
nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ int i;
- if (nv50->state.fb)
- so_ref(NULL, &nv50->state.fb);
- if (nv50->state.blend)
- so_ref(NULL, &nv50->state.blend);
- if (nv50->state.blend_colour)
- so_ref(NULL, &nv50->state.blend_colour);
- if (nv50->state.zsa)
- so_ref(NULL, &nv50->state.zsa);
- if (nv50->state.rast)
- so_ref(NULL, &nv50->state.rast);
- if (nv50->state.stipple)
- so_ref(NULL, &nv50->state.stipple);
- if (nv50->state.scissor)
- so_ref(NULL, &nv50->state.scissor);
- if (nv50->state.viewport)
- so_ref(NULL, &nv50->state.viewport);
- if (nv50->state.tsc_upload)
- so_ref(NULL, &nv50->state.tsc_upload);
- if (nv50->state.tic_upload)
- so_ref(NULL, &nv50->state.tic_upload);
- if (nv50->state.vertprog)
- so_ref(NULL, &nv50->state.vertprog);
- if (nv50->state.fragprog)
- so_ref(NULL, &nv50->state.fragprog);
- if (nv50->state.geomprog)
- so_ref(NULL, &nv50->state.geomprog);
- if (nv50->state.fp_linkage)
- so_ref(NULL, &nv50->state.fp_linkage);
- if (nv50->state.gp_linkage)
- so_ref(NULL, &nv50->state.gp_linkage);
- if (nv50->state.vtxfmt)
- so_ref(NULL, &nv50->state.vtxfmt);
- if (nv50->state.vtxbuf)
- so_ref(NULL, &nv50->state.vtxbuf);
- if (nv50->state.vtxattr)
- so_ref(NULL, &nv50->state.vtxattr);
+ for (i = 0; i < 64; i++) {
+ if (!nv50->state.hw[i])
+ continue;
+ so_ref(NULL, &nv50->state.hw[i]);
+ }
draw_destroy(nv50->draw);
@@ -123,11 +93,11 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
screen->base.channel->user_private = nv50;
- screen->base.channel->flush_notify = nv50_state_flush_notify;
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
nv50_init_query_functions(nv50);
+ nv50_init_transfer_functions(nv50);
nv50->draw = draw_create();
assert(nv50->draw);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index c540594b94..1743f6fb39 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -72,6 +72,12 @@ struct nv50_sampler_stateobj {
unsigned tsc[8];
};
+struct nv50_vtxelt_stateobj {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+ uint32_t hw[16];
+};
+
static INLINE unsigned
get_tile_height(uint32_t tile_mode)
{
@@ -90,10 +96,12 @@ struct nv50_miptree_level {
unsigned tile_mode;
};
+#define NV50_MAX_TEXTURE_LEVELS 16
+
struct nv50_miptree {
struct nouveau_miptree base;
- struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
+ struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};
@@ -115,30 +123,12 @@ nv50_surface(struct pipe_surface *pt)
}
struct nv50_state {
- unsigned dirty;
+ struct nouveau_stateobj *hw[64];
+ uint64_t hw_dirty;
- struct nouveau_stateobj *fb;
- struct nouveau_stateobj *blend;
- struct nouveau_stateobj *blend_colour;
- struct nouveau_stateobj *zsa;
- struct nouveau_stateobj *stencil_ref;
- struct nouveau_stateobj *rast;
- struct nouveau_stateobj *stipple;
- struct nouveau_stateobj *scissor;
- unsigned scissor_enabled;
- struct nouveau_stateobj *viewport;
- struct nouveau_stateobj *tsc_upload;
- struct nouveau_stateobj *tic_upload;
unsigned miptree_nr[PIPE_SHADER_TYPES];
- struct nouveau_stateobj *vertprog;
- struct nouveau_stateobj *fragprog;
- struct nouveau_stateobj *geomprog;
- struct nouveau_stateobj *fp_linkage;
- struct nouveau_stateobj *gp_linkage;
- struct nouveau_stateobj *vtxfmt;
struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr;
- struct nouveau_stateobj *instbuf;
unsigned vtxelt_nr;
};
@@ -167,14 +157,13 @@ struct nv50_context {
struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
+ struct nv50_vtxelt_stateobj *vtxelt;
struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
unsigned sampler_nr[PIPE_SHADER_TYPES];
struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
unsigned miptree_nr[PIPE_SHADER_TYPES];
- uint16_t vbo_fifo;
+ unsigned vbo_fifo;
};
static INLINE struct nv50_context *
@@ -186,6 +175,7 @@ nv50_context(struct pipe_context *pipe)
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_init_transfer_functions(struct nv50_context *nv50);
extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen);
@@ -216,24 +206,36 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned count,
unsigned startInstance,
unsigned instanceCount);
-extern void nv50_vbo_validate(struct nv50_context *nv50);
+extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
+extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
+
+/* nv50_push.c */
+extern void
+nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *,
+ unsigned idxsize, unsigned mode, unsigned start,
+ unsigned count, unsigned i_start,
+ unsigned i_count);
/* nv50_clear.c */
extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
const float *rgba, double depth, unsigned stencil);
/* nv50_program.c */
-extern void nv50_vertprog_validate(struct nv50_context *nv50);
-extern void nv50_fragprog_validate(struct nv50_context *nv50);
-extern void nv50_geomprog_validate(struct nv50_context *nv50);
-extern void nv50_fp_linkage_validate(struct nv50_context *nv50);
-extern void nv50_gp_linkage_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_vertprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_fragprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_geomprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_fp_linkage_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_gp_linkage_validate(struct nv50_context *nv50);
extern void nv50_program_destroy(struct nv50_context *nv50,
struct nv50_program *p);
/* nv50_state_validate.c */
-extern boolean nv50_state_validate(struct nv50_context *nv50);
-extern void nv50_state_flush_notify(struct nouveau_channel *chan);
+extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords);
extern void nv50_so_init_sifc(struct nv50_context *nv50,
struct nouveau_stateobj *so,
@@ -241,7 +243,8 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50,
unsigned offset, unsigned size);
/* nv50_tex.c */
-extern void nv50_tex_validate(struct nv50_context *);
+extern void nv50_tex_relocs(struct nv50_context *);
+extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
/* nv50_transfer.c */
extern void
@@ -255,4 +258,35 @@ nv50_upload_sifc(struct nv50_context *nv50,
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv);
+static INLINE unsigned
+nv50_prim(unsigned mode)
+{
+ switch (mode) {
+ case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
+ case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
+ case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
+ case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
+ case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
+ case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
+ case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
+ case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
+ case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
+ case PIPE_PRIM_LINES_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
+ default:
+ break;
+ }
+
+ NOUVEAU_ERR("invalid primitive type %d\n", mode);
+ return NV50TCL_VERTEX_BEGIN_POINTS;
+}
+
#endif
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 3f9d869d7a..e091cae602 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -104,7 +104,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
tile_flags = 0x7400;
break;
default:
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) &&
util_format_get_blocksizebits(pt->format) == 32)
tile_flags = 0x7a00;
else
@@ -255,9 +255,10 @@ void
nv50_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv50_miptree_create;
- pscreen->texture_blanket = nv50_miptree_blanket;
pscreen->texture_destroy = nv50_miptree_destroy;
pscreen->get_tex_surface = nv50_miptree_surface_new;
pscreen->tex_surface_destroy = nv50_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 2372cbbef6..c857816b31 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -4270,7 +4270,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
FREE(up);
}
-void
+struct nouveau_stateobj *
nv50_vertprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4286,6 +4286,9 @@ nv50_vertprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_VERTPROG))
+ return NULL;
+
so = so_new(5, 7, 2);
so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4301,11 +4304,10 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.high_temp);
so_method(so, tesla, NV50TCL_VP_START_ID, 1);
so_data (so, 0); /* program start offset */
- so_ref(so, &nv50->state.vertprog);
- so_ref(NULL, &so);
+ return so;
}
-void
+struct nouveau_stateobj *
nv50_fragprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4321,6 +4323,9 @@ nv50_fragprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_FRAGPROG))
+ return NULL;
+
so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4337,11 +4342,10 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.regs[3]);
so_method(so, tesla, NV50TCL_FP_START_ID, 1);
so_data (so, 0); /* program start offset */
- so_ref(so, &nv50->state.fragprog);
- so_ref(NULL, &so);
+ return so;
}
-void
+struct nouveau_stateobj *
nv50_geomprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4357,6 +4361,9 @@ nv50_geomprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_GEOMPROG))
+ return NULL;
+
so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4373,8 +4380,7 @@ nv50_geomprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.vert_count);
so_method(so, tesla, NV50TCL_GP_START_ID, 1);
so_data (so, 0);
- so_ref(so, &nv50->state.geomprog);
- so_ref(NULL, &so);
+ return so;
}
static uint32_t
@@ -4454,7 +4460,7 @@ nv50_vec4_map(uint32_t *map32, int mid, uint8_t zval, uint32_t lin[4],
return mid;
}
-void
+struct nouveau_stateobj *
nv50_fp_linkage_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4580,8 +4586,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_GP_ENABLE, 1);
so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0);
- so_ref(so, &nv50->state.fp_linkage);
- so_ref(NULL, &so);
+ return so;
}
static int
@@ -4615,7 +4620,7 @@ construct_vp_gp_mapping(uint32_t *map32, int m,
return m;
}
-void
+struct nouveau_stateobj *
nv50_gp_linkage_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4625,10 +4630,8 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
uint32_t map[16];
int m = 0;
- if (!gp) {
- so_ref(NULL, &nv50->state.gp_linkage);
- return;
- }
+ if (!gp)
+ return NULL;
memset(map, 0, sizeof(map));
m = construct_vp_gp_mapping(map, m, vp, gp);
@@ -4646,8 +4649,7 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m);
so_datap (so, map, m);
- so_ref(so, &nv50->state.gp_linkage);
- so_ref(NULL, &so);
+ return so;
}
void
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
new file mode 100644
index 0000000000..96a1f32d30
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -0,0 +1,326 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+
+#include "nouveau/nouveau_util.h"
+#include "nv50_context.h"
+
+struct push_context {
+ struct nv50_context *nv50;
+
+ unsigned vtx_size;
+
+ void *idxbuf;
+ unsigned idxsize;
+
+ float edgeflag;
+ int edgeflag_attr;
+
+ struct {
+ void *map;
+ unsigned stride;
+ unsigned divisor;
+ unsigned step;
+ void (*push)(struct nouveau_channel *, void *);
+ } attr[16];
+ unsigned attr_nr;
+};
+
+static void
+emit_b32_1(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b32_2(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+}
+
+static void
+emit_b32_3(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+ OUT_RING(chan, v[2]);
+}
+
+static void
+emit_b32_4(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+ OUT_RING(chan, v[2]);
+ OUT_RING(chan, v[3]);
+}
+
+static void
+emit_b16_1(struct nouveau_channel *chan, void *data)
+{
+ uint16_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b16_3(struct nouveau_channel *chan, void *data)
+{
+ uint16_t *v = data;
+
+ OUT_RING(chan, (v[1] << 16) | v[0]);
+ OUT_RING(chan, v[2]);
+}
+
+static void
+emit_b08_1(struct nouveau_channel *chan, void *data)
+{
+ uint8_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b08_3(struct nouveau_channel *chan, void *data)
+{
+ uint8_t *v = data;
+
+ OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
+}
+
+static INLINE void
+emit_vertex(struct push_context *ctx, unsigned n)
+{
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ int i;
+
+ if (ctx->edgeflag_attr < 16) {
+ float *edgeflag = ctx->attr[ctx->edgeflag_attr].map +
+ ctx->attr[ctx->edgeflag_attr].stride * n;
+
+ if (*edgeflag != ctx->edgeflag) {
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, *edgeflag ? 1 : 0);
+ ctx->edgeflag = *edgeflag;
+ }
+ }
+
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size);
+ for (i = 0; i < ctx->attr_nr; i++)
+ ctx->attr[i].push(chan, ctx->attr[i].map + ctx->attr[i].stride * n);
+}
+
+static void
+emit_edgeflag(void *priv, boolean enabled)
+{
+ struct push_context *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, enabled ? 1 : 0);
+}
+
+static void
+emit_elt08(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint8_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_elt16(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint16_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_elt32(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint32_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_verts(void *priv, unsigned start, unsigned count)
+{
+ while (count--)
+ emit_vertex(priv, start++);
+}
+
+void
+nv50_push_elements_instanced(struct pipe_context *pipe,
+ struct pipe_buffer *idxbuf, unsigned idxsize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned i_start, unsigned i_count)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ struct push_context ctx;
+ const unsigned p_overhead = 4 + /* begin/end */
+ 4; /* potential edgeflag enable/disable */
+ const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */
+ 2; /* potential edgeflag modification */
+ struct u_split_prim s;
+ unsigned vtx_size;
+ boolean nzi = FALSE;
+ int i;
+
+ ctx.nv50 = nv50;
+ ctx.attr_nr = 0;
+ ctx.idxbuf = NULL;
+ ctx.vtx_size = 0;
+ ctx.edgeflag = 0.5f;
+ ctx.edgeflag_attr = nv50->vertprog->cfg.edgeflag_in;
+
+ /* map vertex buffers, determine vertex size */
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
+ struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
+ struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ unsigned size, nr_components, n;
+
+ if (!(nv50->vbo_fifo & (1 << i)))
+ continue;
+ n = ctx.attr_nr++;
+
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
+ assert(bo->map);
+ return;
+ }
+ ctx.attr[n].map = bo->map + vb->buffer_offset + ve->src_offset;
+ nouveau_bo_unmap(bo);
+
+ ctx.attr[n].stride = vb->stride;
+ ctx.attr[n].divisor = ve->instance_divisor;
+ if (ctx.attr[n].divisor) {
+ ctx.attr[n].step = i_start % ve->instance_divisor;
+ ctx.attr[n].map += i_start * vb->stride;
+ }
+
+ size = util_format_get_component_bits(ve->src_format,
+ UTIL_FORMAT_COLORSPACE_RGB, 0);
+ nr_components = util_format_get_nr_components(ve->src_format);
+ switch (size) {
+ case 8:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b08_1; break;
+ case 2: ctx.attr[n].push = emit_b16_1; break;
+ case 3: ctx.attr[n].push = emit_b08_3; break;
+ case 4: ctx.attr[n].push = emit_b32_1; break;
+ }
+ ctx.vtx_size++;
+ break;
+ case 16:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b16_1; break;
+ case 2: ctx.attr[n].push = emit_b32_1; break;
+ case 3: ctx.attr[n].push = emit_b16_3; break;
+ case 4: ctx.attr[n].push = emit_b32_2; break;
+ }
+ ctx.vtx_size += (nr_components + 1) >> 1;
+ break;
+ case 32:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b32_1; break;
+ case 2: ctx.attr[n].push = emit_b32_2; break;
+ case 3: ctx.attr[n].push = emit_b32_3; break;
+ case 4: ctx.attr[n].push = emit_b32_4; break;
+ }
+ ctx.vtx_size += nr_components;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ }
+ vtx_size = ctx.vtx_size + v_overhead;
+
+ /* map index buffer, if present */
+ if (idxbuf) {
+ struct nouveau_bo *bo = nouveau_bo(idxbuf);
+
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
+ assert(bo->map);
+ return;
+ }
+ ctx.idxbuf = bo->map;
+ ctx.idxsize = idxsize;
+ nouveau_bo_unmap(bo);
+ }
+
+ s.priv = &ctx;
+ s.edge = emit_edgeflag;
+ if (idxbuf) {
+ if (idxsize == 1)
+ s.emit = emit_elt08;
+ else
+ if (idxsize == 2)
+ s.emit = emit_elt16;
+ else
+ s.emit = emit_elt32;
+ } else
+ s.emit = emit_verts;
+
+ /* per-instance loop */
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
+ OUT_RING (chan, NV50_CB_AUX | (24 << 8));
+ OUT_RING (chan, i_start);
+ while (i_count--) {
+ unsigned max_verts;
+ boolean done;
+
+ for (i = 0; i < ctx.attr_nr; i++) {
+ if (!ctx.attr[i].divisor ||
+ ctx.attr[i].divisor != ++ctx.attr[i].step)
+ continue;
+ ctx.attr[i].step = 0;
+ ctx.attr[i].map += ctx.attr[i].stride;
+ }
+
+ u_split_prim_init(&s, mode, start, count);
+ do {
+ if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, p_overhead + (6 * vtx_size))) {
+ assert(0);
+ return;
+ }
+ }
+
+ max_verts = AVAIL_RING(chan);
+ max_verts -= p_overhead;
+ max_verts /= vtx_size;
+
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0));
+ done = u_split_prim_next(&s, max_verts);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ } while (!done);
+
+ nzi = TRUE;
+ }
+}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index eed6031eaf..7e2e8aa336 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -95,6 +95,8 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
static int
nv50_screen_get_param(struct pipe_screen *pscreen, int param)
{
+ struct nv50_screen *screen = nv50_screen(pscreen);
+
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 32;
@@ -132,9 +134,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
case NOUVEAU_CAP_HW_VTXBUF:
- return 1;
+ return screen->force_push ? 0 : 1;
case NOUVEAU_CAP_HW_IDXBUF:
- return 1;
+ return screen->force_push ? 0 : 1;
case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -202,28 +204,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
FREE(screen);
}
-static int
-nv50_pre_pipebuffer_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
- unsigned usage)
-{
- struct nv50_screen *screen = nv50_screen(pscreen);
- struct nv50_context *ctx = screen->cur_ctx;
-
- if (!(pb->usage & PIPE_BUFFER_USAGE_VERTEX))
- return 0;
-
- /* Our vtxbuf got mapped, it can no longer be considered part of current
- * state, remove it to avoid emitting reloc markers.
- */
- if (ctx && ctx->state.vtxbuf && so_bo_is_reloc(ctx->state.vtxbuf,
- nouveau_bo(pb))) {
- so_ref(NULL, &ctx->state.vtxbuf);
- ctx->dirty |= NV50_NEW_ARRAYS;
- }
-
- return 0;
-}
-
struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
@@ -252,7 +232,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->get_paramf = nv50_screen_get_paramf;
pscreen->is_format_supported = nv50_screen_is_format_supported;
pscreen->context_create = nv50_create;
- screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map;
nv50_screen_init_miptree_functions(pscreen);
nv50_transfer_init_screen_functions(pscreen);
@@ -508,10 +487,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1);
so_data (so, 1);
- /* activate first scissor rectangle */
- so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
- so_data (so, 1);
-
so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
so_data (so, 1); /* default edgeflag to TRUE */
@@ -520,6 +495,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_ref (NULL, &so);
nouveau_pushbuf_flush(chan, 0);
+ screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
return pscreen;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 2687b72127..d1bc80cb9e 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -28,6 +28,8 @@ struct nv50_screen {
struct nouveau_bo *tsc;
struct nouveau_stateobj *static_init;
+
+ boolean force_push;
};
static INLINE struct nv50_screen *
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 7d304907b6..b0e5552eff 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -302,7 +302,7 @@ static void *
nv50_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
- struct nouveau_stateobj *so = so_new(15, 21, 0);
+ struct nouveau_stateobj *so = so_new(16, 22, 0);
struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
struct nv50_rasterizer_stateobj *rso =
CALLOC_STRUCT(nv50_rasterizer_stateobj);
@@ -314,6 +314,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
* - point_sprite / sprite_coord_mode
*/
+ so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
+ so_data (so, cso->scissor);
+
so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
NV50TCL_SHADE_MODEL_SMOOTH);
@@ -720,15 +723,34 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv50->dirty |= NV50_NEW_ARRAYS;
}
+static void *
+nv50_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+ nv50_vtxelt_construct(cso);
+
+ return (void *)cso;
+}
+
static void
-nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv50_context *nv50 = nv50_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv50->vtxelt, ve, sizeof(*ve) * count);
- nv50->vtxelt_nr = count;
+static void
+nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ nv50->vtxelt = hwcso;
nv50->dirty |= NV50_NEW_ARRAYS;
}
@@ -778,7 +800,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.set_scissor_state = nv50_set_scissor_state;
nv50->pipe.set_viewport_state = nv50_set_viewport_state;
+ nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create;
+ nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete;
+ nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
+
nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
- nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index c974cc92dc..2c8e7ca798 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -25,8 +25,8 @@
#include "nv50_context.h"
#include "nouveau/nouveau_stateobj.h"
-static void
-nv50_state_validate_fb(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_fb(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(32, 79, 18);
@@ -167,12 +167,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data (so, w << 16);
so_data (so, h << 16);
- /* we set scissors to framebuffer size when they're 'turned off' */
- nv50->dirty |= NV50_NEW_SCISSOR;
- so_ref(NULL, &nv50->state.scissor);
-
- so_ref(so, &nv50->state.fb);
- so_ref(NULL, &so);
+ return so;
}
static void
@@ -199,263 +194,256 @@ nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so,
}
}
-static void
-nv50_state_emit(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_blend(struct nv50_context *nv50)
{
- struct nv50_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->blend->so, &so);
+ return so;
+}
- /* XXX: this is racy for multiple contexts active on separate
- * threads.
- */
- if (screen->cur_ctx != nv50) {
- if (nv50->state.fb)
- nv50->state.dirty |= NV50_NEW_FRAMEBUFFER;
- if (nv50->state.blend)
- nv50->state.dirty |= NV50_NEW_BLEND;
- if (nv50->state.zsa)
- nv50->state.dirty |= NV50_NEW_ZSA;
- if (nv50->state.vertprog)
- nv50->state.dirty |= NV50_NEW_VERTPROG;
- if (nv50->state.fragprog)
- nv50->state.dirty |= NV50_NEW_FRAGPROG;
- if (nv50->state.geomprog)
- nv50->state.dirty |= NV50_NEW_GEOMPROG;
- if (nv50->state.rast)
- nv50->state.dirty |= NV50_NEW_RASTERIZER;
- if (nv50->state.blend_colour)
- nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
- if (nv50->state.stencil_ref)
- nv50->state.dirty |= NV50_NEW_STENCIL_REF;
- if (nv50->state.stipple)
- nv50->state.dirty |= NV50_NEW_STIPPLE;
- if (nv50->state.scissor)
- nv50->state.dirty |= NV50_NEW_SCISSOR;
- if (nv50->state.viewport)
- nv50->state.dirty |= NV50_NEW_VIEWPORT;
- if (nv50->state.tsc_upload)
- nv50->state.dirty |= NV50_NEW_SAMPLER;
- if (nv50->state.tic_upload)
- nv50->state.dirty |= NV50_NEW_TEXTURE;
- if (nv50->state.vtxfmt && nv50->state.vtxbuf)
- nv50->state.dirty |= NV50_NEW_ARRAYS;
- screen->cur_ctx = nv50;
- }
+static struct nouveau_stateobj *
+validate_zsa(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->zsa->so, &so);
+ return so;
+}
- if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER)
- so_emit(chan, nv50->state.fb);
- if (nv50->state.dirty & NV50_NEW_BLEND)
- so_emit(chan, nv50->state.blend);
- if (nv50->state.dirty & NV50_NEW_ZSA)
- so_emit(chan, nv50->state.zsa);
- if (nv50->state.dirty & NV50_NEW_VERTPROG)
- so_emit(chan, nv50->state.vertprog);
- if (nv50->state.dirty & NV50_NEW_FRAGPROG)
- so_emit(chan, nv50->state.fragprog);
- if (nv50->state.dirty & NV50_NEW_GEOMPROG && nv50->state.geomprog)
- so_emit(chan, nv50->state.geomprog);
- if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
- NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
- so_emit(chan, nv50->state.fp_linkage);
- if ((nv50->state.dirty & (NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG))
- && nv50->state.gp_linkage)
- so_emit(chan, nv50->state.gp_linkage);
- if (nv50->state.dirty & NV50_NEW_RASTERIZER)
- so_emit(chan, nv50->state.rast);
- if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
- so_emit(chan, nv50->state.blend_colour);
- if (nv50->state.dirty & NV50_NEW_STENCIL_REF)
- so_emit(chan, nv50->state.stencil_ref);
- if (nv50->state.dirty & NV50_NEW_STIPPLE)
- so_emit(chan, nv50->state.stipple);
- if (nv50->state.dirty & NV50_NEW_SCISSOR)
- so_emit(chan, nv50->state.scissor);
- if (nv50->state.dirty & NV50_NEW_VIEWPORT)
- so_emit(chan, nv50->state.viewport);
- if (nv50->state.dirty & NV50_NEW_SAMPLER)
- so_emit(chan, nv50->state.tsc_upload);
- if (nv50->state.dirty & NV50_NEW_TEXTURE)
- so_emit(chan, nv50->state.tic_upload);
- if (nv50->state.dirty & NV50_NEW_ARRAYS) {
- so_emit(chan, nv50->state.vtxfmt);
- so_emit(chan, nv50->state.vtxbuf);
- if (nv50->state.vtxattr)
- so_emit(chan, nv50->state.vtxattr);
- }
- nv50->state.dirty = 0;
+static struct nouveau_stateobj *
+validate_rast(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->rasterizer->so, &so);
+ return so;
}
-void
-nv50_state_flush_notify(struct nouveau_channel *chan)
+static struct nouveau_stateobj *
+validate_blend_colour(struct nv50_context *nv50)
{
- struct nv50_context *nv50 = chan->user_private;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(1, 4, 0);
+
+ so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
+ so_data (so, fui(nv50->blend_colour.color[0]));
+ so_data (so, fui(nv50->blend_colour.color[1]));
+ so_data (so, fui(nv50->blend_colour.color[2]));
+ so_data (so, fui(nv50->blend_colour.color[3]));
+ return so;
+}
- if (nv50->state.tic_upload && !(nv50->dirty & NV50_NEW_TEXTURE))
- so_emit(chan, nv50->state.tic_upload);
+static struct nouveau_stateobj *
+validate_stencil_ref(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so = so_new(2, 2, 0);
- so_emit_reloc_markers(chan, nv50->state.fb);
- so_emit_reloc_markers(chan, nv50->state.vertprog);
- so_emit_reloc_markers(chan, nv50->state.fragprog);
- so_emit_reloc_markers(chan, nv50->state.vtxbuf);
- so_emit_reloc_markers(chan, nv50->screen->static_init);
+ so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
+ so_data (so, nv50->stencil_ref.ref_value[0]);
+ so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
+ so_data (so, nv50->stencil_ref.ref_value[1]);
+ return so;
+}
- if (nv50->state.instbuf)
- so_emit_reloc_markers(chan, nv50->state.instbuf);
+static struct nouveau_stateobj *
+validate_stipple(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(1, 32, 0);
+ int i;
+
+ so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
+ for (i = 0; i < 32; i++)
+ so_data(so, util_bswap32(nv50->stipple.stipple[i]));
+ return so;
}
-boolean
-nv50_state_validate(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_scissor(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct pipe_scissor_state *s = &nv50->scissor;
struct nouveau_stateobj *so;
- unsigned i;
- if (nv50->dirty & NV50_NEW_FRAMEBUFFER)
- nv50_state_validate_fb(nv50);
+ so = so_new(1, 2, 0);
+ so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
+ so_data (so, (s->maxx << 16) | s->minx);
+ so_data (so, (s->maxy << 16) | s->miny);
+ return so;
+}
+
+static struct nouveau_stateobj *
+validate_viewport(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(5, 9, 0);
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
+ so_data (so, fui(nv50->viewport.translate[0]));
+ so_data (so, fui(nv50->viewport.translate[1]));
+ so_data (so, fui(nv50->viewport.translate[2]));
+ so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
+ so_data (so, fui(nv50->viewport.scale[0]));
+ so_data (so, fui(nv50->viewport.scale[1]));
+ so_data (so, fui(nv50->viewport.scale[2]));
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+ so_data (so, 1);
+ /* 0x0000 = remove whole primitive only (xyz)
+ * 0x1018 = remove whole primitive only (xy), clamp z
+ * 0x1080 = clip primitive (xyz)
+ * 0x1098 = clip primitive (xy), clamp z
+ */
+ so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+ so_data (so, 0x1080);
+ /* no idea what 0f90 does */
+ so_method(so, tesla, 0x0f90, 1);
+ so_data (so, 0);
+
+ return so;
+}
- if (nv50->dirty & NV50_NEW_BLEND)
- so_ref(nv50->blend->so, &nv50->state.blend);
+static struct nouveau_stateobj *
+validate_sampler(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so;
+ unsigned nr = 0, i;
- if (nv50->dirty & NV50_NEW_ZSA)
- so_ref(nv50->zsa->so, &nv50->state.zsa);
+ for (i = 0; i < PIPE_SHADER_TYPES; ++i)
+ nr += nv50->sampler_nr[i];
- if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB))
- nv50_vertprog_validate(nv50);
+ so = so_new(1 + 5 * PIPE_SHADER_TYPES,
+ 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
+ PIPE_SHADER_TYPES * 2);
- if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
- nv50_fragprog_validate(nv50);
+ nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
+ nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
- if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB))
- nv50_geomprog_validate(nv50);
+ so_method(so, tesla, 0x1334, 1); /* flush TSC */
+ so_data (so, 0);
- if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
- NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
- nv50_fp_linkage_validate(nv50);
+ return so;
+}
- if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_VERTPROG))
- nv50_gp_linkage_validate(nv50);
+static struct nouveau_stateobj *
+validate_vtxbuf(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->state.vtxbuf, &so);
+ return so;
+}
- if (nv50->dirty & NV50_NEW_RASTERIZER)
- so_ref(nv50->rasterizer->so, &nv50->state.rast);
+static struct nouveau_stateobj *
+validate_vtxattr(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->state.vtxattr, &so);
+ return so;
+}
- if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
- so = so_new(1, 4, 0);
- so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
- so_data (so, fui(nv50->blend_colour.color[0]));
- so_data (so, fui(nv50->blend_colour.color[1]));
- so_data (so, fui(nv50->blend_colour.color[2]));
- so_data (so, fui(nv50->blend_colour.color[3]));
- so_ref(so, &nv50->state.blend_colour);
- so_ref(NULL, &so);
- }
+struct state_validate {
+ struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
+ unsigned states;
+} validate_list[] = {
+ { validate_fb , NV50_NEW_FRAMEBUFFER },
+ { validate_blend , NV50_NEW_BLEND },
+ { validate_zsa , NV50_NEW_ZSA },
+ { nv50_vertprog_validate , NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB },
+ { nv50_fragprog_validate , NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB },
+ { nv50_geomprog_validate , NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB },
+ { nv50_fp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG |
+ NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER },
+ { nv50_gp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG },
+ { validate_rast , NV50_NEW_RASTERIZER },
+ { validate_blend_colour , NV50_NEW_BLEND_COLOUR },
+ { validate_stencil_ref , NV50_NEW_STENCIL_REF },
+ { validate_stipple , NV50_NEW_STIPPLE },
+ { validate_scissor , NV50_NEW_SCISSOR },
+ { validate_viewport , NV50_NEW_VIEWPORT },
+ { validate_sampler , NV50_NEW_SAMPLER },
+ { nv50_tex_validate , NV50_NEW_TEXTURE | NV50_NEW_SAMPLER },
+ { nv50_vbo_validate , NV50_NEW_ARRAYS },
+ { validate_vtxbuf , NV50_NEW_ARRAYS },
+ { validate_vtxattr , NV50_NEW_ARRAYS },
+ {}
+};
+#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
- if (nv50->dirty & NV50_NEW_STENCIL_REF) {
- so = so_new(2, 2, 0);
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
- so_data (so, nv50->stencil_ref.ref_value[0]);
- so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
- so_data (so, nv50->stencil_ref.ref_value[1]);
- so_ref(so, &nv50->state.stencil_ref);
- so_ref(NULL, &so);
- }
+boolean
+nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords)
+{
+ struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ unsigned nr_relocs = 128, nr_dwords = wait_dwords + 128 + 4;
+ int ret, i;
- if (nv50->dirty & NV50_NEW_STIPPLE) {
- so = so_new(1, 32, 0);
- so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
- for (i = 0; i < 32; i++)
- so_data(so, util_bswap32(nv50->stipple.stipple[i]));
- so_ref(so, &nv50->state.stipple);
- so_ref(NULL, &so);
- }
+ for (i = 0; i < validate_list_len; i++) {
+ struct state_validate *validate = &validate_list[i];
+ struct nouveau_stateobj *so;
- if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) {
- struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe;
- struct pipe_scissor_state *s = &nv50->scissor;
+ if (!(nv50->dirty & validate->states))
+ continue;
- if (nv50->state.scissor &&
- (rast->scissor == 0 && nv50->state.scissor_enabled == 0))
- goto scissor_uptodate;
- nv50->state.scissor_enabled = rast->scissor;
+ so = validate->func(nv50);
+ if (!so)
+ continue;
- so = so_new(1, 2, 0);
- so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
- if (nv50->state.scissor_enabled) {
- so_data(so, (s->maxx << 16) | s->minx);
- so_data(so, (s->maxy << 16) | s->miny);
- } else {
- so_data(so, (nv50->framebuffer.width << 16));
- so_data(so, (nv50->framebuffer.height << 16));
- }
- so_ref(so, &nv50->state.scissor);
- so_ref(NULL, &so);
- nv50->state.dirty |= NV50_NEW_SCISSOR;
- }
-scissor_uptodate:
-
- if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
- if (nv50->state.viewport &&
- !(nv50->dirty & NV50_NEW_VIEWPORT))
- goto viewport_uptodate;
-
- so = so_new(5, 9, 0);
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
- so_data (so, fui(nv50->viewport.translate[0]));
- so_data (so, fui(nv50->viewport.translate[1]));
- so_data (so, fui(nv50->viewport.translate[2]));
- so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
- so_data (so, fui(nv50->viewport.scale[0]));
- so_data (so, fui(nv50->viewport.scale[1]));
- so_data (so, fui(nv50->viewport.scale[2]));
-
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
- so_data (so, 1);
- /* 0x0000 = remove whole primitive only (xyz)
- * 0x1018 = remove whole primitive only (xy), clamp z
- * 0x1080 = clip primitive (xyz)
- * 0x1098 = clip primitive (xy), clamp z
- */
- so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
- so_data (so, 0x1080);
- /* no idea what 0f90 does */
- so_method(so, tesla, 0x0f90, 1);
- so_data (so, 0);
+ nr_dwords += (so->total + so->cur);
+ nr_relocs += so->cur_reloc;
- so_ref(so, &nv50->state.viewport);
+ so_ref(so, &nv50->state.hw[i]);
so_ref(NULL, &so);
- nv50->state.dirty |= NV50_NEW_VIEWPORT;
+ nv50->state.hw_dirty |= (1 << i);
}
-viewport_uptodate:
-
- if (nv50->dirty & NV50_NEW_SAMPLER) {
- unsigned nr = 0;
-
- for (i = 0; i < PIPE_SHADER_TYPES; ++i)
- nr += nv50->sampler_nr[i];
+ nv50->dirty = 0;
- so = so_new(1 + 5 * PIPE_SHADER_TYPES,
- 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
- PIPE_SHADER_TYPES * 2);
+ if (nv50->screen->cur_ctx != nv50) {
+ for (i = 0; i < validate_list_len; i++) {
+ if (!nv50->state.hw[i] ||
+ (nv50->state.hw_dirty & (1 << i)))
+ continue;
- nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
- nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
+ nr_dwords += (nv50->state.hw[i]->total +
+ nv50->state.hw[i]->cur);
+ nr_relocs += nv50->state.hw[i]->cur_reloc;
+ nv50->state.hw_dirty |= (1 << i);
+ }
- so_method(so, tesla, 0x1334, 1); /* flush TSC */
- so_data (so, 0);
+ nv50->screen->cur_ctx = nv50;
+ }
- so_ref(so, &nv50->state.tsc_upload);
- so_ref(NULL, &so);
+ ret = MARK_RING(chan, nr_dwords, nr_relocs);
+ if (ret) {
+ debug_printf("MARK_RING(%d, %d) failed: %d\n",
+ nr_dwords, nr_relocs, ret);
+ return FALSE;
}
- if (nv50->dirty & (NV50_NEW_TEXTURE | NV50_NEW_SAMPLER))
- nv50_tex_validate(nv50);
+ while (nv50->state.hw_dirty) {
+ i = ffs(nv50->state.hw_dirty) - 1;
+ nv50->state.hw_dirty &= ~(1 << i);
- if (nv50->dirty & NV50_NEW_ARRAYS)
- nv50_vbo_validate(nv50);
+ so_emit(chan, nv50->state.hw[i]);
+ }
- nv50->state.dirty |= nv50->dirty;
- nv50->dirty = 0;
- nv50_state_emit(nv50);
+ /* Yes, really, we need to do this. If a buffer that is referenced
+ * on the hardware isn't part of changed state above, without doing
+ * this the kernel is given no clue that the buffer is being used
+ * still. This can cause all sorts of fun issues.
+ */
+ nv50_tex_relocs(nv50);
+ so_emit_reloc_markers(chan, nv50->state.hw[0]); /* fb */
+ so_emit_reloc_markers(chan, nv50->state.hw[3]); /* vp */
+ so_emit_reloc_markers(chan, nv50->state.hw[4]); /* fp */
+ so_emit_reloc_markers(chan, nv50->state.hw[17]); /* vb */
+ so_emit_reloc_markers(chan, nv50->screen->static_init);
+ /* No idea.. */
+ BEGIN_RING(chan, tesla, 0x142c, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, tesla, 0x142c, 1);
+ OUT_RING (chan, 0);
return TRUE;
}
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index de0560e20c..4c48b12cd8 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -24,6 +24,7 @@
#include "nv50_texture.h"
#include "nouveau/nouveau_stateobj.h"
+#include "nouveau/nouveau_reloc.h"
#include "util/u_format.h"
@@ -195,6 +196,35 @@ nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
}
void
+nv50_tex_relocs(struct nv50_context *nv50)
+{
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
+ int p, unit;
+
+ p = PIPE_SHADER_FRAGMENT;
+ for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
+ if (!nv50->miptree[p][unit])
+ continue;
+ nouveau_reloc_emit(chan, nv50->screen->tic,
+ ((p * 32) + unit) * 32, NULL,
+ nv50->miptree[p][unit]->base.bo, 0, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_RD, 0, 0);
+ }
+
+ p = PIPE_SHADER_VERTEX;
+ for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
+ if (!nv50->miptree[p][unit])
+ continue;
+ nouveau_reloc_emit(chan, nv50->screen->tic,
+ ((p * 32) + unit) * 32, NULL,
+ nv50->miptree[p][unit]->base.bo, 0, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_RD, 0, 0);
+ }
+}
+
+struct nouveau_stateobj *
nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_stateobj *so;
@@ -217,12 +247,11 @@ nv50_tex_validate(struct nv50_context *nv50)
so_ref(NULL, &so);
NOUVEAU_ERR("failed tex validate\n");
- return;
+ return NULL;
}
so_method(so, tesla, 0x1330, 1); /* flush TIC */
so_data (so, 0);
- so_ref(so, &nv50->state.tic_upload);
- so_ref(NULL, &so);
+ return so;
}
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index 7c360e9e73..9eb223eca6 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -121,11 +121,12 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
}
static struct pipe_transfer *
-nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = nv50_miptree(pt);
struct nv50_miptree_level *lvl = &mt->level[level];
@@ -186,7 +187,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
static void
-nv50_transfer_del(struct pipe_transfer *ptx)
+nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
struct nv50_miptree *mt = nv50_miptree(ptx->texture);
@@ -196,7 +197,7 @@ nv50_transfer_del(struct pipe_transfer *ptx)
unsigned ny = util_format_get_nblocksy(pt->format, tx->base.height);
if (ptx->usage & PIPE_TRANSFER_WRITE) {
- struct pipe_screen *pscreen = pt->screen;
+ struct pipe_screen *pscreen = pcontext->screen;
nv50_transfer_rect_m2mf(pscreen, tx->bo, 0,
tx->base.stride, tx->bo->tile_mode,
@@ -218,7 +219,7 @@ nv50_transfer_del(struct pipe_transfer *ptx)
}
static void *
-nv50_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
unsigned flags = 0;
@@ -236,7 +237,7 @@ nv50_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
static void
-nv50_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
@@ -244,12 +245,12 @@ nv50_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
void
-nv50_transfer_init_screen_functions(struct pipe_screen *pscreen)
+nv50_init_transfer_functions(struct nv50_context *nv50)
{
- pscreen->get_tex_transfer = nv50_transfer_new;
- pscreen->tex_transfer_destroy = nv50_transfer_del;
- pscreen->transfer_map = nv50_transfer_map;
- pscreen->transfer_unmap = nv50_transfer_unmap;
+ nv50->pipe.get_tex_transfer = nv50_transfer_new;
+ nv50->pipe.tex_transfer_destroy = nv50_transfer_del;
+ nv50->pipe.transfer_map = nv50_transfer_map;
+ nv50->pipe.transfer_unmap = nv50_transfer_unmap;
}
void
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 1c8ee0b9ad..6b9c1ee231 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -25,53 +25,9 @@
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
-static boolean
-nv50_push_elements_u08(struct nv50_context *, uint8_t *, unsigned);
-
-static boolean
-nv50_push_elements_u16(struct nv50_context *, uint16_t *, unsigned);
-
-static boolean
-nv50_push_elements_u32(struct nv50_context *, uint32_t *, unsigned);
-
-static boolean
-nv50_push_arrays(struct nv50_context *, unsigned, unsigned);
-
-#define NV50_USING_LOATHED_EDGEFLAG(ctx) ((ctx)->vertprog->cfg.edgeflag_in < 16)
-
-static INLINE unsigned
-nv50_prim(unsigned mode)
-{
- switch (mode) {
- case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
- case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
- case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
- case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
- case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
- case PIPE_PRIM_TRIANGLE_STRIP:
- return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
- case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
- case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
- case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
- case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
- case PIPE_PRIM_LINES_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
- case PIPE_PRIM_LINE_STRIP_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
- case PIPE_PRIM_TRIANGLES_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
- case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
- default:
- break;
- }
-
- NOUVEAU_ERR("invalid primitive type %d\n", mode);
- return NV50TCL_VERTEX_BEGIN_POINTS;
-}
-
static INLINE uint32_t
nv50_vbo_type_to_hw(enum pipe_format format)
{
@@ -139,15 +95,16 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
uint32_t hw_type, hw_size;
enum pipe_format pf = ve->src_format;
const struct util_format_description *desc;
- unsigned size;
+ unsigned size, nr_components;
desc = util_format_description(pf);
assert(desc);
size = util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0);
+ nr_components = util_format_get_nr_components(pf);
hw_type = nv50_vbo_type_to_hw(pf);
- hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
+ hw_size = nv50_vbo_size_to_hw(size, nr_components);
if (!hw_type || !hw_size) {
NOUVEAU_ERR("unsupported vbo format: %s\n", util_format_name(pf));
@@ -161,250 +118,58 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
return (hw_type | hw_size);
}
-/* For instanced drawing from user buffers, hitting the FIFO repeatedly
- * with the same vertex data is probably worse than uploading all data.
- */
-static boolean
-nv50_upload_vtxbuf(struct nv50_context *nv50, unsigned i)
-{
- struct nv50_screen *nscreen = nv50->screen;
- struct pipe_screen *pscreen = &nscreen->base.base;
- struct pipe_buffer *buf = nscreen->strm_vbuf[i];
- struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- uint8_t *src;
- unsigned size = align(vb->buffer->size, 4096);
-
- if (buf && buf->size < size)
- pipe_buffer_reference(&nscreen->strm_vbuf[i], NULL);
-
- if (!nscreen->strm_vbuf[i]) {
- nscreen->strm_vbuf[i] = pipe_buffer_create(
- pscreen, 0, PIPE_BUFFER_USAGE_VERTEX, size);
- buf = nscreen->strm_vbuf[i];
- }
-
- src = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
- if (!src)
- return FALSE;
- src += vb->buffer_offset;
-
- size = (vb->max_index + 1) * vb->stride + 16; /* + 16 is for stride 0 */
- if (vb->buffer_offset + size > vb->buffer->size)
- size = vb->buffer->size - vb->buffer_offset;
-
- pipe_buffer_write(pscreen, buf, vb->buffer_offset, size, src);
- pipe_buffer_unmap(pscreen, vb->buffer);
-
- vb->buffer = buf; /* don't pipe_reference, this is a private copy */
- return TRUE;
-}
-
-static void
-nv50_upload_user_vbufs(struct nv50_context *nv50)
-{
- unsigned i;
-
- if (nv50->vbo_fifo)
- nv50->dirty |= NV50_NEW_ARRAYS;
- if (!(nv50->dirty & NV50_NEW_ARRAYS))
- return;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i) {
- if (nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)
- continue;
- nv50_upload_vtxbuf(nv50, i);
- }
-}
-
-static void
-nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data)
-{
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- float v[4];
-
- util_format_read_4f(nv50->vtxelt[i].src_format,
- v, 0, data, 0, 0, 0, 1, 1);
-
- switch (nv50->vtxelt[i].nr_components) {
- case 4:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_4F_X(i), 4);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- OUT_RINGf (chan, v[3]);
- break;
- case 3:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_3F_X(i), 3);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- break;
- case 2:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_2F_X(i), 2);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- break;
- case 1:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_1F(i), 1);
- OUT_RINGf (chan, v[0]);
- break;
- default:
- assert(0);
- break;
- }
-}
-
-static unsigned
-init_per_instance_arrays_immd(struct nv50_context *nv50,
- unsigned startInstance,
- unsigned pos[16], unsigned step[16])
-{
- struct nouveau_bo *bo;
- unsigned i, b, count = 0;
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- ++count;
- b = nv50->vtxelt[i].vertex_buffer_index;
-
- pos[i] = nv50->vtxelt[i].src_offset +
- nv50->vtxbuf[b].buffer_offset +
- startInstance * nv50->vtxbuf[b].stride;
- step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
- if (!bo->map)
- nouveau_bo_map(bo, NOUVEAU_BO_RD);
-
- nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
- }
-
- return count;
-}
-
-static unsigned
-init_per_instance_arrays(struct nv50_context *nv50,
- unsigned startInstance,
- unsigned pos[16], unsigned step[16])
-{
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
+struct instance {
struct nouveau_bo *bo;
- struct nouveau_stateobj *so;
- unsigned i, b, count = 0;
- const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- if (nv50->vbo_fifo)
- return init_per_instance_arrays_immd(nv50, startInstance,
- pos, step);
-
- so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- ++count;
- b = nv50->vtxelt[i].vertex_buffer_index;
-
- pos[i] = nv50->vtxelt[i].src_offset +
- nv50->vtxbuf[b].buffer_offset +
- startInstance * nv50->vtxbuf[b].stride;
-
- if (!startInstance) {
- step[i] = 0;
- continue;
- }
- step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
-
- so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0);
- }
-
- if (count && startInstance) {
- so_ref (so, &nv50->state.instbuf); /* for flush notify */
- so_emit(chan, nv50->state.instbuf);
- }
- so_ref (NULL, &so);
-
- return count;
-}
+ unsigned delta;
+ unsigned stride;
+ unsigned step;
+ unsigned divisor;
+};
static void
-step_per_instance_arrays_immd(struct nv50_context *nv50,
- unsigned pos[16], unsigned step[16])
+instance_init(struct nv50_context *nv50, struct instance *a, unsigned first)
{
- struct nouveau_bo *bo;
- unsigned i, b;
+ int i;
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- if (++step[i] != nv50->vtxelt[i].instance_divisor)
- continue;
- b = nv50->vtxelt[i].vertex_buffer_index;
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
+ struct pipe_vertex_buffer *vb;
- step[i] = 0;
- pos[i] += nv50->vtxbuf[b].stride;
+ a[i].divisor = ve->instance_divisor;
+ if (a[i].divisor) {
+ vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
+ a[i].bo = nouveau_bo(vb->buffer);
+ a[i].stride = vb->stride;
+ a[i].step = first % a[i].divisor;
+ a[i].delta = vb->buffer_offset + ve->src_offset +
+ (first * a[i].stride);
+ }
}
}
static void
-step_per_instance_arrays(struct nv50_context *nv50,
- unsigned pos[16], unsigned step[16])
+instance_step(struct nv50_context *nv50, struct instance *a)
{
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- struct nouveau_bo *bo;
- struct nouveau_stateobj *so;
- unsigned i, b;
- const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- if (nv50->vbo_fifo) {
- step_per_instance_arrays_immd(nv50, pos, step);
- return;
- }
-
- so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
+ int i;
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ if (!a[i].divisor)
continue;
- b = nv50->vtxelt[i].vertex_buffer_index;
- if (++step[i] == nv50->vtxelt[i].instance_divisor) {
- step[i] = 0;
- pos[i] += nv50->vtxbuf[b].stride;
+ BEGIN_RING(chan, tesla,
+ NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
+ OUT_RELOCh(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ OUT_RELOCl(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ if (++a[i].step == a[i].divisor) {
+ a[i].step = 0;
+ a[i].delta += a[i].stride;
}
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
-
- so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0);
}
-
- so_ref (so, &nv50->state.instbuf); /* for flush notify */
- so_ref (NULL, &so);
-
- so_emit(chan, nv50->state.instbuf);
-}
-
-static INLINE void
-nv50_unmap_vbufs(struct nv50_context *nv50)
-{
- unsigned i;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i)
- if (nouveau_bo(nv50->vtxbuf[i].buffer)->map)
- nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer));
}
void
@@ -415,198 +180,207 @@ nv50_draw_arrays_instanced(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned i, nz_divisors;
- unsigned step[16], pos[16];
-
- if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50_upload_user_vbufs(nv50);
+ struct instance a[16];
+ unsigned prim = nv50_prim(mode);
- nv50_state_validate(nv50);
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, 10 + 16*3))
+ return;
- nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+ if (nv50->vbo_fifo) {
+ nv50_push_elements_instanced(pipe, NULL, 0, mode, start,
+ count, startInstance,
+ instanceCount);
+ return;
+ }
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, startInstance);
+ while (instanceCount--) {
+ if (AVAIL_RING(chan) < (7 + 16*3)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, 7 + 16*3)) {
+ assert(0);
+ return;
+ }
+ }
+ instance_step(nv50, a);
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (nv50->vbo_fifo)
- nv50_push_arrays(nv50, start, count);
- else {
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, prim);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
OUT_RING (chan, start);
OUT_RING (chan, count);
- }
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- for (i = 1; i < instanceCount; i++) {
- if (nz_divisors) /* any non-zero array divisors ? */
- step_per_instance_arrays(nv50, pos, step);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode) | (1 << 28));
-
- if (nv50->vbo_fifo)
- nv50_push_arrays(nv50, start, count);
- else {
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- }
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
- }
- nv50_unmap_vbufs(nv50);
- so_ref(NULL, &nv50->state.instbuf);
+ prim |= (1 << 28);
+ }
}
void
nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- boolean ret;
-
- nv50_state_validate(nv50);
-
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (nv50->vbo_fifo)
- ret = nv50_push_arrays(nv50, start, count);
- else {
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- ret = TRUE;
- }
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- nv50_unmap_vbufs(nv50);
-
- /* XXX: not sure what to do if ret != TRUE: flush and retry?
- */
- assert(ret);
+ nv50_draw_arrays_instanced(pipe, mode, start, count, 0, 1);
}
-static INLINE boolean
-nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
- unsigned start, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
-
- map += start;
+struct inline_ctx {
+ struct nv50_context *nv50;
+ void *map;
+};
- if (nv50->vbo_fifo)
- return nv50_push_elements_u08(nv50, map, count);
+static void
+inline_elt08(void *priv, unsigned start, unsigned count)
+{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ uint8_t *map = (uint8_t *)ctx->map + start;
if (count & 1) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, map[0]);
map++;
- count--;
+ count &= ~1;
}
- while (count) {
- unsigned nr = count > 2046 ? 2046 : count;
- int i;
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1);
- for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[i + 1] << 16) | map[i]);
+ count >>= 1;
+ if (!count)
+ return;
- count -= nr;
- map += nr;
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
+ while (count--) {
+ OUT_RING(chan, (map[1] << 16) | map[0]);
+ map += 2;
}
- return TRUE;
}
-static INLINE boolean
-nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
- unsigned start, unsigned count)
+static void
+inline_elt16(void *priv, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
-
- map += start;
-
- if (nv50->vbo_fifo)
- return nv50_push_elements_u16(nv50, map, count);
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ uint16_t *map = (uint16_t *)ctx->map + start;
if (count & 1) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, map[0]);
+ count &= ~1;
map++;
- count--;
}
- while (count) {
- unsigned nr = count > 2046 ? 2046 : count;
- int i;
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1);
- for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[i + 1] << 16) | map[i]);
+ count >>= 1;
+ if (!count)
+ return;
- count -= nr;
- map += nr;
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
+ while (count--) {
+ OUT_RING(chan, (map[1] << 16) | map[0]);
+ map += 2;
}
- return TRUE;
}
-static INLINE boolean
-nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
- unsigned start, unsigned count)
+static void
+inline_elt32(void *priv, unsigned start, unsigned count)
+{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, count);
+ OUT_RINGp (chan, (uint32_t *)ctx->map + start, count);
+}
+
+static void
+inline_edgeflag(void *priv, boolean enabled)
{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, enabled ? 1 : 0);
+}
+
+static void
+nv50_draw_elements_inline(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer, unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned startInstance, unsigned instanceCount)
+{
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct instance a[16];
+ struct inline_ctx ctx;
+ struct u_split_prim s;
+ boolean nzi = FALSE;
+ unsigned overhead;
+
+ overhead = 16*3; /* potential instance adjustments */
+ overhead += 4; /* Begin()/End() */
+ overhead += 4; /* potential edgeflag disable/reenable */
+ overhead += 3; /* potentially 3 VTX_ELT_U16/U32 packet headers */
+
+ s.priv = &ctx;
+ if (indexSize == 1)
+ s.emit = inline_elt08;
+ else
+ if (indexSize == 2)
+ s.emit = inline_elt16;
+ else
+ s.emit = inline_elt32;
+ s.edge = inline_edgeflag;
+
+ ctx.nv50 = nv50;
+ ctx.map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
+ assert(ctx.map);
+ if (!ctx.map)
+ return;
- map += start;
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, overhead + 6 + 3))
+ return;
- if (nv50->vbo_fifo)
- return nv50_push_elements_u32(nv50, map, count);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
+ OUT_RING (chan, NV50_CB_AUX | (24 << 8));
+ OUT_RING (chan, startInstance);
+ while (instanceCount--) {
+ unsigned max_verts;
+ boolean done;
+
+ u_split_prim_init(&s, mode, start, count);
+ do {
+ if (AVAIL_RING(chan) < (overhead + 6)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, (overhead + 6))) {
+ assert(0);
+ return;
+ }
+ }
- while (count) {
- unsigned nr = count > 2047 ? 2047 : count;
+ max_verts = AVAIL_RING(chan) - overhead;
+ if (max_verts > 2047)
+ max_verts = 2047;
+ if (indexSize != 4)
+ max_verts <<= 1;
+ instance_step(nv50, a);
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, nr);
- OUT_RINGp (chan, map, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1<<28) : 0));
+ done = u_split_prim_next(&s, max_verts);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ } while (!done);
- count -= nr;
- map += nr;
+ nzi = TRUE;
}
- return TRUE;
-}
-static INLINE void
-nv50_draw_elements_inline(struct nv50_context *nv50,
- void *map, unsigned indexSize,
- unsigned start, unsigned count)
-{
- switch (indexSize) {
- case 1:
- nv50_draw_elements_inline_u08(nv50, map, start, count);
- break;
- case 2:
- nv50_draw_elements_inline_u16(nv50, map, start, count);
- break;
- case 4:
- nv50_draw_elements_inline_u32(nv50, map, start, count);
- break;
- }
+ pipe_buffer_unmap(pscreen, indexBuffer);
}
void
@@ -617,49 +391,68 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned startInstance, unsigned instanceCount)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
- unsigned i, nz_divisors;
- unsigned step[16], pos[16];
+ struct instance a[16];
+ unsigned prim = nv50_prim(mode);
- map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
-
- if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50_upload_user_vbufs(nv50);
-
- nv50_state_validate(nv50);
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, 13 + 16*3))
+ return;
- nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+ if (nv50->vbo_fifo) {
+ nv50_push_elements_instanced(pipe, indexBuffer, indexSize,
+ mode, start, count, startInstance,
+ instanceCount);
+ return;
+ } else
+ if (!(indexBuffer->usage & PIPE_BUFFER_USAGE_INDEX) || indexSize == 1) {
+ nv50_draw_elements_inline(pipe, indexBuffer, indexSize,
+ mode, start, count, startInstance,
+ instanceCount);
+ return;
+ }
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, startInstance);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- for (i = 1; i < instanceCount; ++i) {
- if (nz_divisors) /* any non-zero array divisors ? */
- step_per_instance_arrays(nv50, pos, step);
+ while (instanceCount--) {
+ if (AVAIL_RING(chan) < (7 + 16*3)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, 10 + 16*3)) {
+ assert(0);
+ return;
+ }
+ }
+ instance_step(nv50, a);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode) | (1 << 28));
-
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
-
+ OUT_RING (chan, prim);
+ if (indexSize == 4) {
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
+ OUT_RING (chan, count);
+ nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ start << 2, count << 2);
+ } else
+ if (indexSize == 2) {
+ unsigned vb_start = (start & ~1);
+ unsigned vb_end = (start + count + 1) & ~1;
+ unsigned dwords = (vb_end - vb_start) >> 1;
+
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+ OUT_RING (chan, ((start & 1) << 31) | count);
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
+ OUT_RING (chan, dwords);
+ nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ vb_start << 1, dwords << 2);
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+ OUT_RING (chan, 0);
+ }
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
- }
- nv50_unmap_vbufs(nv50);
- so_ref(NULL, &nv50->state.instbuf);
+ prim |= (1 << 28);
+ }
}
void
@@ -667,51 +460,8 @@ nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
-
- nv50_state_validate(nv50);
-
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (!nv50->vbo_fifo && indexSize == 4) {
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
- OUT_RING (chan, count);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
- start << 2, count << 2);
- } else
- if (!nv50->vbo_fifo && indexSize == 2) {
- unsigned vb_start = (start & ~1);
- unsigned vb_end = (start + count + 1) & ~1;
- unsigned dwords = (vb_end - vb_start) >> 1;
-
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
- OUT_RING (chan, ((start & 1) << 31) | count);
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
- OUT_RING (chan, dwords);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
- vb_start << 1, dwords << 2);
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
- OUT_RING (chan, 0);
- } else {
- map = pipe_buffer_map(pscreen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
- nv50_unmap_vbufs(nv50);
- pipe_buffer_unmap(pscreen, indexBuffer);
- }
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
+ nv50_draw_elements_instanced(pipe, indexBuffer, indexSize,
+ mode, start, count, 0, 1);
}
static INLINE boolean
@@ -726,6 +476,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
float v[4];
int ret;
+ unsigned nr_components = util_format_get_nr_components(ve->src_format);
ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
if (ret)
@@ -736,9 +487,10 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
0, 0, 1, 1);
so = *pso;
if (!so)
- *pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0);
+ *pso = so = so_new(nv50->vtxelt->num_elements,
+ nv50->vtxelt->num_elements * 4, 0);
- switch (ve->nr_components) {
+ switch (nr_components) {
case 4:
so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4);
so_data (so, fui(v[0]));
@@ -775,6 +527,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
}
void
+nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso)
+{
+ unsigned i;
+
+ for (i = 0; i < cso->num_elements; ++i) {
+ struct pipe_vertex_element *ve = &cso->pipe[i];
+
+ cso->hw[i] = nv50_vbo_vtxelt_to_hw(ve);
+ }
+}
+
+struct nouveau_stateobj *
nv50_vbo_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -783,30 +547,31 @@ nv50_vbo_validate(struct nv50_context *nv50)
/* don't validate if Gallium took away our buffers */
if (nv50->vtxbuf_nr == 0)
- return;
- nv50->vbo_fifo = 0;
+ return NULL;
+
+ if (nv50->screen->force_push ||
+ nv50->vertprog->cfg.edgeflag_in < 16)
+ nv50->vbo_fifo = 0xffff;
- for (i = 0; i < nv50->vtxbuf_nr; ++i)
+ for (i = 0; i < nv50->vtxbuf_nr; i++) {
if (nv50->vtxbuf[i].stride &&
!(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX))
nv50->vbo_fifo = 0xffff;
+ }
- if (NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */
-
- n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr);
+ n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr);
vtxattr = NULL;
- vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt_nr * 4);
+ vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4);
vtxfmt = so_new(1, n_ve, 0);
so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve);
- for (i = 0; i < nv50->vtxelt_nr; i++) {
- struct pipe_vertex_element *ve = &nv50->vtxelt[i];
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
- uint32_t hw = nv50_vbo_vtxelt_to_hw(ve);
+ uint32_t hw = nv50->vtxelt->hw[i];
if (!vb->stride &&
nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
@@ -821,13 +586,13 @@ nv50_vbo_validate(struct nv50_context *nv50)
}
if (nv50->vbo_fifo) {
- so_data (vtxfmt, hw |
- (ve->instance_divisor ? (1 << 4) : i));
+ so_data (vtxfmt, hw | (ve->instance_divisor ? (1 << 4) : i));
so_method(vtxbuf, tesla,
NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
so_data (vtxbuf, 0);
continue;
}
+
so_data(vtxfmt, hw | i);
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
@@ -855,355 +620,13 @@ nv50_vbo_validate(struct nv50_context *nv50)
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
so_data (vtxbuf, 0);
}
- nv50->state.vtxelt_nr = nv50->vtxelt_nr;
+ nv50->state.vtxelt_nr = nv50->vtxelt->num_elements;
- so_ref (vtxfmt, &nv50->state.vtxfmt);
so_ref (vtxbuf, &nv50->state.vtxbuf);
so_ref (vtxattr, &nv50->state.vtxattr);
so_ref (NULL, &vtxbuf);
- so_ref (NULL, &vtxfmt);
so_ref (NULL, &vtxattr);
+ return vtxfmt;
}
-typedef void (*pfn_push)(struct nouveau_channel *, void *);
-
-struct nv50_vbo_emitctx
-{
- pfn_push push[16];
- uint8_t *map[16];
- unsigned stride[16];
- unsigned nr_ve;
- unsigned vtx_dwords;
- unsigned vtx_max;
-
- float edgeflag;
- unsigned ve_edgeflag;
-};
-
-static INLINE void
-emit_vtx_next(struct nouveau_channel *chan, struct nv50_vbo_emitctx *emit)
-{
- unsigned i;
-
- for (i = 0; i < emit->nr_ve; ++i) {
- emit->push[i](chan, emit->map[i]);
- emit->map[i] += emit->stride[i];
- }
-}
-
-static INLINE void
-emit_vtx(struct nouveau_channel *chan, struct nv50_vbo_emitctx *emit,
- uint32_t vi)
-{
- unsigned i;
-
- for (i = 0; i < emit->nr_ve; ++i)
- emit->push[i](chan, emit->map[i] + emit->stride[i] * vi);
-}
-
-static INLINE boolean
-nv50_map_vbufs(struct nv50_context *nv50)
-{
- int i;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i) {
- struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- unsigned size = vb->stride * (vb->max_index + 1) + 16;
-
- if (nouveau_bo(vb->buffer)->map)
- continue;
-
- size = vb->stride * (vb->max_index + 1) + 16;
- size = MIN2(size, vb->buffer->size);
- if (!size)
- size = vb->buffer->size;
-
- if (nouveau_bo_map_range(nouveau_bo(vb->buffer),
- 0, size, NOUVEAU_BO_RD))
- break;
- }
-
- if (i == nv50->vtxbuf_nr)
- return TRUE;
- for (; i >= 0; --i)
- nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer));
- return FALSE;
-}
-
-static void
-emit_b32_1(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b32_2(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
-}
-
-static void
-emit_b32_3(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
- OUT_RING(chan, v[2]);
-}
-
-static void
-emit_b32_4(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
- OUT_RING(chan, v[2]);
- OUT_RING(chan, v[3]);
-}
-
-static void
-emit_b16_1(struct nouveau_channel *chan, void *data)
-{
- uint16_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b16_3(struct nouveau_channel *chan, void *data)
-{
- uint16_t *v = data;
-
- OUT_RING(chan, (v[1] << 16) | v[0]);
- OUT_RING(chan, v[2]);
-}
-
-static void
-emit_b08_1(struct nouveau_channel *chan, void *data)
-{
- uint8_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b08_3(struct nouveau_channel *chan, void *data)
-{
- uint8_t *v = data;
-
- OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
-}
-
-static boolean
-emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,
- unsigned start)
-{
- unsigned i;
-
- if (nv50_map_vbufs(nv50) == FALSE)
- return FALSE;
-
- emit->ve_edgeflag = nv50->vertprog->cfg.edgeflag_in;
-
- emit->edgeflag = 0.5f;
- emit->nr_ve = 0;
- emit->vtx_dwords = 0;
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- struct pipe_vertex_element *ve;
- struct pipe_vertex_buffer *vb;
- unsigned n, size;
- const struct util_format_description *desc;
-
- ve = &nv50->vtxelt[i];
- vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor)
- continue;
- n = emit->nr_ve++;
-
- emit->stride[n] = vb->stride;
- emit->map[n] = (uint8_t *)nouveau_bo(vb->buffer)->map +
- vb->buffer_offset +
- (start * vb->stride + ve->src_offset);
-
- desc = util_format_description(ve->src_format);
- assert(desc);
-
- size = util_format_get_component_bits(
- ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0);
-
- assert(ve->nr_components > 0 && ve->nr_components <= 4);
-
- /* It shouldn't be necessary to push the implicit 1s
- * for case 3 and size 8 cases 1, 2, 3.
- */
- switch (size) {
- default:
- NOUVEAU_ERR("unsupported vtxelt size: %u\n", size);
- return FALSE;
- case 32:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b32_1; break;
- case 2: emit->push[n] = emit_b32_2; break;
- case 3: emit->push[n] = emit_b32_3; break;
- case 4: emit->push[n] = emit_b32_4; break;
- }
- emit->vtx_dwords += ve->nr_components;
- break;
- case 16:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b16_1; break;
- case 2: emit->push[n] = emit_b32_1; break;
- case 3: emit->push[n] = emit_b16_3; break;
- case 4: emit->push[n] = emit_b32_2; break;
- }
- emit->vtx_dwords += (ve->nr_components + 1) >> 1;
- break;
- case 8:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b08_1; break;
- case 2: emit->push[n] = emit_b16_1; break;
- case 3: emit->push[n] = emit_b08_3; break;
- case 4: emit->push[n] = emit_b32_1; break;
- }
- emit->vtx_dwords += 1;
- break;
- }
- }
-
- emit->vtx_max = 512 / emit->vtx_dwords;
- if (emit->ve_edgeflag < 16)
- emit->vtx_max = 1;
-
- return TRUE;
-}
-
-static INLINE void
-set_edgeflag(struct nouveau_channel *chan,
- struct nouveau_grobj *tesla,
- struct nv50_vbo_emitctx *emit, uint32_t index)
-{
- unsigned i = emit->ve_edgeflag;
-
- if (i < 16) {
- float f = *((float *)(emit->map[i] + index * emit->stride[i]));
-
- if (emit->edgeflag != f) {
- emit->edgeflag = f;
-
- BEGIN_RING(chan, tesla, 0x15e4, 1);
- OUT_RING (chan, f ? 1 : 0);
- }
- }
-}
-
-static boolean
-nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
- if (emit_prepare(nv50, &emit, start) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx_next(chan, &emit);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index 1f69daec81..61b54af4dd 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -19,7 +19,8 @@ C_SOURCES = \
r300_state_invariant.c \
r300_vs.c \
r300_texture.c \
- r300_tgsi_to_rc.c
+ r300_tgsi_to_rc.c \
+ r300_transfer.c
LIBRARY_INCLUDES = \
-I$(TOP)/src/mesa/drivers/dri/r300/compiler \
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 183aa17f9b..27b2e30993 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -30,6 +30,7 @@ r300 = env.ConvenienceLibrary(
'r300_vs.c',
'r300_texture.c',
'r300_tgsi_to_rc.c',
+ 'r300_transfer.c',
] + r300compiler) + r300compiler
Export('r300')
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 513cc0f5d4..b7ad6b2020 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -36,6 +36,7 @@ static void r300_blitter_save_states(struct r300_context* r300)
util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
util_blitter_save_viewport(r300->blitter, &r300->viewport);
util_blitter_save_clip(r300->blitter, &r300->clip);
+ util_blitter_save_vertex_elements(r300->blitter, r300->velems);
}
/* Clear currently bound buffers. */
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 86b98a4ba5..8606c0004e 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -34,6 +34,7 @@
#include "r300_screen.h"
#include "r300_state_invariant.h"
#include "r300_texture.h"
+#include "r300_transfer.h"
#include "radeon_winsys.h"
@@ -60,7 +61,6 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state);
FREE(r300->textures_state.state);
- FREE(r300->vertex_stream_state.state);
FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
@@ -72,11 +72,8 @@ r300_is_texture_referenced(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level)
{
- struct pipe_buffer* buf = 0;
-
- r300_get_texture_buffer(pipe->screen, texture, &buf, NULL);
-
- return pipe->is_buffer_referenced(pipe, buf);
+ return pipe->is_buffer_referenced(pipe,
+ ((struct r300_texture *)texture)->buffer);
}
static unsigned int
@@ -86,7 +83,14 @@ r300_is_buffer_referenced(struct pipe_context *pipe,
/* This only checks to see whether actual hardware buffers are
* referenced. Since we use managed BOs and transfers, it's actually not
* possible for pipe_buffers to ever reference the actual hardware, so
- * buffers are never referenced. */
+ * buffers are never referenced.
+ */
+
+ /* XXX: that doesn't make sense given that
+ * r300_is_texture_referenced is implemented on top of this
+ * function and hardware can certainly refer to textures
+ * directly...
+ */
return 0;
}
@@ -143,7 +147,6 @@ static void r300_setup_atoms(struct r300_context* r300)
r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
- r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
@@ -159,6 +162,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300)
return NULL;
+ r300screen->ctx = (struct pipe_context*)r300;
+
r300->winsys = radeon_winsys;
r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
@@ -205,6 +210,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300_init_query_functions(r300);
+ r300_init_transfer_functions(r300);
+
/* r300_init_surface_functions(r300); */
r300_init_state_functions(r300);
@@ -212,7 +219,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->invariant_state.dirty = TRUE;
r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
- r300->dirty_state = R300_NEW_KITCHEN_SINK;
r300->dirty_hw++;
r300->blitter = util_blitter_create(&r300->context);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 0d1518a05b..03b09603c7 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -124,13 +124,15 @@ struct r300_texture_format_state {
uint32_t format2; /* R300_TX_FORMAT2: 0x4500 */
};
+#define R300_MAX_TEXTURE_LEVELS 13
+
struct r300_texture_fb_state {
/* Colorbuffer. */
- uint32_t colorpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
+ uint32_t colorpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
uint32_t us_out_fmt; /* R300_US_OUT_FMT[0-3] */
/* Zbuffer. */
- uint32_t depthpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */
+ uint32_t depthpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */
uint32_t zb_format; /* R300_ZB_FORMAT */
};
@@ -236,16 +238,16 @@ struct r300_texture {
struct pipe_texture tex;
/* Offsets into the buffer. */
- unsigned offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned offset[R300_MAX_TEXTURE_LEVELS];
/* A pitch for each mip-level */
- unsigned pitch[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned pitch[R300_MAX_TEXTURE_LEVELS];
/* Size of one zslice or face based on the texture target */
- unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned layer_size[R300_MAX_TEXTURE_LEVELS];
/* Whether the mipmap level is macrotiled. */
- enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS];
+ enum r300_buffer_tiling mip_macrotile[R300_MAX_TEXTURE_LEVELS];
/**
* If non-zero, override the natural texture layout with
@@ -276,6 +278,23 @@ struct r300_texture {
enum r300_buffer_tiling microtile, macrotile;
};
+struct r300_vertex_info {
+ /* Parent class */
+ struct vertex_info vinfo;
+
+ /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
+ uint32_t vap_prog_stream_cntl[8];
+ /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
+ uint32_t vap_prog_stream_cntl_ext[8];
+};
+
+struct r300_vertex_element_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+
+ struct r300_vertex_stream_state vertex_stream;
+};
+
extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context {
@@ -348,8 +367,7 @@ struct r300_context {
int vertex_buffer_count;
int vertex_buffer_max_index;
/* Vertex elements for Gallium. */
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- int vertex_element_count;
+ struct r300_vertex_element_state *velems;
/* Vertex info for Draw. */
struct vertex_info vertex_info;
@@ -368,6 +386,8 @@ struct r300_context {
boolean polygon_offset_enabled;
/* Z buffer bit depth. */
uint32_t zbuffer_bpp;
+ /* Whether scissor is enabled. */
+ boolean scissor_enabled;
};
/* Convenience cast wrapper. */
@@ -384,6 +404,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct draw_stage* r300_draw_stage(struct r300_context* r300);
void r300_init_state_functions(struct r300_context* r300);
void r300_init_surface_functions(struct r300_context* r300);
+void r300_init_tex_functions( struct pipe_context *pipe );
static INLINE boolean CTX_DBG_ON(struct r300_context * ctx, unsigned flags)
{
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index addb28bded..55e9217fd3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -675,7 +675,7 @@ void r300_emit_scissor_state(struct r300_context* r300,
maxx = fb->width;
maxy = fb->height;
- if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
+ if (r300->scissor_enabled) {
minx = MAX2(minx, scissor->minx);
miny = MAX2(miny, scissor->miny);
maxx = MIN2(maxx, scissor->maxx);
@@ -757,9 +757,9 @@ void r300_emit_textures_state(struct r300_context *r300,
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
int i;
- unsigned size1, size2, aos_count = r300->vertex_element_count;
+ unsigned size1, size2, aos_count = r300->velems->count;
unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300);
@@ -794,6 +794,30 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
END_CS;
}
+void r300_emit_vertex_buffer(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, "
+ "vertex size %d\n", r300->vbo,
+ r300->vertex_info.size);
+ /* Set the pointer to our vertex buffer. The emitted values are this:
+ * PACKET3 [3D_LOAD_VBPNTR]
+ * COUNT [1]
+ * FORMAT [size | stride << 8]
+ * OFFSET [offset into BO]
+ * VBPNTR [relocated BO]
+ */
+ BEGIN_CS(7);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
+ OUT_CS(1);
+ OUT_CS(r300->vertex_info.size |
+ (r300->vertex_info.size << 8));
+ OUT_CS(r300->vbo_offset);
+ OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
+}
+
void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state)
{
@@ -868,7 +892,7 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
CS_LOCALS(r300);
if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vertex_shader called,"
+ debug_printf("r300: Implementation error: emit_vs_state called,"
" but has_tcl is FALSE!\n");
return;
}
@@ -907,7 +931,7 @@ void r300_emit_vs_constant_buffer(struct r300_context* r300,
CS_LOCALS(r300);
if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vertex_shader called,"
+ debug_printf("r300: Implementation error: emit_vs_constant_buffer called,"
" but has_tcl is FALSE!\n");
return;
}
@@ -980,7 +1004,7 @@ void r300_emit_buffer_validate(struct r300_context *r300,
(struct r300_textures_state*)r300->textures_state.state;
struct r300_texture* tex;
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
struct pipe_buffer *pbuf;
unsigned i;
boolean invalid = FALSE;
@@ -1038,7 +1062,7 @@ validate:
}
/* ...vertex buffers for HWTCL path... */
if (do_validate_vertex_buffers) {
- for (i = 0; i < r300->vertex_element_count; i++) {
+ for (i = 0; i < r300->velems->count; i++) {
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
if (!r300->winsys->add_buffer(r300->winsys, pbuf,
@@ -1135,8 +1159,10 @@ void r300_emit_dirty_state(struct r300_context* r300)
assert(r300->dirty_state == 0);
*/
- /* Finally, emit the VBO. */
- /* r300_emit_vertex_buffer(r300); */
+ /* Emit the VBO for SWTCL. */
+ if (!r300screen->caps->has_tcl) {
+ r300_emit_vertex_buffer(r300);
+ }
r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index e37d309270..70de152713 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -61,6 +61,12 @@ static void r300_flush(struct pipe_context* pipe,
atom->dirty = TRUE;
}
}
+
+ /* Unmark HWTCL state for SWTCL. */
+ if (!r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->vs_state.dirty = FALSE;
+ r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
+ }
}
/* reset flushed query */
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 3c2625269b..9e71e61c30 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -207,6 +207,7 @@ static void r300_translate_fragment_shader(
DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
compiler.Base.ErrorMsg);
assert(0);
+ abort();
}
/* And, finally... */
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 6c891029a5..ef1b7510e1 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -143,7 +143,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
- unsigned vertex_element_count = r300->vertex_element_count;
+ unsigned vertex_element_count = r300->velems->count;
unsigned i, v, vbi, dw, elem_offset, dwords;
/* Size of the vertex, in dwords. */
@@ -166,7 +166,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
offset[i] = velem->src_offset / 4;
size[i] = util_format_get_blocksize(velem->src_format) / 4;
vertex_size += size[i];
@@ -183,18 +183,19 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
}
}
- dwords = 10 + count * vertex_size;
+ dwords = 9 + count * vertex_size;
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
- r300_emit_buffer_validate(r300, FALSE, 0);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
BEGIN_CS(dwords);
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
r300_translate_primitive(mode));
@@ -202,7 +203,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Emit vertices. */
for (v = 0; v < count; v++) {
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
vbi = velem->vertex_buffer_index;
elem_offset = offset[i] + stride[vbi] * (v + start);
@@ -215,7 +216,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Unmap buffers. */
for (i = 0; i < vertex_element_count; i++) {
- vbi = r300->vertex_element[i].vertex_buffer_index;
+ vbi = r300->velems->velem[i].vertex_buffer_index;
if (map[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
@@ -238,15 +239,16 @@ static void r300_emit_draw_arrays(struct r300_context *r300,
if (alt_num_verts) {
assert(count < (1 << 24));
- BEGIN_CS(10);
+ BEGIN_CS(9);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else {
- BEGIN_CS(8);
+ BEGIN_CS(7);
}
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300_translate_primitive(mode) |
@@ -278,18 +280,19 @@ static void r300_emit_draw_elements(struct r300_context *r300,
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
count, minIndex, maxIndex);
- maxIndex = MIN2(maxIndex, ((1 << 24) - 1));
+ maxIndex = MIN3(maxIndex, r300->vertex_buffer_max_index, (1 << 24) - 1);
if (alt_num_verts) {
- BEGIN_CS(16);
+ BEGIN_CS(15);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else {
- BEGIN_CS(14);
+ BEGIN_CS(13);
}
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(maxIndex);
+ OUT_CS(minIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) {
count_dwords = count;
@@ -450,7 +453,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
/* Make sure there are at least 128 spare dwords in the command buffer.
* (most of it being consumed by emit_aos) */
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
- r300_emit_buffer_validate(r300, TRUE, 0);
+ r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
if (alt_num_verts || count <= 65535) {
@@ -468,7 +471,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
/* Again, we emit both AOS and draw_arrays so there should be
* at least 128 spare dwords. */
if (count && r300_reserve_cs_space(r300, 128)) {
- r300_emit_buffer_validate(r300, TRUE, 0);
+ r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
}
} while (count);
@@ -688,6 +691,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
@@ -711,6 +715,7 @@ static void r300_render_draw(struct vbuf_render* render,
CS_LOCALS(r300);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
BEGIN_CS(dwords);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index d397a8eb2b..64d1909a38 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,13 +21,11 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_simple_screen.h"
#include "r300_context.h"
-#include "r300_screen.h"
#include "r300_texture.h"
#include "radeon_winsys.h"
@@ -231,14 +230,16 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
/* Check colorbuffer format support. */
if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) &&
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) &&
/* 2101010 cannot be rendered to on non-r5xx. */
(is_r500 || !is_color2101010) &&
r300_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED);
}
/* Check depth-stencil format support. */
@@ -250,70 +251,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
return retval == usage;
}
-static struct pipe_transfer*
-r300_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
-{
- struct r300_texture *tex = (struct r300_texture *)texture;
- struct r300_transfer *trans;
- struct r300_screen *rscreen = r300_screen(screen);
- unsigned offset;
-
- offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */
-
- trans = CALLOC_STRUCT(r300_transfer);
- if (trans) {
- pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.x = x;
- trans->transfer.y = y;
- trans->transfer.width = w;
- trans->transfer.height = h;
- trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level);
- trans->transfer.usage = usage;
- trans->transfer.zslice = zslice;
- trans->transfer.face = face;
-
- trans->offset = offset;
- }
- return &trans->transfer;
-}
-
-static void
-r300_tex_transfer_destroy(struct pipe_transfer *trans)
-{
- pipe_texture_reference(&trans->texture, NULL);
- FREE(trans);
-}
-
-static void* r300_transfer_map(struct pipe_screen* screen,
- struct pipe_transfer* transfer)
-{
- struct r300_texture* tex = (struct r300_texture*)transfer->texture;
- char* map;
- enum pipe_format format = tex->tex.format;
-
- map = pipe_buffer_map(screen, tex->buffer,
- pipe_transfer_buffer_flags(transfer));
-
- if (!map) {
- return NULL;
- }
-
- return map + r300_transfer(transfer)->offset +
- transfer->y / util_format_get_blockheight(format) * transfer->stride +
- transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
-}
-
-static void r300_transfer_unmap(struct pipe_screen* screen,
- struct pipe_transfer* transfer)
-{
- struct r300_texture* tex = (struct r300_texture*)transfer->texture;
- pipe_buffer_unmap(screen, tex->buffer);
-}
-
static void r300_destroy_screen(struct pipe_screen* pscreen)
{
struct r300_screen* r300screen = r300_screen(pscreen);
@@ -350,13 +287,10 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
r300screen->screen.get_paramf = r300_get_paramf;
r300screen->screen.is_format_supported = r300_is_format_supported;
r300screen->screen.context_create = r300_create_context;
- r300screen->screen.get_tex_transfer = r300_get_tex_transfer;
- r300screen->screen.tex_transfer_destroy = r300_tex_transfer_destroy;
- r300screen->screen.transfer_map = r300_transfer_map;
- r300screen->screen.transfer_unmap = r300_transfer_unmap;
r300_init_screen_texture_functions(&r300screen->screen);
u_simple_screen_init(&r300screen->screen);
return &r300screen->screen;
}
+
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 502fbfa5a2..484bde6a6b 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -27,6 +28,8 @@
#include "r300_chipset.h"
+#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM
+
struct radeon_winsys;
struct r300_screen {
@@ -35,6 +38,10 @@ struct r300_screen {
struct radeon_winsys* radeon_winsys;
+ /* XXX This hack will be removed once texture transfers become part of
+ * pipe_context. */
+ struct pipe_context* ctx;
+
/* Chipset capabilities */
struct r300_capabilities* caps;
@@ -42,25 +49,14 @@ struct r300_screen {
unsigned debug;
};
-struct r300_transfer {
- /* Parent class */
- struct pipe_transfer transfer;
-
- /* Offset from start of buffer. */
- unsigned offset;
-};
/* Convenience cast wrapper. */
static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
return (struct r300_screen*)screen;
}
-/* Convenience cast wrapper. */
-static INLINE struct r300_transfer*
-r300_transfer(struct pipe_transfer* transfer)
-{
- return (struct r300_transfer*)transfer;
-}
+/* Creates a new r300 screen. */
+struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
/* Debug functionality. */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 1f6f99d3e5..ced6c810ec 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -571,6 +571,7 @@ static void
{
struct r300_context* r300 = r300_context(pipe);
struct r300_screen* r300screen = r300_screen(pipe->screen);
+ struct pipe_framebuffer_state *old_state = r300->fb_state.state;
unsigned max_width, max_height;
uint32_t zbuffer_bpp = 0;
@@ -595,23 +596,30 @@ static void
return;
}
-
if (r300->draw) {
draw_flush(r300->draw);
}
- memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+ r300->fb_state.dirty = TRUE;
- r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
- (state->zsbuf ? 10 : 0) + 8;
+ /* If nr_cbufs is changed from zero to non-zero or vice versa... */
+ if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
+ r300->blend_state.dirty = TRUE;
+ }
+ /* If zsbuf is set from NULL to non-NULL or vice versa.. */
+ if (!!old_state->zsbuf != !!state->zsbuf) {
+ r300->dsa_state.dirty = TRUE;
+ }
+ if (!r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
+ }
r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
- /* XXX wait what */
- r300->blend_state.dirty = TRUE;
- r300->dsa_state.dirty = TRUE;
- r300->fb_state.dirty = TRUE;
- r300->scissor_state.dirty = TRUE;
+ memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+
+ r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
+ (state->zsbuf ? 10 : 0) + 8;
/* Polygon offset depends on the zbuffer bit depth. */
if (state->zsbuf && r300->polygon_offset_enabled) {
@@ -716,8 +724,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->vap_control_status = R300_VC_32BIT_SWAP;
#endif
- /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
- * Else, enable HW TCL and force Draw's TCL off. */
+ /* If no TCL engine is present, turn off the HW TCL. */
if (!r300screen->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
}
@@ -807,6 +814,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ boolean scissor_was_enabled = r300->scissor_enabled;
if (r300->draw) {
draw_flush(r300->draw);
@@ -815,20 +823,17 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
+ r300->scissor_enabled = rs->rs.scissor;
} else {
r300->polygon_offset_enabled = FALSE;
+ r300->scissor_enabled = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
- /* XXX Why is this still needed, dammit!? */
- r300->scissor_state.dirty = TRUE;
- r300->viewport_state.dirty = TRUE;
-
- /* XXX Clean these up when we move to atom emits */
- if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ if (scissor_was_enabled != r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
}
}
@@ -973,7 +978,9 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
memcpy(r300->scissor_state.state, state,
sizeof(struct pipe_scissor_state));
- r300->scissor_state.dirty = TRUE;
+ if (r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
+ }
}
static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -1024,7 +1031,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
- unsigned i, max_index = ~0;
+ unsigned i, max_index = (1 << 24) - 1;
memcpy(r300->vertex_buffer, buffers,
sizeof(struct pipe_vertex_buffer) * count);
@@ -1039,19 +1046,17 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
if (r300->draw) {
draw_flush(r300->draw);
draw_set_vertex_buffers(r300->draw, count, buffers);
- } else {
- r300->vertex_stream_state.dirty = TRUE;
}
}
static boolean r300_validate_aos(struct r300_context *r300)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
int i;
/* Check if formats and strides are aligned to the size of DWORD. */
- for (i = 0; i < r300->vertex_element_count; i++) {
+ for (i = 0; i < r300->velems->count; i++) {
if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
return FALSE;
@@ -1060,20 +1065,209 @@ static boolean r300_validate_aos(struct r300_context *r300)
return TRUE;
}
-static void r300_set_vertex_elements(struct pipe_context* pipe,
- unsigned count,
- const struct pipe_vertex_element* elements)
+static void r300_draw_emit_attrib(struct r300_context* r300,
+ enum attrib_emit emit,
+ enum interp_mode interp,
+ int index)
{
- struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct tgsi_shader_info* info = &vs->info;
+ int output;
+
+ output = draw_find_shader_output(r300->draw,
+ info->output_semantic_name[index],
+ info->output_semantic_index[index]);
+ draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
+}
+
+static void r300_draw_emit_all_attribs(struct r300_context* r300)
+{
+ struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct r300_shader_semantics* vs_outputs = &vs->outputs;
+ int i, gen_count;
+
+ /* Position. */
+ if (vs_outputs->pos != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->pos);
+ } else {
+ assert(0);
+ }
+
+ /* Point size. */
+ if (vs_outputs->psize != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
+ vs_outputs->psize);
+ }
+
+ /* Colors. */
+ for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ if (vs_outputs->color[i] != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
+ vs_outputs->color[i]);
+ }
+ }
+
+ /* XXX Back-face colors. */
- memcpy(r300->vertex_element,
- elements,
- sizeof(struct pipe_vertex_element) * count);
- r300->vertex_element_count = count;
+ /* Texture coordinates. */
+ gen_count = 0;
+ for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
+ if (vs_outputs->generic[i] != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->generic[i]);
+ gen_count++;
+ }
+ }
+
+ /* Fog coordinates. */
+ if (vs_outputs->fog != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->fog);
+ gen_count++;
+ }
+
+ /* XXX magic */
+ assert(gen_count <= 8);
+}
+
+/* Update the PSC tables. */
+static void r300_vertex_psc(struct r300_vertex_element_state *velems)
+{
+ struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
+ uint16_t type, swizzle;
+ enum pipe_format format;
+ unsigned i;
+
+ assert(velems->count <= 16);
+
+ /* Vertex shaders have no semantics on their inputs,
+ * so PSC should just route stuff based on the vertex elements,
+ * and not on attrib information. */
+ for (i = 0; i < velems->count; i++) {
+ format = velems->velem[i].src_format;
+
+ type = r300_translate_vertex_data_type(format) |
+ (i << R300_DST_VEC_LOC_SHIFT);
+ swizzle = r300_translate_vertex_data_swizzle(format);
+
+ if (i & 1) {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
+ } else {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
+ }
+ }
+
+ /* Set the last vector in the PSC. */
+ if (i) {
+ i -= 1;
+ }
+ vstream->vap_prog_stream_cntl[i >> 1] |=
+ (R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+ vstream->count = (i >> 1) + 1;
+}
+
+/* Update the PSC tables for SW TCL, using Draw. */
+static void r300_swtcl_vertex_psc(struct r300_context *r300,
+ struct r300_vertex_element_state *velems)
+{
+ struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
+ struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct vertex_info* vinfo = &r300->vertex_info;
+ uint16_t type, swizzle;
+ enum pipe_format format;
+ unsigned i, attrib_count;
+ int* vs_output_tab = vs->stream_loc_notcl;
+
+ /* For each Draw attribute, route it to the fragment shader according
+ * to the vs_output_tab. */
+ attrib_count = vinfo->num_attribs;
+ DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
+ for (i = 0; i < attrib_count; i++) {
+ DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
+ " vs_output_tab %d\n", vinfo->attrib[i].src_index,
+ vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
+ vs_output_tab[i]);
+ }
+
+ for (i = 0; i < attrib_count; i++) {
+ /* Make sure we have a proper destination for our attribute. */
+ assert(vs_output_tab[i] != -1);
+
+ format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+
+ /* Obtain the type of data in this attribute. */
+ type = r300_translate_vertex_data_type(format) |
+ vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
+
+ /* Obtain the swizzle for this attribute. Note that the default
+ * swizzle in the hardware is not XYZW! */
+ swizzle = r300_translate_vertex_data_swizzle(format);
+
+ /* Add the attribute to the PSC table. */
+ if (i & 1) {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
+ } else {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
+ }
+ }
+
+ /* Set the last vector in the PSC. */
+ if (i) {
+ i -= 1;
+ }
+ vstream->vap_prog_stream_cntl[i >> 1] |=
+ (R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+ vstream->count = (i >> 1) + 1;
+}
+
+static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
+ unsigned count,
+ const struct pipe_vertex_element* attribs)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_screen* r300screen = r300_screen(pipe->screen);
+ struct r300_vertex_element_state *velems;
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = CALLOC_STRUCT(r300_vertex_element_state);
+ if (velems != NULL) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
+
+ if (r300screen->caps->has_tcl) {
+ r300_vertex_psc(velems);
+ } else {
+ memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+ r300_draw_emit_all_attribs(r300);
+ draw_compute_vertex_size(&r300->vertex_info);
+ r300_swtcl_vertex_psc(r300, velems);
+ }
+ }
+ return velems;
+}
+
+static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *state)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_vertex_element_state *velems = state;
+
+ if (velems == NULL) {
+ return;
+ }
+
+ r300->velems = velems;
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_vertex_elements(r300->draw, count, elements);
+ draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
}
if (!r300_validate_aos(r300)) {
@@ -1081,6 +1275,14 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,
assert(0);
abort();
}
+
+ UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
+ r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
+}
+
+static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
}
static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -1088,68 +1290,71 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
- /* Copy state directly into shader. */
- vs->state = *shader;
- vs->state.tokens = tgsi_dup_tokens(shader->tokens);
-
- tgsi_scan_shader(shader->tokens, &vs->info);
+ struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
+ r300_vertex_shader_common_init(vs, shader);
- return (void*)vs;
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300_translate_vertex_shader(r300, vs);
} else {
- return draw_create_vertex_shader(r300->draw, shader);
+ vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
}
+
+ return vs;
}
static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
+ if (vs == NULL) {
+ r300->vs_state.state = NULL;
+ return;
+ }
+ if (vs == r300->vs_state.state) {
+ return;
+ }
+ r300->vs_state.state = vs;
- if (vs == NULL) {
- r300->vs_state.state = NULL;
- return;
- } else if (!vs->translated) {
- r300_translate_vertex_shader(r300, vs);
- }
+ // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block
+ if (r300->fs) {
+ r300_vertex_shader_setup_wpos(r300);
+ }
+ memcpy(r300->vap_output_state.state, &vs->vap_out,
+ sizeof(struct r300_vap_output_state));
+ r300->vap_output_state.dirty = TRUE;
- UPDATE_STATE(shader, r300->vs_state);
+ /* The majority of the RS block bits is dependent on the vertex shader. */
+ r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->vs_state.dirty = TRUE;
r300->vs_state.size = vs->code.length + 9;
- r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
- r300->vap_output_state.dirty = TRUE;
- r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */
r300->pvs_flush.dirty = TRUE;
- if (r300->fs) {
- r300_vertex_shader_setup_wpos(r300);
- }
-
r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
- (struct draw_vertex_shader*)shader);
+ (struct draw_vertex_shader*)vs->draw_vs);
}
}
static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
-
rc_constants_destroy(&vs->code.constants);
- FREE((void*)vs->state.tokens);
- FREE(shader);
} else {
draw_delete_vertex_shader(r300->draw,
- (struct draw_vertex_shader*)shader);
+ (struct draw_vertex_shader*)vs->draw_vs);
}
+
+ FREE((void*)vs->state.tokens);
+ FREE(shader);
}
static void r300_set_constant_buffer(struct pipe_context *pipe,
@@ -1201,8 +1406,10 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
pipe_buffer_unmap(pipe->screen, buf);
if (shader == PIPE_SHADER_VERTEX) {
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
- r300->pvs_flush.dirty = TRUE;
+ if (r300screen->caps->has_tcl) {
+ r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ r300->pvs_flush.dirty = TRUE;
+ }
}
else if (shader == PIPE_SHADER_FRAGMENT)
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
@@ -1250,7 +1457,10 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.set_viewport_state = r300_set_viewport_state;
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
- r300->context.set_vertex_elements = r300_set_vertex_elements;
+
+ r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
+ r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
+ r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state;
r300->context.create_vs_state = r300_create_vs_state;
r300->context.bind_vs_state = r300_bind_vs_state;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 9c8e907fdf..6b9f61acd7 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -37,187 +37,6 @@
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
-static void r300_draw_emit_attrib(struct r300_context* r300,
- enum attrib_emit emit,
- enum interp_mode interp,
- int index)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct tgsi_shader_info* info = &vs->info;
- int output;
-
- output = draw_find_shader_output(r300->draw,
- info->output_semantic_name[index],
- info->output_semantic_index[index]);
- draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output);
-}
-
-static void r300_draw_emit_all_attribs(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_shader_semantics* vs_outputs = &vs->outputs;
- int i, gen_count;
-
- /* Position. */
- if (vs_outputs->pos != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
- vs_outputs->pos);
- } else {
- assert(0);
- }
-
- /* Point size. */
- if (vs_outputs->psize != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS,
- vs_outputs->psize);
- }
-
- /* Colors. */
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
- vs_outputs->color[i]);
- }
- }
-
- /* XXX Back-face colors. */
-
- /* Texture coordinates. */
- gen_count = 0;
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- if (vs_outputs->generic[i] != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
- vs_outputs->generic[i]);
- gen_count++;
- }
- }
-
- /* Fog coordinates. */
- if (vs_outputs->fog != ATTR_UNUSED) {
- r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
- vs_outputs->fog);
- gen_count++;
- }
-
- /* XXX magic */
- assert(gen_count <= 8);
-}
-
-/* Update the PSC tables. */
-/* XXX move this function into r300_state.c after TCL-bypass gets removed
- * XXX because this one is dependent only on vertex elements. */
-static void r300_vertex_psc(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_stream_state *vformat =
- (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
- uint16_t type, swizzle;
- enum pipe_format format;
- unsigned i;
- int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
- int* stream_tab;
-
- memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
-
- stream_tab = identity;
-
- /* Vertex shaders have no semantics on their inputs,
- * so PSC should just route stuff based on the vertex elements,
- * and not on attrib information. */
- DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
- " in psc\n",
- vs->info.num_inputs,
- r300->vertex_element_count);
-
- for (i = 0; i < r300->vertex_element_count; i++) {
- format = r300->vertex_element[i].src_format;
-
- type = r300_translate_vertex_data_type(format) |
- (stream_tab[i] << R300_DST_VEC_LOC_SHIFT);
- swizzle = r300_translate_vertex_data_swizzle(format);
-
- if (i & 1) {
- vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
- } else {
- vformat->vap_prog_stream_cntl[i >> 1] |= type;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
- }
- }
-
- assert(i <= 15);
-
- /* Set the last vector in the PSC. */
- if (i) {
- i -= 1;
- }
- vformat->vap_prog_stream_cntl[i >> 1] |=
- (R300_LAST_VEC << (i & 1 ? 16 : 0));
-
- vformat->count = (i >> 1) + 1;
- r300->vertex_stream_state.size = (1 + vformat->count) * 2;
-}
-
-/* Update the PSC tables for SW TCL, using Draw. */
-static void r300_swtcl_vertex_psc(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_stream_state *vformat =
- (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
- struct vertex_info* vinfo = &r300->vertex_info;
- uint16_t type, swizzle;
- enum pipe_format format;
- unsigned i, attrib_count;
- int* vs_output_tab = vs->stream_loc_notcl;
-
- memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
-
- /* For each Draw attribute, route it to the fragment shader according
- * to the vs_output_tab. */
- attrib_count = vinfo->num_attribs;
- DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
- for (i = 0; i < attrib_count; i++) {
- DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
- " vs_output_tab %d\n", vinfo->attrib[i].src_index,
- vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
- vs_output_tab[i]);
- }
-
- for (i = 0; i < attrib_count; i++) {
- /* Make sure we have a proper destination for our attribute. */
- assert(vs_output_tab[i] != -1);
-
- format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
-
- /* Obtain the type of data in this attribute. */
- type = r300_translate_vertex_data_type(format) |
- vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
-
- /* Obtain the swizzle for this attribute. Note that the default
- * swizzle in the hardware is not XYZW! */
- swizzle = r300_translate_vertex_data_swizzle(format);
-
- /* Add the attribute to the PSC table. */
- if (i & 1) {
- vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
- } else {
- vformat->vap_prog_stream_cntl[i >> 1] |= type;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
- }
- }
-
- /* Set the last vector in the PSC. */
- if (i) {
- i -= 1;
- }
- vformat->vap_prog_stream_cntl[i >> 1] |=
- (R300_LAST_VEC << (i & 1 ? 16 : 0));
-
- vformat->count = (i >> 1) + 1;
- r300->vertex_stream_state.size = (1 + vformat->count) * 2;
-}
-
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
boolean swizzle_0001)
{
@@ -432,23 +251,8 @@ static void r300_update_rs_block(struct r300_context* r300,
static void r300_update_derived_shader_state(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_vap_output_state *vap_out =
- (struct r300_vap_output_state*)r300->vap_output_state.state;
-
- /* XXX Mmm, delicious hax */
- memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
- memcpy(vap_out, vs->hwfmt, sizeof(uint)*4);
r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
-
- if (r300screen->caps->has_tcl) {
- r300_vertex_psc(r300);
- } else {
- r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(&r300->vertex_info);
- r300_swtcl_vertex_psc(r300);
- }
}
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
@@ -581,9 +385,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
void r300_update_derived_state(struct r300_context* r300)
{
- if (r300->rs_block_state.dirty ||
- r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */
- r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */
+ if (r300->rs_block_state.dirty) {
r300_update_derived_shader_state(r300);
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 2f3a56e1fb..a32924ed0a 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -348,39 +348,12 @@ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
return 0;
}
-/* Utility function to count the number of components in RGBAZS formats.
- * XXX should go to util or p_format.h */
-static INLINE unsigned pf_component_count(enum pipe_format format) {
- unsigned count = 0;
-
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
- count++;
- }
-
- return count;
-}
-
/* Translate pipe_formats into PSC vertex types. */
static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) {
uint32_t result = 0;
const struct util_format_description *desc;
- unsigned components = pf_component_count(format);
+ unsigned components = util_format_get_nr_components(format);
desc = util_format_description(format);
@@ -453,7 +426,6 @@ r300_translate_vertex_data_type(enum pipe_format format) {
static INLINE uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format) {
const struct util_format_description *desc = util_format_description(format);
- unsigned swizzle[4], i;
assert(format);
@@ -463,25 +435,10 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
return 0;
}
- /* Swizzles for 8bits formats are in the reversed order, not sure why. */
- if (desc->channel[0].size == 8) {
- for (i = 0; i < 4; i++) {
- if (desc->swizzle[i] <= 3) {
- swizzle[i] = 3 - desc->swizzle[i];
- } else {
- swizzle[i] = desc->swizzle[i];
- }
- }
- } else {
- for (i = 0; i < 4; i++) {
- swizzle[i] = desc->swizzle[i];
- }
- }
-
- return ((swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
- (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
- (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
- (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
+ return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
+ (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
+ (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
+ (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
(0xf << R300_WRITE_ENA_SHIFT));
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index c0144f64b4..04124afd4d 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -617,18 +617,23 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_texture *tex,
unsigned level,
- boolean rv350_mode)
+ boolean rv350_mode,
+ int dim)
{
- unsigned tile_width, width;
+ unsigned tile, texdim;
- tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
- width = u_minify(tex->tex.width0, level);
+ tile = r300_texture_get_tile_size(tex, dim, TRUE);
+ if (dim == TILE_WIDTH) {
+ texdim = u_minify(tex->tex.width0, level);
+ } else {
+ texdim = u_minify(tex->tex.height0, level);
+ }
/* See TX_FILTER1_n.MACRO_SWITCH. */
if (rv350_mode) {
- return width >= tile_width;
+ return texdim >= tile;
} else {
- return width > tile_width;
+ return texdim > tile;
}
}
@@ -692,9 +697,10 @@ static void r300_setup_miptree(struct r300_screen* screen,
for (i = 0; i <= base->last_level; i++) {
/* Let's see if this miplevel can be macrotiled. */
- tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED &&
- r300_texture_macro_switch(tex, i, rv350_mode)) ?
- R300_BUFFER_TILED : R300_BUFFER_LINEAR;
+ tex->mip_macrotile[i] =
+ (tex->macrotile == R300_BUFFER_TILED &&
+ r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH)) ?
+ R300_BUFFER_TILED : R300_BUFFER_LINEAR;
stride = r300_texture_get_stride(screen, tex, i);
nblocksy = r300_texture_get_nblocksy(tex, i);
@@ -724,10 +730,46 @@ static void r300_setup_flags(struct r300_texture* tex)
!util_is_power_of_two(tex->tex.height0);
}
+static void r300_setup_tiling(struct pipe_screen *screen,
+ struct r300_texture *tex)
+{
+ enum pipe_format format = tex->tex.format;
+ boolean rv350_mode = r300_screen(screen)->caps->family >= CHIP_FAMILY_RV350;
+
+ if (util_format_is_compressed(format)) {
+ return;
+ }
+
+ if (tex->tex.width0 == 1 ||
+ tex->tex.height0 == 1) {
+ return;
+ }
+
+ /* Set microtiling. */
+ switch (util_format_get_blocksize(format)) {
+ case 1:
+ case 4:
+ tex->microtile = R300_BUFFER_TILED;
+ break;
+
+ /* XXX Square-tiling doesn't work with kernel older than 2.6.34,
+ * XXX need to check the DRM version */
+ /*case 2:
+ case 8:
+ tex->microtile = R300_BUFFER_SQUARETILED;
+ break;*/
+ }
+
+ /* Set macrotiling. */
+ if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) &&
+ r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) {
+ tex->macrotile = R300_BUFFER_TILED;
+ }
+}
+
/* Create a new texture. */
-static struct pipe_texture*
- r300_texture_create(struct pipe_screen* screen,
- const struct pipe_texture* template)
+static struct pipe_texture* r300_texture_create(struct pipe_screen* screen,
+ const struct pipe_texture* template)
{
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
struct r300_screen* rscreen = r300_screen(screen);
@@ -742,6 +784,9 @@ static struct pipe_texture*
tex->tex.screen = screen;
r300_setup_flags(tex);
+ if (!(template->tex_usage & R300_TEXTURE_USAGE_TRANSFER)) {
+ r300_setup_tiling(screen, tex);
+ }
r300_setup_miptree(rscreen, tex);
r300_setup_texture_state(rscreen, tex);
@@ -806,14 +851,17 @@ static void r300_tex_surface_destroy(struct pipe_surface* s)
FREE(s);
}
+
static struct pipe_texture*
- r300_texture_blanket(struct pipe_screen* screen,
- const struct pipe_texture* base,
- const unsigned* stride,
- struct pipe_buffer* buffer)
+ r300_texture_from_handle(struct pipe_screen* screen,
+ const struct pipe_texture* base,
+ struct winsys_handle *whandle)
{
- struct r300_texture* tex;
+ struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
struct r300_screen* rscreen = r300_screen(screen);
+ struct pipe_buffer *buffer;
+ struct r300_texture* tex;
+ unsigned stride;
/* Support only 2D textures without mipmaps */
if (base->target != PIPE_TEXTURE_2D ||
@@ -822,6 +870,11 @@ static struct pipe_texture*
return NULL;
}
+ buffer = winsys->buffer_from_handle(winsys, screen, whandle, &stride);
+ if (!buffer) {
+ return NULL;
+ }
+
tex = CALLOC_STRUCT(r300_texture);
if (!tex) {
return NULL;
@@ -831,17 +884,38 @@ static struct pipe_texture*
pipe_reference_init(&tex->tex.reference, 1);
tex->tex.screen = screen;
- tex->stride_override = *stride;
- tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
+ tex->stride_override = stride;
+ tex->pitch[0] = stride / util_format_get_blocksize(base->format);
r300_setup_flags(tex);
r300_setup_texture_state(rscreen, tex);
- pipe_buffer_reference(&tex->buffer, buffer);
+ /* one ref already taken */
+ tex->buffer = buffer;
return (struct pipe_texture*)tex;
}
+static boolean
+ r300_texture_get_handle(struct pipe_screen* screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
+ struct r300_texture* tex = (struct r300_texture*)texture;
+ unsigned stride;
+
+ if (!tex) {
+ return FALSE;
+ }
+
+ stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
+
+ winsys->buffer_get_handle(winsys, tex->buffer, stride, whandle);
+
+ return TRUE;
+}
+
static struct pipe_video_surface *
r300_video_surface_create(struct pipe_screen *screen,
enum pipe_video_chroma_format chroma_format,
@@ -893,30 +967,13 @@ static void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
void r300_init_screen_texture_functions(struct pipe_screen* screen)
{
screen->texture_create = r300_texture_create;
+ screen->texture_from_handle = r300_texture_from_handle;
+ screen->texture_get_handle = r300_texture_get_handle;
screen->texture_destroy = r300_texture_destroy;
screen->get_tex_surface = r300_get_tex_surface;
screen->tex_surface_destroy = r300_tex_surface_destroy;
- screen->texture_blanket = r300_texture_blanket;
screen->video_surface_create = r300_video_surface_create;
screen->video_surface_destroy= r300_video_surface_destroy;
}
-boolean r300_get_texture_buffer(struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride)
-{
- struct r300_texture* tex = (struct r300_texture*)texture;
- if (!tex) {
- return FALSE;
- }
-
- pipe_buffer_reference(buffer, tex->buffer);
-
- if (stride) {
- *stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
- }
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 46a5fb6188..138b62784e 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -60,13 +60,11 @@ r300_video_surface(struct pipe_video_surface *pvs)
return (struct r300_video_surface *)pvs;
}
-#ifndef R300_WINSYS_H
-
+/* Used internally for texture_is_referenced()
+ */
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
-#endif /* R300_WINSYS_H */
-
#endif /* R300_TEXTURE_H */
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
new file mode 100644
index 0000000000..495e3dee76
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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
+ * THE AUTHOR(S) 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 "r300_context.h"
+#include "r300_transfer.h"
+#include "r300_texture.h"
+#include "r300_screen.h"
+
+#include "util/u_memory.h"
+#include "util/u_format.h"
+
+struct r300_transfer {
+ /* Parent class */
+ struct pipe_transfer transfer;
+
+ /* Pipe context. */
+ struct pipe_context *ctx;
+
+ /* Parameters of get_tex_transfer. */
+ unsigned x, y, level, zslice, face;
+
+ /* Offset from start of buffer. */
+ unsigned offset;
+
+ /* Detiled texture. */
+ struct r300_texture *detiled_texture;
+
+ /* Transfer and format flags. */
+ unsigned buffer_usage, render_target_usage;
+};
+
+/* Convenience cast wrapper. */
+static INLINE struct r300_transfer*
+r300_transfer(struct pipe_transfer* transfer)
+{
+ return (struct r300_transfer*)transfer;
+}
+
+/* Copy from a tiled texture to a detiled one. */
+static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
+ struct r300_transfer *r300transfer)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
+ struct pipe_texture *tex = transfer->texture;
+ struct pipe_surface *src, *dst;
+
+ src = screen->get_tex_surface(screen, tex, r300transfer->face,
+ r300transfer->level, r300transfer->zslice,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_PIXEL |
+ r300transfer->buffer_usage);
+
+ ctx->surface_copy(ctx, dst, 0, 0, src, r300transfer->x, r300transfer->y,
+ transfer->width, transfer->height);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+/* Copy a detiled texture to a tiled one. */
+static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
+ struct r300_transfer *r300transfer)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
+ struct pipe_texture *tex = transfer->texture;
+ struct pipe_surface *src, *dst;
+
+ src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ dst = screen->get_tex_surface(screen, tex, r300transfer->face,
+ r300transfer->level, r300transfer->zslice,
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ /* XXX this flush prevents the following DRM error from occuring:
+ * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation !
+ * Reproducible with perf/copytex. */
+ ctx->flush(ctx, 0, NULL);
+
+ ctx->surface_copy(ctx, dst, r300transfer->x, r300transfer->y, src, 0, 0,
+ transfer->width, transfer->height);
+
+ /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */
+ ctx->flush(ctx, 0, NULL);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+static struct pipe_transfer*
+r300_get_tex_transfer(struct pipe_context *ctx,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage, unsigned x, unsigned y,
+ unsigned w, unsigned h)
+{
+ struct r300_texture *tex = (struct r300_texture *)texture;
+ struct r300_screen *r300screen = r300_screen(ctx->screen);
+ struct r300_transfer *trans;
+ struct pipe_texture template;
+
+ trans = CALLOC_STRUCT(r300_transfer);
+ if (trans) {
+ /* Initialize the transfer object. */
+ pipe_texture_reference(&trans->transfer.texture, texture);
+ trans->transfer.usage = usage;
+ trans->transfer.width = w;
+ trans->transfer.height = h;
+ trans->ctx = ctx;
+ trans->x = x;
+ trans->y = y;
+ trans->level = level;
+ trans->zslice = zslice;
+ trans->face = face;
+
+ /* If the texture is tiled, we must create a temporary detiled texture
+ * for this transfer. */
+ if (tex->microtile || tex->macrotile) {
+ trans->buffer_usage = pipe_transfer_buffer_flags(&trans->transfer);
+ trans->render_target_usage =
+ util_format_is_depth_or_stencil(texture->format) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ template.target = PIPE_TEXTURE_2D;
+ template.format = texture->format;
+ template.width0 = w;
+ template.height0 = h;
+ template.depth0 = 0;
+ template.last_level = 0;
+ template.nr_samples = 0;
+ template.tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
+ R300_TEXTURE_USAGE_TRANSFER;
+
+ /* For texture reading, the temporary (detiled) texture is used as
+ * a render target when blitting from a tiled texture. */
+ if (usage & PIPE_TRANSFER_READ) {
+ template.tex_usage |= trans->render_target_usage;
+ }
+ /* For texture writing, the temporary texture is used as a sampler
+ * when blitting into a tiled texture. */
+ if (usage & PIPE_TRANSFER_WRITE) {
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SAMPLER;
+ }
+
+ /* Create the temporary texture. */
+ trans->detiled_texture = (struct r300_texture*)
+ ctx->screen->texture_create(ctx->screen,
+ &template);
+
+ assert(!trans->detiled_texture->microtile &&
+ !trans->detiled_texture->macrotile);
+
+ /* Set the stride.
+ * Parameters x, y, level, zslice, and face remain zero. */
+ trans->transfer.stride =
+ r300_texture_get_stride(r300screen, trans->detiled_texture, 0);
+
+ if (usage & PIPE_TRANSFER_READ) {
+ /* We cannot map a tiled texture directly because the data is
+ * in a different order, therefore we do detiling using a blit. */
+ r300_copy_from_tiled_texture(ctx, trans);
+ }
+ } else {
+ trans->transfer.x = x;
+ trans->transfer.y = y;
+ trans->transfer.stride =
+ r300_texture_get_stride(r300screen, tex, level);
+ trans->transfer.level = level;
+ trans->transfer.zslice = zslice;
+ trans->transfer.face = face;
+ trans->offset = r300_texture_get_offset(tex, level, zslice, face);
+ }
+ }
+ return &trans->transfer;
+}
+
+static void r300_tex_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans)
+{
+ struct r300_transfer *r300transfer = r300_transfer(trans);
+
+ if (r300transfer->detiled_texture) {
+ if (trans->usage & PIPE_TRANSFER_WRITE) {
+ r300_copy_into_tiled_texture(r300transfer->ctx, r300transfer);
+ }
+
+ pipe_texture_reference(
+ (struct pipe_texture**)&r300transfer->detiled_texture, NULL);
+ }
+ pipe_texture_reference(&trans->texture, NULL);
+ FREE(trans);
+}
+
+static void* r300_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer *transfer)
+{
+ struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_texture *tex = (struct r300_texture*)transfer->texture;
+ char *map;
+ enum pipe_format format = tex->tex.format;
+
+ if (r300transfer->detiled_texture) {
+ /* The detiled texture is of the same size as the region being mapped
+ * (no offset needed). */
+ return pipe_buffer_map(ctx->screen,
+ r300transfer->detiled_texture->buffer,
+ pipe_transfer_buffer_flags(transfer));
+ } else {
+ /* Tiling is disabled. */
+ map = pipe_buffer_map(ctx->screen, tex->buffer,
+ pipe_transfer_buffer_flags(transfer));
+
+ if (!map) {
+ return NULL;
+ }
+
+ return map + r300_transfer(transfer)->offset +
+ transfer->y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ }
+}
+
+static void r300_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer *transfer)
+{
+ struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_texture *tex = (struct r300_texture*)transfer->texture;
+
+ if (r300transfer->detiled_texture) {
+ pipe_buffer_unmap(ctx->screen, r300transfer->detiled_texture->buffer);
+ } else {
+ pipe_buffer_unmap(ctx->screen, tex->buffer);
+ }
+}
+
+
+void r300_init_transfer_functions( struct r300_context *r300ctx )
+{
+ struct pipe_context *ctx = &r300ctx->context;
+
+ ctx->get_tex_transfer = r300_get_tex_transfer;
+ ctx->tex_transfer_destroy = r300_tex_transfer_destroy;
+ ctx->transfer_map = r300_transfer_map;
+ ctx->transfer_unmap = r300_transfer_unmap;
+}
diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h
new file mode 100644
index 0000000000..79baf6d048
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_transfer.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * 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
+ * THE AUTHOR(S) 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 R300_TRANSFER
+#define R300_TRANSFER
+
+#include "pipe/p_screen.h"
+
+struct r300_context;
+
+void r300_init_transfer_functions(struct r300_context *r300ctx);
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 60a04bbfed..379939ac75 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -89,95 +89,41 @@ static void r300_shader_read_vs_outputs(
assert(0);
}
}
+
+ /* WPOS is a straight copy of POSITION and it's always emitted. */
+ vs_outputs->wpos = i;
}
-static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
+/* This function sets up:
+ * - VAP mapping, which maps VS registers to output semantics and
+ * at the same time it indicates which attributes are enabled and should
+ * be rasterized.
+ * - Stream mapping to VS outputs if TCL is not present. */
+static void r300_init_vs_output_mapping(struct r300_vertex_shader* vs)
{
struct r300_shader_semantics* vs_outputs = &vs->outputs;
- uint32_t* hwfmt = vs->hwfmt;
- int i, gen_count;
+ struct r300_vap_output_state *vap_out = &vs->vap_out;
+ int *stream_loc = vs->stream_loc_notcl;
+ int i, gen_count, tabi = 0;
boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
vs_outputs->bcolor[1] != ATTR_UNUSED;
- /* Do the actual vertex_info setup.
- *
- * vertex_info has four uints of hardware-specific data in it.
- * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
- * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
- * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
- * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
-
- hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+ vap_out->vap_vtx_state_cntl = 0x5555; /* XXX this is classic Mesa bonghits */
/* Position. */
if (vs_outputs->pos != ATTR_UNUSED) {
- hwfmt[1] |= R300_INPUT_CNTL_POS;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+
+ stream_loc[tabi++] = 0;
} else {
assert(0);
}
/* Point size. */
if (vs_outputs->psize != ATTR_UNUSED) {
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
- }
-
- /* Colors. */
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
- vs_outputs->color[1] != ATTR_UNUSED) {
- hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
- }
- }
-
- /* Back-face colors. */
- if (any_bcolor_used) {
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
- }
- }
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
- /* Texture coordinates. */
- gen_count = 0;
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- if (vs_outputs->generic[i] != ATTR_UNUSED) {
- hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
- hwfmt[3] |= (4 << (3 * gen_count));
- gen_count++;
- }
- }
-
- /* Fog coordinates. */
- if (vs_outputs->fog != ATTR_UNUSED) {
- hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
- hwfmt[3] |= (4 << (3 * gen_count));
- gen_count++;
- }
-
- /* XXX magic */
- assert(gen_count <= 8);
-
- /* WPOS. */
- vs->wpos_tex_output = gen_count;
-}
-
-/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed
- * or isn't present. */
-static void r300_stream_locations_notcl(
- struct r300_shader_semantics* vs_outputs,
- int* stream_loc)
-{
- int i, tabi = 0, gen_count;
- boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
- vs_outputs->bcolor[1] != ATTR_UNUSED;
-
- /* Position. */
- stream_loc[tabi++] = 0;
-
- /* Point size. */
- if (vs_outputs->psize != ATTR_UNUSED) {
stream_loc[tabi++] = 1;
}
@@ -185,6 +131,9 @@ static void r300_stream_locations_notcl(
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
vs_outputs->color[1] != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
+
stream_loc[tabi++] = 2 + i;
}
}
@@ -192,6 +141,9 @@ static void r300_stream_locations_notcl(
/* Back-face colors. */
if (any_bcolor_used) {
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+
stream_loc[tabi++] = 4 + i;
}
}
@@ -200,6 +152,9 @@ static void r300_stream_locations_notcl(
gen_count = 0;
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
if (vs_outputs->generic[i] != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
+
assert(tabi < 16);
stream_loc[tabi++] = 6 + gen_count;
gen_count++;
@@ -208,17 +163,22 @@ static void r300_stream_locations_notcl(
/* Fog coordinates. */
if (vs_outputs->fog != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
+
assert(tabi < 16);
stream_loc[tabi++] = 6 + gen_count;
gen_count++;
}
+ /* XXX magic */
+ assert(gen_count <= 8);
+
/* WPOS. */
- if (vs_outputs->wpos != ATTR_UNUSED) {
- assert(tabi < 16);
- stream_loc[tabi++] = 6 + gen_count;
- gen_count++;
- }
+ vs->wpos_tex_output = gen_count;
+
+ assert(tabi < 16);
+ stream_loc[tabi++] = 6 + gen_count;
for (; tabi < 16;) {
stream_loc[tabi++] = -1;
@@ -294,26 +254,16 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
}
}
-static void r300_insert_wpos(struct r300_vertex_program_compiler* c,
- struct r300_shader_semantics* outputs)
+void r300_vertex_shader_common_init(struct r300_vertex_shader *vs,
+ const struct pipe_shader_state *shader)
{
- int i, lastOutput = 0;
-
- /* Find the max output index. */
- lastOutput = MAX2(lastOutput, outputs->psize);
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- lastOutput = MAX2(lastOutput, outputs->color[i]);
- lastOutput = MAX2(lastOutput, outputs->bcolor[i]);
- }
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- lastOutput = MAX2(lastOutput, outputs->generic[i]);
- }
- lastOutput = MAX2(lastOutput, outputs->fog);
+ /* Copy state directly into shader. */
+ vs->state = *shader;
+ vs->state.tokens = tgsi_dup_tokens(shader->tokens);
+ tgsi_scan_shader(shader->tokens, &vs->info);
- /* Set WPOS after the last output. */
- lastOutput++;
- rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */
- outputs->wpos = lastOutput;
+ r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
+ r300_init_vs_output_mapping(vs);
}
void r300_translate_vertex_shader(struct r300_context* r300,
@@ -322,9 +272,6 @@ void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_program_compiler compiler;
struct tgsi_to_rc ttr;
- /* Initialize. */
- r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
-
/* Setup the compiler */
rc_init(&compiler.Base);
@@ -348,10 +295,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
/* Insert the WPOS output. */
- r300_insert_wpos(&compiler, &vs->outputs);
-
- r300_shader_vap_output_fmt(vs);
- r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
+ rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
/* Invoke the compiler */
r3xx_compile_vertex_program(&compiler);
@@ -363,30 +307,29 @@ void r300_translate_vertex_shader(struct r300_context* r300,
/* And, finally... */
rc_destroy(&compiler.Base);
- vs->translated = TRUE;
}
boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct r300_vap_output_state *vap_out = &vs->vap_out;
int tex_output = vs->wpos_tex_output;
uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
- uint32_t* hwfmt = vs->hwfmt;
if (r300->fs->inputs.wpos != ATTR_UNUSED) {
/* Enable WPOS in VAP. */
- if (!(hwfmt[1] & tex_fmt)) {
- hwfmt[1] |= tex_fmt;
- hwfmt[3] |= (4 << (3 * tex_output));
+ if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) {
+ vap_out->vap_vsm_vtx_assm |= tex_fmt;
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * tex_output));
assert(tex_output < 8);
return TRUE;
}
} else {
/* Disable WPOS in VAP. */
- if (hwfmt[1] & tex_fmt) {
- hwfmt[1] &= ~tex_fmt;
- hwfmt[3] &= ~(4 << (3 * tex_output));
+ if (vap_out->vap_vsm_vtx_assm & tex_fmt) {
+ vap_out->vap_vsm_vtx_assm &= ~tex_fmt;
+ vap_out->vap_out_vtx_fmt[1] &= ~(4 << (3 * tex_output));
return TRUE;
}
}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 18cfeee3cd..f6f0b86b68 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -28,6 +28,7 @@
#include "tgsi/tgsi_scan.h"
#include "radeon_code.h"
+#include "r300_context.h"
#include "r300_shader_semantics.h"
struct r300_context;
@@ -38,7 +39,7 @@ struct r300_vertex_shader {
struct tgsi_shader_info info;
struct r300_shader_semantics outputs;
- uint hwfmt[4];
+ struct r300_vap_output_state vap_out;
/* Stream locations for SWTCL or if TCL is bypassed. */
int stream_loc_notcl[16];
@@ -46,13 +47,17 @@ struct r300_vertex_shader {
/* Output stream location for WPOS. */
int wpos_tex_output;
- /* Has this shader been translated yet? */
- boolean translated;
-
+ /* HWTCL-specific. */
/* Machine code (if translated) */
struct r300_vertex_program_code code;
+
+ /* SWTCL-specific. */
+ void *draw_vs;
};
+void r300_vertex_shader_common_init(struct r300_vertex_shader *vs,
+ const struct pipe_shader_state *shader);
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 40fb8a95ca..ddf2b79003 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -40,11 +40,6 @@ struct radeon_winsys;
struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
-boolean r300_get_texture_buffer(struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index e4ac49fa85..239655d628 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -6,7 +6,9 @@ LIBNAME = softpipe
C_SOURCES = \
sp_fs_exec.c \
sp_fs_sse.c \
+ sp_buffer.c \
sp_clear.c \
+ sp_fence.c \
sp_flush.c \
sp_query.c \
sp_context.c \
@@ -32,7 +34,6 @@ C_SOURCES = \
sp_tex_tile_cache.c \
sp_tile_cache.c \
sp_surface.c \
- sp_video_context.c \
- sp_winsys.c
+ sp_video_context.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index 3042e556c6..9949a53adf 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -7,9 +7,11 @@ softpipe = env.ConvenienceLibrary(
source = [
'sp_fs_exec.c',
'sp_fs_sse.c',
+ 'sp_buffer.c',
'sp_clear.c',
'sp_context.c',
'sp_draw_arrays.c',
+ 'sp_fence.c',
'sp_flush.c',
'sp_prim_vbuf.c',
'sp_setup.c',
@@ -33,8 +35,7 @@ softpipe = env.ConvenienceLibrary(
'sp_tex_tile_cache.c',
'sp_texture.c',
'sp_tile_cache.c',
- 'sp_video_context.c',
- 'sp_winsys.c'
+ 'sp_video_context.c'
])
Export('softpipe')
diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c
new file mode 100644
index 0000000000..8f39025086
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_buffer.c
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "sp_screen.h"
+#include "sp_buffer.h"
+
+
+static void *
+softpipe_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf);
+ return softpipe_buf->data;
+}
+
+
+static void
+softpipe_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+softpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct softpipe_buffer *sbuf = softpipe_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+softpipe_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+softpipe_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct softpipe_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(softpipe_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = softpipe_buffer_create;
+ screen->user_buffer_create = softpipe_user_buffer_create;
+ screen->buffer_map = softpipe_buffer_map;
+ screen->buffer_unmap = softpipe_buffer_unmap;
+ screen->buffer_destroy = softpipe_buffer_destroy;
+}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_buffer.h
index 6e3920c49b..9d8e56a176 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_buffer.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2009 VMware, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,64 +10,46 @@
* 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
+ * IN NO EVENT SHALL VMWARE 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.
- *
+ *
**************************************************************************/
-/* This is the interface that softpipe requires any window system
- * hosting it to implement. This is the only include file in softpipe
- * which is public.
- */
+#ifndef SP_BUFFER_H
+#define SP_BUFFER_H
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
-#ifndef SP_WINSYS_H
-#define SP_WINSYS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
+struct softpipe_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+};
-#include "pipe/p_defines.h"
-struct pipe_screen;
-struct pipe_winsys;
-struct pipe_context;
-struct pipe_texture;
-struct pipe_buffer;
-
-
-
-/**
- * Create a softpipe screen that uses the
- * given winsys for allocating buffers.
- */
-struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
-
-/**
- * Create a softpipe screen that uses
- * regular malloc to create all its buffers.
- */
-struct pipe_screen *softpipe_create_screen_malloc(void);
+/** Cast wrapper */
+static INLINE struct softpipe_buffer *
+softpipe_buffer( struct pipe_buffer *buf )
+{
+ return (struct softpipe_buffer *)buf;
+}
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride );
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
-#ifdef __cplusplus
-}
-#endif
-#endif /* SP_WINSYS_H */
+#endif /* SP_BUFFER_H */
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index ddc35bcd62..de92a0cd2c 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -44,6 +44,7 @@
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_tex_tile_cache.h"
+#include "sp_texture.h"
#include "sp_query.h"
@@ -210,7 +211,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
- softpipe->pipe.winsys = screen->winsys;
+ softpipe->pipe.winsys = NULL;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
softpipe->pipe.priv = priv;
@@ -245,6 +246,10 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.bind_gs_state = softpipe_bind_gs_state;
softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
+ softpipe->pipe.create_vertex_elements_state = softpipe_create_vertex_elements_state;
+ softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
+ softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
+
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
@@ -257,7 +262,6 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
- softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
@@ -272,6 +276,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced;
softpipe_init_query_funcs( softpipe );
+ softpipe_init_texture_funcs( &softpipe->pipe );
softpipe->pipe.render_condition = softpipe_render_condition;
@@ -280,13 +285,13 @@ softpipe_create_context( struct pipe_screen *screen,
* Must be before quad stage setup!
*/
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
- softpipe->cbuf_cache[i] = sp_create_tile_cache( screen );
- softpipe->zsbuf_cache = sp_create_tile_cache( screen );
+ softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe );
+ softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe );
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen );
+ softpipe->tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache(screen);
+ softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
}
/* setup quad rendering stages */
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 95def72c54..9a8158e6a2 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -45,6 +45,7 @@ struct softpipe_tile_cache;
struct softpipe_tex_tile_cache;
struct sp_fragment_shader;
struct sp_vertex_shader;
+struct sp_velems_state;
struct softpipe_context {
@@ -59,6 +60,7 @@ struct softpipe_context {
struct sp_fragment_shader *fs;
struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs;
+ struct sp_velems_state *velems;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -72,13 +74,11 @@ struct softpipe_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
unsigned num_textures;
unsigned num_vertex_samplers;
unsigned num_vertex_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of SP_NEW_x flags */
@@ -93,7 +93,7 @@ struct softpipe_context {
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
/** Mapped constant buffers */
- void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
+ const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
/** Vertex format */
struct vertex_info vertex_info;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index b2acc36bf7..7b77eb239f 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -33,90 +33,19 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
#include "util/u_prim.h"
#include "sp_context.h"
#include "sp_query.h"
#include "sp_state.h"
+#include "sp_buffer.h"
#include "draw/draw_context.h"
-static void
-softpipe_map_constant_buffers(struct softpipe_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
-
- for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- uint j;
-
- for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
- if (sp->constants[i][j] && sp->constants[i][j]->size) {
- sp->mapped_constants[i][j] = ws->buffer_map(ws,
- sp->constants[i][j],
- PIPE_BUFFER_USAGE_CPU_READ);
- }
- }
- }
-
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- if (sp->constants[PIPE_SHADER_VERTEX][i]) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_VERTEX,
- i,
- sp->mapped_constants[PIPE_SHADER_VERTEX][i],
- sp->constants[PIPE_SHADER_VERTEX][i]->size);
- }
- if (sp->constants[PIPE_SHADER_GEOMETRY][i]) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_GEOMETRY,
- i,
- sp->mapped_constants[PIPE_SHADER_GEOMETRY][i],
- sp->constants[PIPE_SHADER_GEOMETRY][i]->size);
- }
- }
-}
-
-
-static void
-softpipe_unmap_constant_buffers(struct softpipe_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- /* really need to flush all prims since the vert/frag shaders const buffers
- * are going away now.
- */
- draw_flush(sp->draw);
-
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_VERTEX,
- i,
- NULL,
- 0);
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_GEOMETRY,
- i,
- NULL,
- 0);
- }
-
- for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- uint j;
-
- for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
- if (sp->constants[i][j] && sp->constants[i][j]->size) {
- ws->buffer_unmap(ws, sp->constants[i][j]);
- }
- sp->mapped_constants[i][j] = NULL;
- }
- }
-}
/**
@@ -261,25 +190,16 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
}
softpipe_map_transfers(sp);
- softpipe_map_constant_buffers(sp);
/* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf;
-
- buf = pipe_buffer_map(pipe->screen,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes;
-
- mapped_indexes = pipe_buffer_map(pipe->screen,
- indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = softpipe_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer_range(draw,
indexSize,
minIndex,
@@ -300,15 +220,18 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
/* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe_buffer_unmap(pipe->screen, indexBuffer);
}
- /* Note: leave drawing surfaces mapped */
- softpipe_unmap_constant_buffers(sp);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
+ /* Note: leave drawing surfaces mapped */
sp->dirty_render_cache = TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c
new file mode 100644
index 0000000000..66c5214113
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_fence.c
@@ -0,0 +1,70 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_screen.h"
+#include "util/u_debug.h"
+#include "sp_fence.h"
+
+
+static void
+softpipe_fence_reference(struct pipe_screen *screen,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ assert(!*ptr);
+ assert(!fence);
+}
+
+
+static int
+softpipe_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flags)
+{
+ assert(!fence);
+ return 0;
+}
+
+
+static int
+softpipe_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flags)
+{
+ assert(!fence);
+ return 0;
+}
+
+
+void
+softpipe_init_screen_fence_funcs(struct pipe_screen *screen)
+{
+ screen->fence_reference = softpipe_fence_reference;
+ screen->fence_finish = softpipe_fence_finish;
+ screen->fence_signalled = softpipe_fence_signalled;
+}
diff --git a/src/gallium/drivers/softpipe/sp_fence.h b/src/gallium/drivers/softpipe/sp_fence.h
new file mode 100644
index 0000000000..39c33243bd
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_fence.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef SP_FENCE_H_
+#define SP_FENCE_H_
+
+
+struct pipe_screen;
+
+
+void
+softpipe_init_screen_fence_funcs(struct pipe_screen *screen);
+
+
+#endif /* SP_FENCE_H_ */
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index e8952bf4fb..3d76af4d8c 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -93,9 +93,9 @@ softpipe_flush( struct pipe_context *pipe,
static unsigned frame_no = 1;
static char filename[256];
util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no);
- debug_dump_surface_bmp(filename, softpipe->framebuffer.cbufs[0]);
+ debug_dump_surface_bmp(softpipe, filename, softpipe->framebuffer.cbufs[0]);
util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no);
- debug_dump_surface_bmp(filename, softpipe->framebuffer.zsbuf);
+ debug_dump_surface_bmp(softpipe, filename, softpipe->framebuffer.zsbuf);
++frame_no;
}
#endif
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 27fa126b7c..67e2c8f8bc 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -145,8 +145,13 @@ exec_run( const struct sp_fragment_shader *base,
case TGSI_SEMANTIC_COLOR:
{
uint cbuf = sem_index[i];
+
+ assert(sizeof(quad->output.color[cbuf]) ==
+ sizeof(machine->Outputs[i]));
+
+ /* copy float[4][4] result */
memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
+ &machine->Outputs[i],
sizeof(quad->output.color[0]) );
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index acee213670..daa158df7c 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -156,8 +156,13 @@ fs_sse_run( const struct sp_fragment_shader *base,
case TGSI_SEMANTIC_COLOR:
{
uint cbuf = sem_index[i];
+
+ assert(sizeof(quad->output.color[cbuf]) ==
+ sizeof(machine->Outputs[i]));
+
+ /* copy float[4][4] result */
memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
+ &machine->Outputs[i],
sizeof(quad->output.color[0]) );
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 98c08eaffa..6749243ab4 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -264,57 +264,29 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride));
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- }
}
break;
@@ -448,56 +420,28 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
- }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-0, stride) );
- }
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_public.h b/src/gallium/drivers/softpipe/sp_public.h
new file mode 100644
index 0000000000..62d0903d87
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_public.h
@@ -0,0 +1,10 @@
+#ifndef SP_PUBLIC_H
+#define SP_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+softpipe_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 6ec63fe698..d62bfa3d63 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -27,15 +27,17 @@
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "state_tracker/sw_winsys.h"
+
#include "sp_texture.h"
-#include "sp_winsys.h"
#include "sp_screen.h"
#include "sp_context.h"
+#include "sp_buffer.h"
+#include "sp_fence.h"
+#include "sp_public.h"
static const char *
@@ -83,11 +85,11 @@ softpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13; /* max 4Kx4K */
+ return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 9; /* max 256x256x256 */
+ return SP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13; /* max 4Kx4K */
+ return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
@@ -145,6 +147,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
assert(target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
target == PIPE_TEXTURE_3D ||
@@ -166,15 +170,25 @@ softpipe_is_format_supported( struct pipe_screen *screen,
case PIPE_FORMAT_NONE:
return FALSE;
default:
- return TRUE;
+ break;
}
+
+ if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if(!winsys->is_displaytarget_format_supported(winsys, format))
+ return FALSE;
+ }
+
+ /* XXX: this is often a lie. Pull in logic from llvmpipe to fix.
+ */
+ return TRUE;
}
static void
softpipe_destroy_screen( struct pipe_screen *screen )
{
- struct pipe_winsys *winsys = screen->winsys;
+ struct softpipe_screen *sp_screen = softpipe_screen(screen);
+ struct sw_winsys *winsys = sp_screen->winsys;
if(winsys->destroy)
winsys->destroy(winsys);
@@ -183,21 +197,37 @@ softpipe_destroy_screen( struct pipe_screen *screen )
}
+/* This is often overriden by the co-state tracker.
+ */
+static void
+softpipe_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct softpipe_screen *screen = softpipe_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct softpipe_texture *texture = softpipe_texture(surface->texture);
+
+ assert(texture->dt);
+ if (texture->dt)
+ winsys->displaytarget_display(winsys, texture->dt, context_private);
+}
/**
* 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)
+softpipe_create_screen(struct sw_winsys *winsys)
{
struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
if (!screen)
return NULL;
- screen->base.winsys = winsys;
+ screen->winsys = winsys;
+ screen->base.winsys = NULL;
screen->base.destroy = softpipe_destroy_screen;
screen->base.get_name = softpipe_get_name;
@@ -206,9 +236,11 @@ softpipe_create_screen(struct pipe_winsys *winsys)
screen->base.get_paramf = softpipe_get_paramf;
screen->base.is_format_supported = softpipe_is_format_supported;
screen->base.context_create = softpipe_create_context;
+ screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
softpipe_init_screen_texture_funcs(&screen->base);
- u_simple_screen_init(&screen->base);
+ softpipe_init_screen_buffer_funcs(&screen->base);
+ softpipe_init_screen_fence_funcs(&screen->base);
return &screen->base;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h
index 3d4bfd3e84..f741454c9e 100644
--- a/src/gallium/drivers/softpipe/sp_screen.h
+++ b/src/gallium/drivers/softpipe/sp_screen.h
@@ -35,10 +35,13 @@
#include "pipe/p_defines.h"
+struct sw_winsys;
struct softpipe_screen {
struct pipe_screen base;
+ struct sw_winsys *winsys;
+
/* Increments whenever textures are modified. Contexts can track
* this.
*/
@@ -55,4 +58,5 @@ softpipe_screen( struct pipe_screen *pipe )
}
+
#endif /* SP_SCREEN_H */
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 4370bbeaee..6b01c0f4d7 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -100,6 +100,11 @@ struct sp_geometry_shader {
struct draw_geometry_shader *draw_data;
};
+struct sp_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
void *
softpipe_create_blend_state(struct pipe_context *,
@@ -160,8 +165,14 @@ void *softpipe_create_gs_state(struct pipe_context *,
void softpipe_bind_gs_state(struct pipe_context *, void *);
void softpipe_delete_gs_state(struct pipe_context *, void *);
+void *softpipe_create_vertex_elements_state(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+void softpipe_bind_vertex_elements_state(struct pipe_context *, void *);
+void softpipe_delete_vertex_elements_state(struct pipe_context *, void *);
+
void softpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
+ const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
@@ -178,10 +189,6 @@ softpipe_set_vertex_sampler_textures(struct pipe_context *,
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void softpipe_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-
void softpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index c88e213751..2b089c2831 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -28,6 +28,7 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_fs.h"
+#include "sp_buffer.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
@@ -163,26 +164,33 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
FREE( state );
}
-
-
void
softpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_buffer *constants)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ unsigned size = constants ? constants->size : 0;
+ const void *data = constants ? softpipe_buffer(constants)->data : NULL;
assert(shader < PIPE_SHADER_TYPES);
- assert(index < PIPE_MAX_CONSTANT_BUFFERS);
+ assert(index == 0);
draw_flush(softpipe->draw);
/* note: reference counting */
- pipe_buffer_reference(&softpipe->constants[shader][index], buf);
+ pipe_buffer_reference(&softpipe->constants[shader][index], constants);
+ if(shader == PIPE_SHADER_VERTEX) {
+ draw_set_mapped_constant_buffer(softpipe->draw, PIPE_SHADER_VERTEX, index,
+ data, size);
+ }
+
+ softpipe->mapped_constants[shader][index] = data;
softpipe->dirty |= SP_NEW_CONSTANTS;
}
+
void *
softpipe_create_gs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index b491d92ed1..462f4d2655 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -32,27 +32,45 @@
#include "sp_context.h"
#include "sp_state.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
+void *
+softpipe_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct sp_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct sp_velems_state *) MALLOC(sizeof(struct sp_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
void
-softpipe_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *attribs)
+softpipe_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ struct sp_velems_state *sp_velems = (struct sp_velems_state *) velems;
- assert(count <= PIPE_MAX_ATTRIBS);
-
- memcpy(softpipe->vertex_element, attribs,
- count * sizeof(struct pipe_vertex_element));
- softpipe->num_vertex_elements = count;
+ softpipe->velems = sp_velems;
softpipe->dirty |= SP_NEW_VERTEX;
- draw_set_vertex_elements(softpipe->draw, count, attribs);
+ if (sp_velems)
+ draw_set_vertex_elements(softpipe->draw, sp_velems->count, sp_velems->velem);
}
+void
+softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
softpipe_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index ef7ccf4189..fa9e19b282 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -1614,7 +1614,6 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned j;
float ssss[4], tttt[4];
- unsigned face;
/*
major axis
@@ -1628,7 +1627,8 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
*/
- /* First choose the cube face.
+ /* Choose the cube face and compute new s/t coords for the 2D face.
+ *
* Use the same cube face for all four pixels in the quad.
*
* This isn't ideal, but if we want to use a different cube face
@@ -1647,85 +1647,37 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
if (arx >= ary && arx >= arz) {
- if (rx >= 0.0F) {
- face = PIPE_TEX_FACE_POS_X;
- }
- else {
- face = PIPE_TEX_FACE_NEG_X;
+ float sign = (rx >= 0.0F) ? 1.0F : -1.0F;
+ uint face = (rx >= 0.0F) ? PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float ima = -0.5F / fabsf(s[j]);
+ ssss[j] = sign * p[j] * ima + 0.5F;
+ tttt[j] = t[j] * ima + 0.5F;
+ samp->faces[j] = face;
}
}
else if (ary >= arx && ary >= arz) {
- if (ry >= 0.0F) {
- face = PIPE_TEX_FACE_POS_Y;
- }
- else {
- face = PIPE_TEX_FACE_NEG_Y;
+ float sign = (ry >= 0.0F) ? 1.0F : -1.0F;
+ uint face = (ry >= 0.0F) ? PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float ima = -0.5F / fabsf(t[j]);
+ ssss[j] = -s[j] * ima + 0.5F;
+ tttt[j] = sign * -p[j] * ima + 0.5F;
+ samp->faces[j] = face;
}
}
else {
- if (rz > 0.0F) {
- face = PIPE_TEX_FACE_POS_Z;
- }
- else {
- face = PIPE_TEX_FACE_NEG_Z;
+ float sign = (rz >= 0.0F) ? 1.0F : -1.0F;
+ uint face = (rz >= 0.0F) ? PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float ima = -0.5 / fabsf(p[j]);
+ ssss[j] = sign * -s[j] * ima + 0.5F;
+ tttt[j] = t[j] * ima + 0.5F;
+ samp->faces[j] = face;
}
}
}
- /* Now compute the 2D _face_ texture coords from the
- * 3D _cube_ texture coords.
- */
- for (j = 0; j < QUAD_SIZE; j++) {
- const float rx = s[j], ry = t[j], rz = p[j];
- const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
- float sc, tc, ma;
-
- switch (face) {
- case PIPE_TEX_FACE_POS_X:
- sc = -rz;
- tc = -ry;
- ma = arx;
- break;
- case PIPE_TEX_FACE_NEG_X:
- sc = rz;
- tc = -ry;
- ma = arx;
- break;
- case PIPE_TEX_FACE_POS_Y:
- sc = rx;
- tc = rz;
- ma = ary;
- break;
- case PIPE_TEX_FACE_NEG_Y:
- sc = rx;
- tc = -rz;
- ma = ary;
- break;
- case PIPE_TEX_FACE_POS_Z:
- sc = rx;
- tc = -ry;
- ma = arz;
- break;
- case PIPE_TEX_FACE_NEG_Z:
- sc = -rx;
- tc = -ry;
- ma = arz;
- break;
- default:
- assert(0 && "bad cube face");
- sc = 0.0F;
- tc = 0.0F;
- ma = 0.0F;
- }
-
- {
- const float ima = 1.0 / ma;
- ssss[j] = ( sc * ima + 1.0F ) * 0.5F;
- tttt[j] = ( tc * ima + 1.0F ) * 0.5F;
- samp->faces[j] = face;
- }
- }
-
/* In our little pipeline, the compare stage is next. If compare
* is not active, this will point somewhere deeper into the
* pipeline, eg. to mip_filter or even img_filter.
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index a0b95c8884..e3a5e37ce4 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -43,14 +43,14 @@
struct softpipe_tex_tile_cache *
-sp_create_tex_tile_cache( struct pipe_screen *screen )
+sp_create_tex_tile_cache( struct pipe_context *pipe )
{
struct softpipe_tex_tile_cache *tc;
uint pos;
tc = CALLOC_STRUCT( softpipe_tex_tile_cache );
if (tc) {
- tc->screen = screen;
+ tc->pipe = pipe;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
tc->entries[pos].addr.bits.invalid = 1;
}
@@ -63,19 +63,16 @@ sp_create_tex_tile_cache( struct pipe_screen *screen )
void
sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
{
- struct pipe_screen *screen;
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
/*assert(tc->entries[pos].x < 0);*/
}
if (tc->transfer) {
- screen = tc->transfer->texture->screen;
- screen->tex_transfer_destroy(tc->transfer);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer);
}
if (tc->tex_trans) {
- screen = tc->tex_trans->texture->screen;
- screen->tex_transfer_destroy(tc->tex_trans);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans);
}
FREE( tc );
@@ -88,7 +85,7 @@ void
sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc)
{
if (tc->tex_trans && !tc->tex_trans_map)
- tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
}
@@ -96,7 +93,7 @@ void
sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc)
{
if (tc->tex_trans_map) {
- tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
tc->tex_trans_map = NULL;
}
}
@@ -133,14 +130,12 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
pipe_texture_reference(&tc->texture, texture);
if (tc->tex_trans) {
- struct pipe_screen *screen = tc->tex_trans->texture->screen;
-
if (tc->tex_trans_map) {
- screen->transfer_unmap(screen, tc->tex_trans);
+ tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
tc->tex_trans_map = NULL;
}
- screen->tex_transfer_destroy(tc->tex_trans);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans);
tc->tex_trans = NULL;
}
@@ -204,7 +199,6 @@ const struct softpipe_tex_cached_tile *
sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
union tex_tile_address addr )
{
- struct pipe_screen *screen = tc->screen;
struct softpipe_tex_cached_tile *tile;
tile = tc->entries + tex_cache_pos( addr );
@@ -232,16 +226,16 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
if (tc->tex_trans) {
if (tc->tex_trans_map) {
- tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
tc->tex_trans_map = NULL;
}
- screen->tex_transfer_destroy(tc->tex_trans);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans);
tc->tex_trans = NULL;
}
tc->tex_trans =
- screen->get_tex_transfer(screen, tc->texture,
+ tc->pipe->get_tex_transfer(tc->pipe, tc->texture,
addr.bits.face,
addr.bits.level,
addr.bits.z,
@@ -249,7 +243,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
u_minify(tc->texture->width0, addr.bits.level),
u_minify(tc->texture->height0, addr.bits.level));
- tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
+ tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
tc->tex_face = addr.bits.face;
tc->tex_level = addr.bits.level;
@@ -257,7 +251,8 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
/* get tile from the transfer (view into texture) */
- pipe_get_tile_rgba(tc->tex_trans,
+ pipe_get_tile_rgba(tc->pipe,
+ tc->tex_trans,
addr.bits.x * TILE_SIZE,
addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
index ac6886a3df..b116397258 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -70,7 +70,7 @@ struct softpipe_tex_cached_tile
struct softpipe_tex_tile_cache
{
- struct pipe_screen *screen;
+ struct pipe_context *pipe;
struct pipe_transfer *transfer;
void *transfer_map;
@@ -88,7 +88,7 @@ struct softpipe_tex_tile_cache
extern struct softpipe_tex_tile_cache *
-sp_create_tex_tile_cache( struct pipe_screen *screen );
+sp_create_tex_tile_cache( struct pipe_context *pipe );
extern void
sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc);
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 32d261b5ff..da8529c154 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -36,11 +36,13 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_simple_screen.h"
#include "sp_context.h"
#include "sp_texture.h"
#include "sp_screen.h"
-#include "sp_winsys.h"
+
+#include "state_tracker/sw_winsys.h"
/**
@@ -72,11 +74,9 @@ softpipe_texture_layout(struct pipe_screen *screen,
depth = u_minify(depth, 1);
}
- spt->buffer = screen->buffer_create(screen, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- buffer_size);
+ spt->data = align_malloc(buffer_size, 16);
- return spt->buffer != NULL;
+ return spt->data != NULL;
}
@@ -87,19 +87,18 @@ static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
struct softpipe_texture * spt)
{
- unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ_WRITE);
- unsigned tex_usage = spt->base.tex_usage;
-
- spt->buffer = screen->surface_buffer_create( screen,
- spt->base.width0,
- spt->base.height0,
- spt->base.format,
- usage,
- tex_usage,
- &spt->stride[0]);
-
- return spt->buffer != NULL;
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
+ /* Round up the surface size to a multiple of the tile size?
+ */
+ spt->dt = winsys->displaytarget_create(winsys,
+ spt->base.format,
+ spt->base.width0,
+ spt->base.height0,
+ 16,
+ &spt->stride[0] );
+
+ return spt->dt != NULL;
}
@@ -123,7 +122,8 @@ softpipe_texture_create(struct pipe_screen *screen,
util_is_power_of_two(template->depth0));
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
if (!softpipe_displaytarget_layout(screen, spt))
goto fail;
}
@@ -140,46 +140,24 @@ softpipe_texture_create(struct pipe_screen *screen,
}
-/**
- * Create a new pipe_texture which wraps an existing buffer.
- */
-static struct pipe_texture *
-softpipe_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- struct softpipe_texture *spt;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- spt = CALLOC_STRUCT(softpipe_texture);
- if (!spt)
- return NULL;
-
- spt->base = *base;
- pipe_reference_init(&spt->base.reference, 1);
- spt->base.screen = screen;
- spt->stride[0] = stride[0];
-
- pipe_buffer_reference(&spt->buffer, buffer);
-
- return &spt->base;
-}
static void
softpipe_texture_destroy(struct pipe_texture *pt)
{
+ struct softpipe_screen *screen = softpipe_screen(pt->screen);
struct softpipe_texture *spt = softpipe_texture(pt);
- pipe_buffer_reference(&spt->buffer, NULL);
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = screen->winsys;
+ winsys->displaytarget_destroy(winsys, spt->dt);
+ }
+ else {
+ /* regular texture */
+ align_free(spt->data);
+ }
+
FREE(spt);
}
@@ -278,7 +256,7 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf)
* \param height height of region to read/write
*/
static struct pipe_transfer *
-softpipe_get_tex_transfer(struct pipe_screen *screen,
+softpipe_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
@@ -332,7 +310,8 @@ softpipe_get_tex_transfer(struct pipe_screen *screen,
* softpipe_get_tex_transfer().
*/
static void
-softpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
+softpipe_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
/* Effectively do the texture_update work here - if texture images
* needed post-processing to put them into hardware layout, this is
@@ -348,7 +327,7 @@ softpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
* Create memory mapping for given pipe_transfer object.
*/
static void *
-softpipe_transfer_map( struct pipe_screen *screen,
+softpipe_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
ubyte *map, *xfer_map;
@@ -359,9 +338,20 @@ softpipe_transfer_map( struct pipe_screen *screen,
spt = softpipe_texture(transfer->texture);
format = transfer->texture->format;
- map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
- if (map == NULL)
- return NULL;
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
+
+ map = winsys->displaytarget_map(winsys, spt->dt,
+ pipe_transfer_buffer_flags(transfer));
+ if (map == NULL)
+ return NULL;
+ }
+ else {
+ map = spt->data;
+ if (map == NULL)
+ return NULL;
+ }
/* May want to different things here depending on read/write nature
* of the map:
@@ -370,7 +360,7 @@ softpipe_transfer_map( struct pipe_screen *screen,
/* Do something to notify sharing contexts of a texture change.
* In softpipe, that would mean flushing the texture cache.
*/
- softpipe_screen(screen)->timestamp++;
+ softpipe_screen(pipe->screen)->timestamp++;
}
xfer_map = map + softpipe_transfer(transfer)->offset +
@@ -385,7 +375,7 @@ softpipe_transfer_map( struct pipe_screen *screen,
* Unmap memory mapping for given pipe_transfer object.
*/
static void
-softpipe_transfer_unmap(struct pipe_screen *screen,
+softpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct softpipe_texture *spt;
@@ -393,7 +383,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
assert(transfer->texture);
spt = softpipe_texture(transfer->texture);
- pipe_buffer_unmap( screen, spt->buffer );
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
+ winsys->displaytarget_unmap(winsys, spt->dt);
+ }
if (transfer->usage & PIPE_TRANSFER_WRITE) {
/* Mark the texture as dirty to expire the tile caches. */
@@ -455,43 +449,26 @@ softpipe_video_surface_destroy(struct pipe_video_surface *vsfc)
void
+softpipe_init_texture_funcs(struct pipe_context *pipe)
+{
+ pipe->get_tex_transfer = softpipe_get_tex_transfer;
+ pipe->tex_transfer_destroy = softpipe_tex_transfer_destroy;
+ pipe->transfer_map = softpipe_transfer_map;
+ pipe->transfer_unmap = softpipe_transfer_unmap;
+}
+
+void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
- screen->texture_blanket = softpipe_texture_blanket;
screen->texture_destroy = softpipe_texture_destroy;
screen->get_tex_surface = softpipe_get_tex_surface;
screen->tex_surface_destroy = softpipe_tex_surface_destroy;
- screen->get_tex_transfer = softpipe_get_tex_transfer;
- screen->tex_transfer_destroy = softpipe_tex_transfer_destroy;
- screen->transfer_map = softpipe_transfer_map;
- screen->transfer_unmap = softpipe_transfer_unmap;
-
screen->video_surface_create = softpipe_video_surface_create;
screen->video_surface_destroy = softpipe_video_surface_destroy;
}
-/**
- * Return pipe_buffer handle and stride for given texture object.
- * XXX used for???
- */
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride )
-{
- struct softpipe_texture *tex = (struct softpipe_texture *) texture;
-
- if (!tex)
- return FALSE;
-
- pipe_buffer_reference(buf, tex->buffer);
- if (stride)
- *stride = tex->stride[0];
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 2ef64e1e7c..c0e6ba8a86 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -33,6 +33,10 @@
#include "pipe/p_video_state.h"
+#define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */
+#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */
+
+
struct pipe_context;
struct pipe_screen;
struct softpipe_context;
@@ -42,12 +46,19 @@ struct softpipe_texture
{
struct pipe_texture base;
- unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS];
+ unsigned stride[SP_MAX_TEXTURE_2D_LEVELS];
- /* The data is held here:
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
*/
- struct pipe_buffer *buffer;
+ struct sw_displaytarget *dt;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
+ */
+ void *data;
/* True if texture images are power-of-two in all dimensions:
*/
@@ -96,5 +107,8 @@ softpipe_video_surface(struct pipe_video_surface *pvs)
extern void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen);
+void
+softpipe_init_texture_funcs(struct pipe_context *pipe);
+
#endif /* SP_TEXTURE */
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index aedfdf1b46..1c3c2667d7 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -79,20 +79,20 @@ clear_clear_flag(uint *bitvec, union tile_address addr)
struct softpipe_tile_cache *
-sp_create_tile_cache( struct pipe_screen *screen )
+sp_create_tile_cache( struct pipe_context *pipe )
{
struct softpipe_tile_cache *tc;
uint pos;
int maxLevels, maxTexSize;
/* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */
- maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ maxLevels = pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
maxTexSize = 1 << (maxLevels - 1);
assert(MAX_WIDTH >= maxTexSize);
tc = CALLOC_STRUCT( softpipe_tile_cache );
if (tc) {
- tc->screen = screen;
+ tc->pipe = pipe;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
tc->entries[pos].addr.bits.invalid = 1;
}
@@ -115,15 +115,13 @@ sp_create_tile_cache( struct pipe_screen *screen )
void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
{
- struct pipe_screen *screen;
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
/*assert(tc->entries[pos].x < 0);*/
}
if (tc->transfer) {
- screen = tc->transfer->texture->screen;
- screen->tex_transfer_destroy(tc->transfer);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer);
}
FREE( tc );
@@ -137,27 +135,25 @@ void
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct pipe_surface *ps)
{
- if (tc->transfer) {
- struct pipe_screen *screen = tc->transfer->texture->screen;
+ struct pipe_context *pipe = tc->pipe;
+ if (tc->transfer) {
if (ps == tc->surface)
return;
if (tc->transfer_map) {
- screen->transfer_unmap(screen, tc->transfer);
+ pipe->transfer_unmap(pipe, tc->transfer);
tc->transfer_map = NULL;
}
- screen->tex_transfer_destroy(tc->transfer);
+ pipe->tex_transfer_destroy(pipe, tc->transfer);
tc->transfer = NULL;
}
tc->surface = ps;
if (ps) {
- struct pipe_screen *screen = ps->texture->screen;
-
- tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
+ tc->transfer = pipe->get_tex_transfer(pipe, ps->texture, ps->face,
ps->level, ps->zslice,
PIPE_TRANSFER_READ_WRITE,
0, 0, ps->width, ps->height);
@@ -187,7 +183,7 @@ void
sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
{
if (tc->transfer && !tc->transfer_map)
- tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
+ tc->transfer_map = tc->pipe->transfer_map(tc->pipe, tc->transfer);
}
@@ -195,7 +191,7 @@ void
sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
{
if (tc->transfer_map) {
- tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->pipe->transfer_unmap(tc->pipe, tc->transfer);
tc->transfer_map = NULL;
}
}
@@ -295,7 +291,8 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
union tile_address addr = tile_address(x, y);
if (is_clear_flag_set(tc->clear_flags, addr)) {
- pipe_put_tile_raw(pt,
+ pipe_put_tile_raw(tc->pipe,
+ pt,
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
@@ -329,14 +326,14 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc)
struct softpipe_cached_tile *tile = tc->entries + pos;
if (!tile->addr.bits.invalid) {
if (tc->depth_stencil) {
- pipe_put_tile_raw(pt,
+ pipe_put_tile_raw(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_put_tile_rgba(pt,
+ pipe_put_tile_rgba(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
@@ -379,14 +376,14 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
if (tile->addr.bits.invalid == 0) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
- pipe_put_tile_raw(pt,
+ pipe_put_tile_raw(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_put_tile_rgba(pt,
+ pipe_put_tile_rgba(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
@@ -409,14 +406,14 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
else {
/* get new tile data from transfer */
if (tc->depth_stencil) {
- pipe_get_tile_raw(pt,
+ pipe_get_tile_raw(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_get_tile_rgba(pt,
+ pipe_get_tile_rgba(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index a12092702a..753d8c0daa 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -80,7 +80,7 @@ struct softpipe_cached_tile
struct softpipe_tile_cache
{
- struct pipe_screen *screen;
+ struct pipe_context *pipe;
struct pipe_surface *surface; /**< the surface we're caching */
struct pipe_transfer *transfer;
void *transfer_map;
@@ -98,7 +98,7 @@ struct softpipe_tile_cache
extern struct softpipe_tile_cache *
-sp_create_tile_cache( struct pipe_screen *screen );
+sp_create_tile_cache( struct pipe_context *pipe );
extern void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc);
diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c
deleted file mode 100644
index 0a6245ed2c..0000000000
--- a/src/gallium/drivers/softpipe/sp_winsys.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * 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 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
- * THE COPYRIGHT HOLDERS, AUTHORS 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.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Malloc softpipe winsys. Uses malloc for all memory allocations.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-
-#include "util/u_simple_screen.h"/* port to just p_screen */
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "sp_winsys.h"
-
-
-struct st_softpipe_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct st_softpipe_buffer *
-st_softpipe_buffer( struct pipe_buffer *buf )
-{
- return (struct st_softpipe_buffer *)buf;
-}
-
-
-static void *
-st_softpipe_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = st_softpipe_buf->data;
- return st_softpipe_buf->mapped;
-}
-
-
-static void
-st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-st_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
-
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
-
- oldBuf->data = NULL;
- }
-
- FREE(oldBuf);
-}
-
-
-static void
-st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
- struct pipe_surface *surf,
- void *context_private)
-{
-}
-
-
-
-static const char *
-st_softpipe_get_name(struct pipe_winsys *winsys)
-{
- return "softpipe";
-}
-
-
-static struct pipe_buffer *
-st_softpipe_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- buffer->data = align_malloc(size, alignment);
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
- void *ptr,
- unsigned bytes)
-{
- struct st_softpipe_buffer *buffer;
-
- buffer = CALLOC_STRUCT(st_softpipe_buffer);
- if(!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-st_softpipe_fence_reference(struct pipe_winsys *winsys,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-st_softpipe_fence_signalled(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-st_softpipe_fence_finish(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static void
-st_softpipe_destroy(struct pipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-struct pipe_screen *
-softpipe_create_screen_malloc(void)
-{
- static struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(pipe_winsys);
- if(!winsys)
- return NULL;
-
- winsys->destroy = st_softpipe_destroy;
-
- winsys->buffer_create = st_softpipe_buffer_create;
- winsys->user_buffer_create = st_softpipe_user_buffer_create;
- winsys->buffer_map = st_softpipe_buffer_map;
- winsys->buffer_unmap = st_softpipe_buffer_unmap;
- winsys->buffer_destroy = st_softpipe_buffer_destroy;
-
- winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
-
- winsys->fence_reference = st_softpipe_fence_reference;
- winsys->fence_signalled = st_softpipe_fence_signalled;
- winsys->fence_finish = st_softpipe_fence_finish;
-
- winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
- winsys->get_name = st_softpipe_get_name;
-
- screen = softpipe_create_screen(winsys);
- if(!screen)
- st_softpipe_destroy(winsys);
-
- return screen;
-}
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 03302e2a6e..791d30edc0 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -169,6 +169,11 @@ struct svga_sampler_state {
unsigned view_max_lod;
};
+struct svga_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
/* Use to calculate differences between state emitted to hardware and
* current driver-calculated state.
*/
@@ -178,13 +183,13 @@ struct svga_state
const struct svga_depth_stencil_state *depth;
const struct svga_rasterizer_state *rast;
const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+ const struct svga_velems_state *velems;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
struct svga_fragment_shader *fs;
struct svga_vertex_shader *vs;
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
struct pipe_buffer *cb[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
@@ -204,7 +209,6 @@ struct svga_state
unsigned num_samplers;
unsigned num_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
unsigned reduced_prim;
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index acba2b8f9d..1a8ef296ca 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -155,7 +155,7 @@ static void svga_bind_sampler_states(struct pipe_context *pipe,
/* Check for no-op */
if (num == svga->curr.num_samplers &&
!memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) {
- debug_printf("sampler noop\n");
+ if (0) debug_printf("sampler noop\n");
return;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 836b8441da..1715a47fc6 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -26,6 +26,7 @@
#include "util/u_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
+#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h"
#include "svga_screen.h"
@@ -64,20 +65,37 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
svga->dirty |= SVGA_NEW_VBUFFER;
}
-static void svga_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+
+static void *
+svga_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
- struct svga_context *svga = svga_context(pipe);
- unsigned i;
+ struct svga_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
- for (i = 0; i < count; i++)
- svga->curr.ve[i] = elements[i];
+static void svga_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct svga_context *svga = svga_context(pipe);
+ struct svga_velems_state *svga_velems = (struct svga_velems_state *) velems;
- svga->curr.num_vertex_elements = count;
+ svga->curr.velems = svga_velems;
svga->dirty |= SVGA_NEW_VELEMENT;
}
+static void svga_delete_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ FREE(velems);
+}
void svga_cleanup_vertex_state( struct svga_context *svga )
{
@@ -91,7 +109,9 @@ void svga_cleanup_vertex_state( struct svga_context *svga )
void svga_init_vertex_functions( struct svga_context *svga )
{
svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
- svga->pipe.set_vertex_elements = svga_set_vertex_elements;
+ svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
+ svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
+ svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index e9792e063e..107e4a3962 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -315,7 +315,11 @@ svga_texture_create(struct pipe_screen *screen,
tex->key.cachable = 0;
}
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) {
+ tex->key.cachable = 0;
+ }
+
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) {
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
tex->key.cachable = 0;
}
@@ -355,80 +359,18 @@ error1:
}
-static struct pipe_texture *
-svga_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- struct svga_texture *tex;
- struct svga_buffer *sbuf = svga_buffer(buffer);
- struct svga_winsys_screen *sws = svga_winsys_screen(screen);
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- /**
- * We currently can't do texture blanket on
- * SVGA3D_BUFFER. Need to blit to a temporary surface?
- */
- assert(sbuf->handle);
- if (!sbuf->handle)
- return NULL;
- if (svga_translate_format(base->format) != sbuf->key.format) {
- unsigned f1 = svga_translate_format(base->format);
- unsigned f2 = sbuf->key.format;
- /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
- if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
- (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
- (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
- debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
- return NULL;
- }
- }
-
- tex = CALLOC_STRUCT(svga_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
-
-
- if (sbuf->key.format == 1)
- tex->base.format = PIPE_FORMAT_B8G8R8X8_UNORM;
- else if (sbuf->key.format == 2)
- tex->base.format = PIPE_FORMAT_B8G8R8A8_UNORM;
-
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle);
-
- /* We don't own this storage, so don't try to cache it.
- */
- assert(sbuf->key.cachable == 0);
- tex->key.cachable = 0;
- sws->surface_reference(sws, &tex->handle, sbuf->handle);
-
- return &tex->base;
-}
-
-
-struct pipe_texture *
-svga_screen_texture_wrap_surface(struct pipe_screen *screen,
- struct pipe_texture *base,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf)
+static struct pipe_texture *
+svga_screen_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *base,
+ struct winsys_handle *whandle)
{
+ struct svga_winsys_screen *sws = svga_winsys_screen(screen);
+ struct svga_winsys_surface *srf;
struct svga_texture *tex;
+ enum SVGA3dSurfaceFormat format = 0;
assert(screen);
/* Only supports one type */
@@ -438,6 +380,8 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
return NULL;
}
+ srf = sws->surface_from_handle(sws, whandle, &format);
+
if (!srf)
return NULL;
@@ -478,6 +422,22 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
}
+static boolean
+svga_screen_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
+ unsigned stride;
+
+ assert(svga_texture(texture)->key.cachable == 0);
+ svga_texture(texture)->key.cachable = 0;
+ stride = util_format_get_nblocksx(texture->format, texture->width0) *
+ util_format_get_blocksize(texture->format);
+ return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
+}
+
+
static void
svga_texture_destroy(struct pipe_texture *pt)
{
@@ -823,15 +783,17 @@ svga_surface_needs_propagation(struct pipe_surface *surf)
return s->dirty && s->handle != tex->handle;
}
-
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
static struct pipe_transfer *
-svga_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
+svga_get_tex_transfer(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage, unsigned x, unsigned y,
+ unsigned w, unsigned h)
{
- struct svga_screen *ss = svga_screen(screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st;
unsigned nblocksx = util_format_get_nblocksx(texture->format, w);
@@ -899,11 +861,14 @@ no_hwbuf:
}
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
static void *
-svga_transfer_map( struct pipe_screen *screen,
+svga_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
- struct svga_screen *ss = svga_screen(screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st = svga_transfer(transfer);
@@ -917,11 +882,14 @@ svga_transfer_map( struct pipe_screen *screen,
}
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
static void
-svga_transfer_unmap(struct pipe_screen *screen,
+svga_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct svga_screen *ss = svga_screen(screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st = svga_transfer(transfer);
@@ -931,10 +899,11 @@ svga_transfer_unmap(struct pipe_screen *screen,
static void
-svga_tex_transfer_destroy(struct pipe_transfer *transfer)
+svga_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
struct svga_texture *tex = svga_texture(transfer->texture);
- struct svga_screen *ss = svga_screen(transfer->texture->screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st = svga_transfer(transfer);
@@ -951,18 +920,26 @@ svga_tex_transfer_destroy(struct pipe_transfer *transfer)
FREE(st);
}
+
+void
+svga_init_texture_functions(struct pipe_context *pipe)
+{
+ pipe->get_tex_transfer = svga_get_tex_transfer;
+ pipe->transfer_map = svga_transfer_map;
+ pipe->transfer_unmap = svga_transfer_unmap;
+ pipe->tex_transfer_destroy = svga_tex_transfer_destroy;
+}
+
+
void
svga_screen_init_texture_functions(struct pipe_screen *screen)
{
screen->texture_create = svga_texture_create;
+ screen->texture_from_handle = svga_screen_texture_from_handle;
+ screen->texture_get_handle = svga_screen_texture_get_handle;
screen->texture_destroy = svga_texture_destroy;
screen->get_tex_surface = svga_get_tex_surface;
screen->tex_surface_destroy = svga_tex_surface_destroy;
- screen->texture_blanket = svga_texture_blanket;
- screen->get_tex_transfer = svga_get_tex_transfer;
- screen->transfer_map = svga_transfer_map;
- screen->transfer_unmap = svga_transfer_unmap;
- screen->tex_transfer_destroy = svga_tex_transfer_destroy;
}
/***********************************************************************
@@ -1120,33 +1097,3 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
pipe_texture_reference(&v->texture, NULL);
FREE(v);
}
-
-boolean
-svga_screen_buffer_from_texture(struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride)
-{
- struct svga_texture *stex = svga_texture(texture);
-
- *buffer = svga_screen_buffer_wrap_surface
- (texture->screen,
- svga_translate_format(texture->format),
- stex->handle);
-
- *stride = util_format_get_stride(texture->format, texture->width0);
-
- return *buffer != NULL;
-}
-
-
-struct svga_winsys_surface *
-svga_screen_texture_get_winsys_surface(struct pipe_texture *texture)
-{
- struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
- struct svga_winsys_surface *vsurf = NULL;
-
- assert(svga_texture(texture)->key.cachable == 0);
- svga_texture(texture)->key.cachable = 0;
- sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle);
- return vsurf;
-}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
index 24c1f78ca5..96d035b12d 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -78,7 +78,7 @@ struct svga_texture
{
struct pipe_texture base;
- boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
+ boolean defined[6][SVGA_MAX_TEXTURE_LEVELS];
struct svga_sampler_view *cached_view;
@@ -186,6 +186,9 @@ svga_surface_needs_propagation(struct pipe_surface *surf);
extern void
svga_screen_init_texture_functions(struct pipe_screen *screen);
+void
+svga_init_texture_functions(struct pipe_context *pipe);
+
enum SVGA3dSurfaceFormat
svga_translate_format(enum pipe_format format);
diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c
index d774e3e504..dfaab53aef 100644
--- a/src/gallium/drivers/svga/svga_state_need_swtnl.c
+++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c
@@ -76,8 +76,13 @@ static int update_need_swvfetch( struct svga_context *svga,
unsigned i;
boolean need_swvfetch = FALSE;
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
- svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.ve[i].src_format);
+ if (!svga->curr.velems) {
+ /* No vertex elements bound. */
+ return 0;
+ }
+
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.velems->velem[i].src_format);
if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) {
need_swvfetch = TRUE;
break;
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index 107cc403b4..b7195d246b 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -191,15 +191,24 @@ static int emit_rss( struct svga_context *svga,
EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
}
- if (dirty & SVGA_NEW_RAST)
+ if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
{
const struct svga_rasterizer_state *curr = svga->curr.rast;
+ unsigned cullmode = curr->cullmode;
/* Shademode: still need to rearrange index list to move
* flat-shading PV first vertex.
*/
EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
- EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
+
+ /* Don't do culling while the software pipeline is active. It
+ * does it for us, and additionally introduces potentially
+ * back-facing triangles.
+ */
+ if (svga->state.sw.need_pipeline)
+ cullmode = SVGA3D_FACE_NONE;
+
+ EMIT_RS( svga, cullmode, CULLMODE, fail );
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index ded903170b..f531e22304 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -95,17 +95,17 @@ upload_user_buffers( struct svga_context *svga )
static int emit_hw_vs_vdecl( struct svga_context *svga,
unsigned dirty )
{
- const struct pipe_vertex_element *ve = svga->curr.ve;
+ const struct pipe_vertex_element *ve = svga->curr.velems->velem;
SVGA3dVertexDecl decl;
unsigned i;
- assert(svga->curr.num_vertex_elements >=
+ assert(svga->curr.velems->count >=
svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
svga_hwtnl_reset_vdecl( svga->hwtnl,
- svga->curr.num_vertex_elements );
+ svga->curr.velems->count );
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
+ for (i = 0; i < svga->curr.velems->count; i++) {
const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
unsigned usage, index;
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index d7999fe53d..781f7bf533 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -186,8 +186,8 @@ static int update_zero_stride( struct svga_context *svga,
svga->curr.zero_stride_vertex_elements = 0;
svga->curr.num_zero_stride_vertex_elements = 0;
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
- const struct pipe_vertex_element *vel = &svga->curr.ve[i];
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i];
const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
vel->vertex_buffer_index];
if (vbuffer->stride == 0) {
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 35f36a828f..246d34e649 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -99,8 +99,8 @@ static int update_swtnl_draw( struct svga_context *svga,
if (dirty & SVGA_NEW_VELEMENT)
draw_set_vertex_elements(svga->swtnl.draw,
- svga->curr.num_vertex_elements,
- svga->curr.ve );
+ svga->curr.velems->count,
+ svga->curr.velems->velem );
if (dirty & SVGA_NEW_CLIP)
draw_set_clip_state(svga->swtnl.draw,
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index b4e3af0eaf..d4bb176f9a 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -51,6 +51,7 @@ struct pipe_context;
struct pipe_fence_handle;
struct pipe_texture;
struct svga_region;
+struct winsys_handle;
#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0)
@@ -187,6 +188,25 @@ struct svga_winsys_screen
uint32 numMipLevels);
/**
+ * Creates a surface from a winsys handle.
+ * Used to implement pipe_screen::texture_from_handle.
+ */
+ struct svga_winsys_surface *
+ (*surface_from_handle)(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format);
+
+ /**
+ * Get a winsys_handle from a surface.
+ * Used to implement pipe_screen::texture_get_handle.
+ */
+ boolean
+ (*surface_get_handle)(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
+ /**
* Whether this surface is sitting in a validate list
*/
boolean
@@ -284,19 +304,6 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
struct svga_winsys_surface *srf);
struct svga_winsys_surface *
-svga_screen_texture_get_winsys_surface(struct pipe_texture *texture);
-struct svga_winsys_surface *
svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
-boolean
-svga_screen_buffer_from_texture(struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
-
-struct pipe_texture *
-svga_screen_texture_wrap_surface(struct pipe_screen *screen,
- struct pipe_texture *base,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf);
-
#endif /* SVGA_WINSYS_H_ */
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
index 705ca29e8f..4ee1bf2c35 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
@@ -360,7 +360,9 @@ dump_dstreg(struct sh_dstreg dstreg,
union {
struct sh_reg reg;
struct sh_dstreg dstreg;
- } u = { { 0 } };
+ } u;
+
+ memset(&u, 0, sizeof(u));
assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index df40fbade6..b7e6bbac68 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -27,7 +27,9 @@
#include "util/u_memory.h"
#include "util/u_simple_list.h"
+#include "util/u_format.h"
+#include "pipe/p_format.h"
#include "pipe/p_screen.h"
#include "tr_dump.h"
@@ -773,6 +775,70 @@ trace_context_delete_vs_state(struct pipe_context *_pipe,
}
+static INLINE void *
+trace_context_create_vertex_elements_state(struct pipe_context *_pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ void * result;
+
+ trace_dump_call_begin("pipe_context", "create_vertex_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(uint, num_elements);
+
+ trace_dump_arg_begin("elements");
+ trace_dump_struct_array(vertex_element, elements, num_elements);
+ trace_dump_arg_end();
+
+ result = pipe->create_vertex_elements_state(pipe, num_elements, elements);
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ return result;
+}
+
+
+static INLINE void
+trace_context_bind_vertex_elements_state(struct pipe_context *_pipe,
+ void *state)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "bind_vertex_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, state);
+
+ pipe->bind_vertex_elements_state(pipe, state);
+
+ trace_dump_call_end();
+}
+
+
+static INLINE void
+trace_context_delete_vertex_elements_state(struct pipe_context *_pipe,
+ void *state)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "delete_verte_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, state);
+
+ pipe->delete_vertex_elements_state(pipe, state);
+
+ trace_dump_call_end();
+}
+
+
static INLINE void
trace_context_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *state)
@@ -1048,29 +1114,6 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
static INLINE void
-trace_context_set_vertex_elements(struct pipe_context *_pipe,
- unsigned num_elements,
- const struct pipe_vertex_element *elements)
-{
- struct trace_context *tr_ctx = trace_context(_pipe);
- struct pipe_context *pipe = tr_ctx->pipe;
-
- trace_dump_call_begin("pipe_context", "set_vertex_elements");
-
- trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_elements);
-
- trace_dump_arg_begin("elements");
- trace_dump_struct_array(vertex_element, elements, num_elements);
- trace_dump_arg_end();
-
- pipe->set_vertex_elements(pipe, num_elements, elements);
-
- trace_dump_call_end();
-}
-
-
-static INLINE void
trace_context_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *dest,
unsigned destx, unsigned desty,
@@ -1242,6 +1285,136 @@ trace_is_buffer_referenced( struct pipe_context *_pipe,
return referenced;
}
+
+/********************************************************************
+ * transfer
+ */
+
+
+static struct pipe_transfer *
+trace_context_get_tex_transfer(struct pipe_context *_context,
+ struct pipe_texture *_texture,
+ unsigned face, unsigned level,
+ unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct trace_texture *tr_tex = trace_texture(_texture);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_texture *texture = tr_tex->texture;
+ struct pipe_transfer *result = NULL;
+
+ assert(texture->screen == context->screen);
+
+ trace_dump_call_begin("pipe_context", "get_tex_transfer");
+
+ trace_dump_arg(ptr, context);
+ trace_dump_arg(ptr, texture);
+ trace_dump_arg(uint, face);
+ trace_dump_arg(uint, level);
+ trace_dump_arg(uint, zslice);
+ trace_dump_arg(uint, usage);
+
+ trace_dump_arg(uint, x);
+ trace_dump_arg(uint, y);
+ trace_dump_arg(uint, w);
+ trace_dump_arg(uint, h);
+
+ result = context->get_tex_transfer(context, texture, face, level, zslice, usage,
+ x, y, w, h);
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ if (result)
+ result = trace_transfer_create(tr_context, tr_tex, result);
+
+ return result;
+}
+
+
+static void
+trace_context_tex_transfer_destroy(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct trace_transfer *tr_trans = trace_transfer(_transfer);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
+
+ trace_dump_call_begin("pipe_context", "tex_transfer_destroy");
+
+ trace_dump_arg(ptr, context);
+ trace_dump_arg(ptr, transfer);
+
+ trace_dump_call_end();
+
+ trace_transfer_destroy(tr_context, tr_trans);
+}
+
+
+static void *
+trace_context_transfer_map(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct trace_transfer *tr_trans = trace_transfer(_transfer);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
+ void *map;
+
+ map = context->transfer_map(context, transfer);
+ if(map) {
+ if(transfer->usage & PIPE_TRANSFER_WRITE) {
+ assert(!tr_trans->map);
+ tr_trans->map = map;
+ }
+ }
+
+ return map;
+}
+
+
+static void
+trace_context_transfer_unmap(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct trace_context *tr_ctx = trace_context(_context);
+ struct trace_transfer *tr_trans = trace_transfer(_transfer);
+ struct pipe_context *context = tr_ctx->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
+
+ if(tr_trans->map) {
+ size_t size = util_format_get_nblocksy(transfer->texture->format, transfer->height) * transfer->stride;
+
+ trace_dump_call_begin("pipe_context", "transfer_write");
+
+ trace_dump_arg(ptr, context);
+
+ trace_dump_arg(ptr, transfer);
+
+ trace_dump_arg_begin("stride");
+ trace_dump_uint(transfer->stride);
+ trace_dump_arg_end();
+
+ trace_dump_arg_begin("data");
+ trace_dump_bytes(tr_trans->map, size);
+ trace_dump_arg_end();
+
+ trace_dump_arg_begin("size");
+ trace_dump_uint(size);
+ trace_dump_arg_end();
+
+ trace_dump_call_end();
+
+ tr_trans->map = NULL;
+ }
+
+ context->transfer_unmap(context, transfer);
+}
+
static const struct debug_named_value rbug_blocker_flags[] = {
{"before", 1},
{"after", 2},
@@ -1303,6 +1476,9 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.create_vs_state = trace_context_create_vs_state;
tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
+ tr_ctx->base.create_vertex_elements_state = trace_context_create_vertex_elements_state;
+ tr_ctx->base.bind_vertex_elements_state = trace_context_bind_vertex_elements_state;
+ tr_ctx->base.delete_vertex_elements_state = trace_context_delete_vertex_elements_state;
tr_ctx->base.set_blend_color = trace_context_set_blend_color;
tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref;
tr_ctx->base.set_clip_state = trace_context_set_clip_state;
@@ -1314,7 +1490,6 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures;
tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
- tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
if (pipe->surface_copy)
tr_ctx->base.surface_copy = trace_context_surface_copy;
if (pipe->surface_fill)
@@ -1324,6 +1499,11 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
+ tr_ctx->base.get_tex_transfer = trace_context_get_tex_transfer;
+ tr_ctx->base.tex_transfer_destroy = trace_context_tex_transfer_destroy;
+ tr_ctx->base.transfer_map = trace_context_transfer_map;
+ tr_ctx->base.transfer_unmap = trace_context_transfer_unmap;
+
tr_ctx->pipe = pipe;
trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 2b4915003e..906b3262e4 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -33,6 +33,7 @@
#include "tr_context.h"
#include "tr_buffer.h"
#include "tr_texture.h"
+#include "tr_public.h"
struct trace_drm_api
{
@@ -62,69 +63,8 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
- return trace_screen_create(screen);
-}
-
-
-static struct pipe_texture *
-trace_drm_texture_from_shared_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct drm_api *api = tr_api->api;
- struct pipe_texture *result;
-
- /* TODO trace call */
-
- result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
-
- result = trace_texture_create(trace_screen(_screen), result);
-
- return result;
-}
-
-static boolean
-trace_drm_shared_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
-
- /* TODO trace call */
-
- return api->shared_handle_from_texture(api, screen, texture, stride, handle);
-}
-static boolean
-trace_drm_local_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
-
- /* TODO trace call */
-
- return api->local_handle_from_texture(api, screen, texture, stride, handle);
+ return trace_screen_create(screen);
}
static void
@@ -158,9 +98,6 @@ trace_drm_create(struct drm_api *api)
tr_api->base.name = api->name;
tr_api->base.driver_name = api->driver_name;
tr_api->base.create_screen = trace_drm_create_screen;
- tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
- tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture;
- tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture;
tr_api->base.destroy = trace_drm_destroy;
tr_api->api = api;
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index f97d963dba..f82dd01c69 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -479,7 +479,6 @@ void trace_dump_vertex_element(const struct pipe_vertex_element *state)
trace_dump_member(uint, state, src_offset);
trace_dump_member(uint, state, vertex_buffer_index);
- trace_dump_member(uint, state, nr_components);
trace_dump_member(format, state, src_format);
diff --git a/src/gallium/drivers/trace/tr_public.h b/src/gallium/drivers/trace/tr_public.h
new file mode 100644
index 0000000000..62e217097d
--- /dev/null
+++ b/src/gallium/drivers/trace/tr_public.h
@@ -0,0 +1,45 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE 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
+ * THE COPYRIGHT HOLDERS, AUTHORS 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.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+#ifndef TR_PUBLIC_H
+#define TR_PUBLIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_screen;
+struct pipe_context;
+
+struct pipe_screen *
+trace_screen_create(struct pipe_screen *screen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TR_PUBLIC_H */
diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c
index a43adac694..f4f17566fd 100644
--- a/src/gallium/drivers/trace/tr_rbug.c
+++ b/src/gallium/drivers/trace/tr_rbug.c
@@ -219,7 +219,7 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header,
struct trace_texture *tr_tex = NULL;
struct tr_list *ptr;
- struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_context *context = tr_scr->private_context;
struct pipe_texture *tex;
struct pipe_transfer *t;
@@ -239,12 +239,12 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header,
}
tex = tr_tex->texture;
- t = screen->get_tex_transfer(tr_scr->screen, tex,
- gptr->face, gptr->level, gptr->zslice,
- PIPE_TRANSFER_READ,
- gptr->x, gptr->y, gptr->w, gptr->h);
+ t = context->get_tex_transfer(context, tex,
+ gptr->face, gptr->level, gptr->zslice,
+ PIPE_TRANSFER_READ,
+ gptr->x, gptr->y, gptr->w, gptr->h);
- map = screen->transfer_map(screen, t);
+ map = context->transfer_map(context, t);
rbug_send_texture_read_reply(tr_rbug->con, serial,
t->texture->format,
@@ -256,8 +256,8 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header,
t->stride,
NULL);
- screen->transfer_unmap(screen, t);
- screen->tex_transfer_destroy(t);
+ context->transfer_unmap(context, t);
+ context->tex_transfer_destroy(context, t);
pipe_mutex_unlock(tr_scr->list_mutex);
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 388d83eb5c..25990bdac7 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -35,6 +35,7 @@
#include "tr_texture.h"
#include "tr_context.h"
#include "tr_screen.h"
+#include "tr_public.h"
#include "util/u_inlines.h"
#include "pipe/p_format.h"
@@ -236,39 +237,41 @@ trace_screen_texture_create(struct pipe_screen *_screen,
return result;
}
-
static struct pipe_texture *
-trace_screen_texture_blanket(struct pipe_screen *_screen,
- const struct pipe_texture *templat,
- const unsigned *ppitch,
- struct pipe_buffer *_buffer)
+trace_screen_texture_from_handle(struct pipe_screen *_screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *handle)
{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(_buffer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_buffer *buffer = tr_buf->buffer;
- unsigned pitch = *ppitch;
+ struct trace_screen *tr_screen = trace_screen(_screen);
+ struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *result;
- trace_dump_call_begin("pipe_screen", "texture_blanket");
+ /* TODO trace call */
- trace_dump_arg(ptr, screen);
- trace_dump_arg(template, templat);
- trace_dump_arg(uint, pitch);
- trace_dump_arg(ptr, buffer);
+ result = screen->texture_from_handle(screen, templ, handle);
- result = screen->texture_blanket(screen, templat, ppitch, buffer);
+ result = trace_texture_create(trace_screen(_screen), result);
- trace_dump_ret(ptr, result);
+ return result;
+}
- trace_dump_call_end();
+static boolean
+trace_screen_texture_get_handle(struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ struct winsys_handle *handle)
+{
+ struct trace_screen *tr_screen = trace_screen(_screen);
+ struct trace_texture *tr_texture = trace_texture(_texture);
+ struct pipe_screen *screen = tr_screen->screen;
+ struct pipe_texture *texture = tr_texture->texture;
- result = trace_texture_create(tr_scr, result);
+ /* TODO trace call */
- return result;
+ return screen->texture_get_handle(screen, texture, handle);
}
+
static void
trace_screen_texture_destroy(struct pipe_texture *_texture)
{
@@ -350,133 +353,7 @@ trace_screen_tex_surface_destroy(struct pipe_surface *_surface)
}
-/********************************************************************
- * transfer
- */
-
-
-static struct pipe_transfer *
-trace_screen_get_tex_transfer(struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned face, unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_texture *tr_tex = trace_texture(_texture);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_texture *texture = tr_tex->texture;
- struct pipe_transfer *result = NULL;
-
- assert(texture->screen == screen);
-
- trace_dump_call_begin("pipe_screen", "get_tex_transfer");
- trace_dump_arg(ptr, screen);
- trace_dump_arg(ptr, texture);
- trace_dump_arg(uint, face);
- trace_dump_arg(uint, level);
- trace_dump_arg(uint, zslice);
- trace_dump_arg(uint, usage);
-
- trace_dump_arg(uint, x);
- trace_dump_arg(uint, y);
- trace_dump_arg(uint, w);
- trace_dump_arg(uint, h);
-
- result = screen->get_tex_transfer(screen, texture, face, level, zslice, usage,
- x, y, w, h);
-
- trace_dump_ret(ptr, result);
-
- trace_dump_call_end();
-
- if (result)
- result = trace_transfer_create(tr_tex, result);
-
- return result;
-}
-
-
-static void
-trace_screen_tex_transfer_destroy(struct pipe_transfer *_transfer)
-{
- struct trace_screen *tr_scr = trace_screen(_transfer->texture->screen);
- struct trace_transfer *tr_trans = trace_transfer(_transfer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_transfer *transfer = tr_trans->transfer;
-
- trace_dump_call_begin("pipe_screen", "tex_transfer_destroy");
-
- trace_dump_arg(ptr, screen);
- trace_dump_arg(ptr, transfer);
-
- trace_dump_call_end();
-
- trace_transfer_destroy(tr_trans);
-}
-
-
-static void *
-trace_screen_transfer_map(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_transfer *tr_trans = trace_transfer(_transfer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_transfer *transfer = tr_trans->transfer;
- void *map;
-
- map = screen->transfer_map(screen, transfer);
- if(map) {
- if(transfer->usage & PIPE_TRANSFER_WRITE) {
- assert(!tr_trans->map);
- tr_trans->map = map;
- }
- }
-
- return map;
-}
-
-
-static void
-trace_screen_transfer_unmap(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_transfer *tr_trans = trace_transfer(_transfer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_transfer *transfer = tr_trans->transfer;
-
- if(tr_trans->map) {
- size_t size = util_format_get_nblocksy(transfer->texture->format, transfer->height) * transfer->stride;
-
- trace_dump_call_begin("pipe_screen", "transfer_write");
-
- trace_dump_arg(ptr, screen);
-
- trace_dump_arg(ptr, transfer);
-
- trace_dump_arg_begin("stride");
- trace_dump_uint(transfer->stride);
- trace_dump_arg_end();
-
- trace_dump_arg_begin("data");
- trace_dump_bytes(tr_trans->map, size);
- trace_dump_arg_end();
-
- trace_dump_arg_begin("size");
- trace_dump_uint(size);
- trace_dump_arg_end();
-
- trace_dump_call_end();
-
- tr_trans->map = NULL;
- }
-
- screen->transfer_unmap(screen, transfer);
-}
/********************************************************************
@@ -484,45 +361,7 @@ trace_screen_transfer_unmap(struct pipe_screen *_screen,
*/
-static struct pipe_buffer *
-trace_screen_surface_buffer_create(struct pipe_screen *_screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *pstride)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct pipe_screen *screen = tr_scr->screen;
- unsigned stride;
- struct pipe_buffer *result;
-
- trace_dump_call_begin("pipe_screen", "surface_buffer_create");
-
- trace_dump_arg(ptr, screen);
- trace_dump_arg(uint, width);
- trace_dump_arg(uint, height);
- trace_dump_arg(format, format);
- trace_dump_arg(uint, usage);
- trace_dump_arg(uint, tex_usage);
-
- result = screen->surface_buffer_create(screen,
- width, height,
- format,
- usage,
- tex_usage,
- pstride);
-
- stride = *pstride;
-
- trace_dump_arg(uint, stride);
-
- trace_dump_ret(ptr, result);
-
- trace_dump_call_end();
- return trace_buffer_create(tr_scr, result);
-}
static struct pipe_buffer *
@@ -931,17 +770,13 @@ trace_screen_create(struct pipe_screen *screen)
assert(screen->context_create);
tr_scr->base.context_create = trace_screen_context_create;
tr_scr->base.texture_create = trace_screen_texture_create;
- tr_scr->base.texture_blanket = trace_screen_texture_blanket;
+ tr_scr->base.texture_from_handle = trace_screen_texture_from_handle;
+ tr_scr->base.texture_get_handle = trace_screen_texture_get_handle;
tr_scr->base.texture_destroy = trace_screen_texture_destroy;
tr_scr->base.get_tex_surface = trace_screen_get_tex_surface;
tr_scr->base.tex_surface_destroy = trace_screen_tex_surface_destroy;
- tr_scr->base.get_tex_transfer = trace_screen_get_tex_transfer;
- tr_scr->base.tex_transfer_destroy = trace_screen_tex_transfer_destroy;
- tr_scr->base.transfer_map = trace_screen_transfer_map;
- tr_scr->base.transfer_unmap = trace_screen_transfer_unmap;
tr_scr->base.buffer_create = trace_screen_buffer_create;
tr_scr->base.user_buffer_create = trace_screen_user_buffer_create;
- tr_scr->base.surface_buffer_create = trace_screen_surface_buffer_create;
if (screen->buffer_map)
tr_scr->base.buffer_map = trace_screen_buffer_map;
if (screen->buffer_map_range)
@@ -955,7 +790,11 @@ trace_screen_create(struct pipe_screen *screen)
tr_scr->base.fence_signalled = trace_screen_fence_signalled;
tr_scr->base.fence_finish = trace_screen_fence_finish;
tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer;
+
tr_scr->screen = screen;
+ tr_scr->private_context = screen->context_create(screen, NULL);
+ if (tr_scr->private_context == NULL)
+ goto error3;
trace_dump_ret(ptr, screen);
trace_dump_call_end();
@@ -965,10 +804,8 @@ trace_screen_create(struct pipe_screen *screen)
return &tr_scr->base;
-#if 0
error3:
FREE(tr_scr);
-#endif
error2:
trace_dump_ret(ptr, screen);
trace_dump_call_end();
diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h
index fe5a0fa190..9bfbe72e2c 100644
--- a/src/gallium/drivers/trace/tr_screen.h
+++ b/src/gallium/drivers/trace/tr_screen.h
@@ -56,6 +56,7 @@ struct trace_screen
struct pipe_screen base;
struct pipe_screen *screen;
+ struct pipe_context *private_context;
/* remote debugger */
struct trace_rbug *rbug;
@@ -99,9 +100,6 @@ trace_enabled(void);
struct trace_screen *
trace_screen(struct pipe_screen *screen);
-struct pipe_screen *
-trace_screen_create(struct pipe_screen *screen);
-
void
trace_screen_user_buffer_update(struct pipe_screen *screen,
struct pipe_buffer *buffer);
diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c
index 5321d68ec0..d818e21bb8 100644
--- a/src/gallium/drivers/trace/tr_texture.c
+++ b/src/gallium/drivers/trace/tr_texture.c
@@ -31,6 +31,7 @@
#include "util/u_simple_list.h"
#include "tr_screen.h"
+#include "tr_context.h"
#include "tr_texture.h"
@@ -124,8 +125,9 @@ trace_surface_destroy(struct trace_surface *tr_surf)
struct pipe_transfer *
-trace_transfer_create(struct trace_texture *tr_tex,
- struct pipe_transfer *transfer)
+trace_transfer_create(struct trace_context *tr_ctx,
+ struct trace_texture *tr_tex,
+ struct pipe_transfer *transfer)
{
struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
struct trace_transfer *tr_trans;
@@ -142,8 +144,9 @@ trace_transfer_create(struct trace_texture *tr_tex,
memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer));
tr_trans->base.texture = NULL;
- pipe_texture_reference(&tr_trans->base.texture, &tr_tex->base);
tr_trans->transfer = transfer;
+
+ pipe_texture_reference(&tr_trans->base.texture, &tr_tex->base);
assert(tr_trans->base.texture == &tr_tex->base);
trace_screen_add_to_list(tr_scr, transfers, tr_trans);
@@ -151,21 +154,23 @@ trace_transfer_create(struct trace_texture *tr_tex,
return &tr_trans->base;
error:
- transfer->texture->screen->tex_transfer_destroy(transfer);
+ tr_ctx->pipe->tex_transfer_destroy(tr_ctx->pipe, transfer);
return NULL;
}
void
-trace_transfer_destroy(struct trace_transfer *tr_trans)
+trace_transfer_destroy(struct trace_context *tr_context,
+ struct trace_transfer *tr_trans)
{
- struct trace_screen *tr_scr = trace_screen(tr_trans->base.texture->screen);
- struct pipe_screen *screen = tr_trans->transfer->texture->screen;
+ struct trace_screen *tr_scr = trace_screen(tr_context->base.screen);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
trace_screen_remove_from_list(tr_scr, transfers, tr_trans);
pipe_texture_reference(&tr_trans->base.texture, NULL);
- screen->tex_transfer_destroy(tr_trans->transfer);
+ context->tex_transfer_destroy(context, transfer);
FREE(tr_trans);
}
diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h
index 395e523e73..4dc95308a7 100644
--- a/src/gallium/drivers/trace/tr_texture.h
+++ b/src/gallium/drivers/trace/tr_texture.h
@@ -34,6 +34,7 @@
#include "tr_screen.h"
+struct trace_context;
struct trace_texture
{
@@ -60,6 +61,7 @@ struct trace_transfer
struct pipe_transfer base;
struct pipe_transfer *transfer;
+ struct pipe_context *pipe;
struct tr_list list;
@@ -112,11 +114,13 @@ void
trace_surface_destroy(struct trace_surface *tr_surf);
struct pipe_transfer *
-trace_transfer_create(struct trace_texture *tr_tex,
- struct pipe_transfer *transfer);
+trace_transfer_create(struct trace_context *tr_ctx,
+ struct trace_texture *tr_tex,
+ struct pipe_transfer *transfer);
void
-trace_transfer_destroy(struct trace_transfer *tr_trans);
+trace_transfer_destroy(struct trace_context *tr_ctx,
+ struct trace_transfer *tr_trans);
#endif /* TR_TEXTURE_H_ */