summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/glx/Makefile4
-rw-r--r--src/egl/main/Makefile2
-rw-r--r--src/gallium/auxiliary/Makefile1
-rw-r--r--src/gallium/auxiliary/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c73
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h12
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c23
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c50
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aapoint.c39
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_line.c34
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_point.c36
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h16
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_pack.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h5
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c22
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c6
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c4
-rw-r--r--src/gallium/auxiliary/util/u_blit.c1
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c8
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h16
-rw-r--r--src/gallium/auxiliary/util/u_dirty_surfaces.h88
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h23
-rw-r--r--src/gallium/auxiliary/util/u_surfaces.c112
-rw-r--r--src/gallium/auxiliary/util/u_surfaces.h54
-rw-r--r--src/gallium/drivers/i915/i915_context.c2
-rw-r--r--src/gallium/drivers/i915/i915_resource_buffer.c1
-rw-r--r--src/gallium/drivers/i915/i915_state.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_rasterizer.c14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c307
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h30
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h3
-rw-r--r--src/gallium/drivers/nvfx/nv04_surface_2d.c8
-rw-r--r--src/gallium/drivers/nvfx/nv04_surface_2d.h4
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragprog.c18
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragtex.c7
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_emit.c3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c25
-rw-r--r--src/gallium/drivers/r300/r300_blit.c3
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c3
-rw-r--r--src/gallium/drivers/r300/r300_chipset.h20
-rw-r--r--src/gallium/drivers/r300/r300_context.c2
-rw-r--r--src/gallium/drivers/r300/r300_query.c2
-rw-r--r--src/gallium/drivers/r300/r300_render.c6
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c19
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h6
-rw-r--r--src/gallium/drivers/r300/r300_state.c17
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c13
-rw-r--r--src/gallium/drivers/r300/r300_texture.c6
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c4
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h10
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h5
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_pipe.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c120
-rw-r--r--src/gallium/drivers/softpipe/sp_state_rasterizer.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_rasterizer.c3
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c2
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c3
-rw-r--r--src/gallium/include/pipe/p_compiler.h40
-rw-r--r--src/gallium/state_trackers/egl/Makefile1
-rw-r--r--src/gallium/targets/libgl-xlib/Makefile3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c20
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c5
-rw-r--r--src/glx/dri2_glx.c13
-rw-r--r--src/mesa/drivers/dri/common/xmlconfig.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/Makefile1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/memory_pool.h31
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c61
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c43
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c19
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c89
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h6
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c15
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c331
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h30
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c7
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h3
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c76
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c53
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_chipset.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c1
-rw-r--r--src/mesa/drivers/dri/savage/savage_xmesa.c5
-rw-r--r--src/mesa/glapi/gen/GL3.xml581
-rw-r--r--src/mesa/main/imports.c3
-rw-r--r--src/mesa/main/imports.h6
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c2
-rw-r--r--src/mesa/state_tracker/st_atom_scissor.c13
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c3
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c4
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c6
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c4
-rw-r--r--src/mesa/state_tracker/st_cb_eglimage.c1
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c11
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h2
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c7
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c2
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c6
-rw-r--r--src/mesa/state_tracker/st_manager.c1
-rw-r--r--src/mesa/state_tracker/st_texture.h18
-rw-r--r--src/mesa/vbo/vbo_exec_api.c5
120 files changed, 2332 insertions, 608 deletions
diff --git a/src/egl/drivers/glx/Makefile b/src/egl/drivers/glx/Makefile
index 634638f538..d976b91a74 100644
--- a/src/egl/drivers/glx/Makefile
+++ b/src/egl/drivers/glx/Makefile
@@ -10,7 +10,7 @@ EGL_INCLUDES = \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
-EGL_CFLAGS =
-EGL_LIBS = -lX11 -lGL
+EGL_CFLAGS = $(X11_CFLAGS)
+EGL_LIBS = $(X11_LIBS) -lGL
include ../Makefile.template
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 31f214cf6f..3b4ebf7fec 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -7,7 +7,7 @@ include $(TOP)/configs/current
EGL_MAJOR = 1
EGL_MINOR = 0
-INCLUDE_DIRS = -I$(TOP)/include
+INCLUDE_DIRS = -I$(TOP)/include $(X11_CFLAGS)
HEADERS = \
eglcompiler.h \
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index c672f32b7b..38ce14df6b 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -129,6 +129,7 @@ C_SOURCES = \
util/u_simple_shaders.c \
util/u_snprintf.c \
util/u_surface.c \
+ util/u_surfaces.c \
util/u_texture.c \
util/u_tile.c \
util/u_transfer.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index 42f2cffc81..a9ec5d4e2c 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -178,6 +178,7 @@ source = [
'util/u_simple_shaders.c',
'util/u_snprintf.c',
'util/u_surface.c',
+ 'util/u_surfaces.c',
'util/u_texture.c',
'util/u_tile.c',
'util/u_transfer.c',
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index b6c558ba9b..4196f01e0b 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -31,22 +31,33 @@
*/
+#include "pipe/p_context.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "draw_context.h"
#include "draw_vs.h"
#include "draw_gs.h"
+#if HAVE_LLVM
+#include "gallivm/lp_bld_init.h"
+#endif
-struct draw_context *draw_create( void )
+struct draw_context *draw_create( struct pipe_context *pipe )
{
struct draw_context *draw = CALLOC_STRUCT( draw_context );
if (draw == NULL)
goto fail;
+#if HAVE_LLVM
+ assert(lp_build_engine);
+ draw->engine = lp_build_engine;
+#endif
+
if (!draw_init(draw))
goto fail;
+ draw->pipe = pipe;
+
return draw;
fail:
@@ -92,10 +103,23 @@ boolean draw_init(struct draw_context *draw)
void draw_destroy( struct draw_context *draw )
{
+ struct pipe_context *pipe;
+ int i, j;
+
if (!draw)
return;
+ pipe = draw->pipe;
+ /* free any rasterizer CSOs that we may have created.
+ */
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ if (draw->rasterizer_no_cull[i][j]) {
+ pipe->delete_rasterizer_state(pipe, draw->rasterizer_no_cull[i][j]);
+ }
+ }
+ }
/* Not so fast -- we're just borrowing this at the moment.
*
@@ -137,12 +161,17 @@ void draw_set_mrd(struct draw_context *draw, double mrd)
* This causes the drawing pipeline to be rebuilt.
*/
void draw_set_rasterizer_state( struct draw_context *draw,
- const struct pipe_rasterizer_state *raster )
+ const struct pipe_rasterizer_state *raster,
+ void *rast_handle )
{
- draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+ if (!draw->suspend_flushing) {
+ draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
- draw->rasterizer = raster;
- draw->bypass_clipping = draw->driver.bypass_clipping;
+ draw->rasterizer = raster;
+ draw->rast_handle = rast_handle;
+
+ draw->bypass_clipping = draw->driver.bypass_clipping;
+ }
}
@@ -499,3 +528,37 @@ draw_current_shader_position_output(const struct draw_context *draw)
return draw->gs.position_output;
return draw->vs.position_output;
}
+
+
+/**
+ * Return a pointer/handle for a driver/CSO rasterizer object which
+ * disabled culling, stippling, unfilled tris, etc.
+ * This is used by some pipeline stages (such as wide_point, aa_line
+ * and aa_point) which convert points/lines into triangles. In those
+ * cases we don't want to accidentally cull the triangles.
+ *
+ * \param scissor should the rasterizer state enable scissoring?
+ * \param flatshade should the rasterizer state use flat shading?
+ * \return rasterizer CSO handle
+ */
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+ boolean scissor,
+ boolean flatshade )
+{
+ if (!draw->rasterizer_no_cull[scissor][flatshade]) {
+ /* create now */
+ struct pipe_context *pipe = draw->pipe;
+ struct pipe_rasterizer_state rast;
+
+ memset(&rast, 0, sizeof(rast));
+ rast.scissor = scissor;
+ rast.flatshade = flatshade;
+ rast.front_winding = PIPE_WINDING_CCW;
+ rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules;
+
+ draw->rasterizer_no_cull[scissor][flatshade] =
+ pipe->create_rasterizer_state(pipe, &rast);
+ }
+ return draw->rasterizer_no_cull[scissor][flatshade];
+}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index cfa0ad88d0..7b41bb48dd 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -48,7 +48,7 @@ struct draw_geometry_shader;
struct tgsi_sampler;
-struct draw_context *draw_create( void );
+struct draw_context *draw_create( struct pipe_context *pipe );
void draw_destroy( struct draw_context *draw );
@@ -59,7 +59,8 @@ void draw_set_clip_state( struct draw_context *pipe,
const struct pipe_clip_state *clip );
void draw_set_rasterizer_state( struct draw_context *draw,
- const struct pipe_rasterizer_state *raster );
+ const struct pipe_rasterizer_state *raster,
+ void *rast_handle );
void draw_set_rasterize_stage( struct draw_context *draw,
struct draw_stage *stage );
@@ -198,11 +199,4 @@ boolean draw_need_pipeline(const struct draw_context *draw,
const struct pipe_rasterizer_state *rasterizer,
unsigned prim );
-#ifdef HAVE_LLVM
-/*******************************************************************************
- * LLVM integration
- */
-struct draw_context *draw_create_with_llvm(void);
-#endif
-
#endif /* DRAW_CONTEXT_H */
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index a5403a49c3..9d11031769 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -10,7 +10,6 @@
#include "gallivm/lp_bld_debug.h"
#include "gallivm/lp_bld_tgsi.h"
#include "gallivm/lp_bld_printf.h"
-#include "gallivm/lp_bld_init.h"
#include "tgsi/tgsi_exec.h"
@@ -196,7 +195,7 @@ draw_llvm_create(struct draw_context *draw)
init_globals(llvm);
-#if 1
+#if 0
LLVMDumpModule(llvm->module);
#endif
@@ -223,26 +222,6 @@ draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
return variant;
}
-
-struct draw_context *draw_create_with_llvm(void)
-{
- struct draw_context *draw = CALLOC_STRUCT( draw_context );
- if (draw == NULL)
- goto fail;
-
- assert(lp_build_engine);
- draw->engine = lp_build_engine;
-
- if (!draw_init(draw))
- goto fail;
-
- return draw;
-
-fail:
- draw_destroy( draw );
- return NULL;
-}
-
static void
generate_vs(struct draw_llvm *llvm,
LLVMBuilderRef builder,
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index e96dbecd26..4faf0a779c 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -113,11 +113,10 @@ struct aaline_stage
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
void **);
+
void (*driver_set_sampler_views)(struct pipe_context *,
unsigned,
struct pipe_sampler_view **);
-
- struct pipe_context *pipe;
};
@@ -342,6 +341,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
static boolean
generate_aaline_fs(struct aaline_stage *aaline)
{
+ struct pipe_context *pipe = aaline->stage.draw->pipe;
const struct pipe_shader_state *orig_fs = &aaline->fs->state;
struct pipe_shader_state aaline_fs;
struct aa_transform_context transform;
@@ -374,7 +374,7 @@ generate_aaline_fs(struct aaline_stage *aaline)
aaline->fs->sampler_unit = transform.freeSampler;
aaline->fs->aaline_fs
- = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
+ = aaline->driver_create_fs_state(pipe, &aaline_fs);
if (aaline->fs->aaline_fs == NULL)
goto fail;
@@ -394,7 +394,7 @@ fail:
static boolean
aaline_create_texture(struct aaline_stage *aaline)
{
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = aaline->stage.draw->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_resource texTemp;
struct pipe_sampler_view viewTempl;
@@ -486,7 +486,7 @@ static boolean
aaline_create_sampler(struct aaline_stage *aaline)
{
struct pipe_sampler_state sampler;
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = aaline->stage.draw->pipe;
memset(&sampler, 0, sizeof(sampler));
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -515,13 +515,14 @@ static boolean
bind_aaline_fragment_shader(struct aaline_stage *aaline)
{
struct draw_context *draw = aaline->stage.draw;
+ struct pipe_context *pipe = draw->pipe;
if (!aaline->fs->aaline_fs &&
!generate_aaline_fs(aaline))
return FALSE;
draw->suspend_flushing = TRUE;
- aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
+ aaline->driver_bind_fs_state(pipe, aaline->fs->aaline_fs);
draw->suspend_flushing = FALSE;
return TRUE;
@@ -661,8 +662,10 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
{
auto struct aaline_stage *aaline = aaline_stage(stage);
struct draw_context *draw = stage->draw;
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
uint num_samplers;
+ void *r;
assert(draw->rasterizer->line_smooth);
@@ -701,6 +704,11 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
draw->suspend_flushing = TRUE;
aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views);
+
+ /* Disable triangle culling, stippling, unfilled mode etc. */
+ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+ pipe->bind_rasterizer_state(pipe, r);
+
draw->suspend_flushing = FALSE;
/* now really draw first line */
@@ -714,7 +722,7 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
{
struct draw_context *draw = stage->draw;
struct aaline_stage *aaline = aaline_stage(stage);
- struct pipe_context *pipe = aaline->pipe;
+ struct pipe_context *pipe = draw->pipe;
stage->line = aaline_first_line;
stage->next->flush( stage->next, flags );
@@ -727,6 +735,12 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
aaline->driver_set_sampler_views(pipe,
aaline->num_sampler_views,
aaline->state.sampler_views);
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ }
+
draw->suspend_flushing = FALSE;
draw->extra_shader_outputs.slot = 0;
@@ -744,6 +758,7 @@ static void
aaline_destroy(struct draw_stage *stage)
{
struct aaline_stage *aaline = aaline_stage(stage);
+ struct pipe_context *pipe = stage->draw->pipe;
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
@@ -751,7 +766,7 @@ aaline_destroy(struct draw_stage *stage)
}
if (aaline->sampler_cso)
- aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
+ pipe->delete_sampler_state(pipe, aaline->sampler_cso);
if (aaline->texture)
pipe_resource_reference(&aaline->texture, NULL);
@@ -814,13 +829,14 @@ aaline_create_fs_state(struct pipe_context *pipe,
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
+
if (aafs == NULL)
return NULL;
aafs->state = *fs;
/* pass-through */
- aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
+ aafs->driver_fs = aaline->driver_create_fs_state(pipe, fs);
return aafs;
}
@@ -835,8 +851,7 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
/* save current */
aaline->fs = aafs;
/* pass-through */
- aaline->driver_bind_fs_state(aaline->pipe,
- (aafs ? aafs->driver_fs : NULL));
+ aaline->driver_bind_fs_state(pipe, (aafs ? aafs->driver_fs : NULL));
}
@@ -845,11 +860,12 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
+
/* pass-through */
- aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
+ aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
if (aafs->aaline_fs)
- aaline->driver_delete_fs_state(aaline->pipe, aafs->aaline_fs);
+ aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
FREE(aafs);
}
@@ -866,7 +882,7 @@ aaline_bind_sampler_states(struct pipe_context *pipe,
aaline->num_samplers = num;
/* pass-through */
- aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
+ aaline->driver_bind_sampler_states(pipe, num, sampler);
}
@@ -888,7 +904,7 @@ aaline_set_sampler_views(struct pipe_context *pipe,
aaline->num_sampler_views = num;
/* pass-through */
- aaline->driver_set_sampler_views(aaline->pipe, num, views);
+ aaline->driver_set_sampler_views(pipe, num, views);
}
@@ -911,8 +927,6 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
if (!aaline)
goto fail;
- aaline->pipe = pipe;
-
/* create special texture, sampler state */
if (!aaline_create_texture(aaline))
goto fail;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 9f9fb4312c..bba6f50c02 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -107,8 +107,6 @@ struct aapoint_stage
const struct pipe_shader_state *);
void (*driver_bind_fs_state)(struct pipe_context *, void *);
void (*driver_delete_fs_state)(struct pipe_context *, void *);
-
- struct pipe_context *pipe;
};
@@ -499,6 +497,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
struct pipe_shader_state aapoint_fs;
struct aa_transform_context transform;
const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS;
+ struct pipe_context *pipe = aapoint->stage.draw->pipe;
aapoint_fs = *orig_fs; /* copy to init */
aapoint_fs.tokens = tgsi_alloc_tokens(newLen);
@@ -527,7 +526,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
#endif
aapoint->fs->aapoint_fs
- = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
+ = aapoint->driver_create_fs_state(pipe, &aapoint_fs);
if (aapoint->fs->aapoint_fs == NULL)
goto fail;
@@ -549,13 +548,14 @@ static boolean
bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
{
struct draw_context *draw = aapoint->stage.draw;
+ struct pipe_context *pipe = draw->pipe;
if (!aapoint->fs->aapoint_fs &&
!generate_aapoint_fs(aapoint))
return FALSE;
draw->suspend_flushing = TRUE;
- aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
+ aapoint->driver_bind_fs_state(pipe, aapoint->fs->aapoint_fs);
draw->suspend_flushing = FALSE;
return TRUE;
@@ -679,6 +679,9 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
{
auto struct aapoint_stage *aapoint = aapoint_stage(stage);
struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
+ void *r;
assert(draw->rasterizer->point_smooth);
@@ -716,6 +719,14 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
}
}
+ draw->suspend_flushing = TRUE;
+
+ /* Disable triangle culling, stippling, unfilled mode etc. */
+ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+ pipe->bind_rasterizer_state(pipe, r);
+
+ draw->suspend_flushing = FALSE;
+
/* now really draw first point */
stage->point = aapoint_point;
stage->point(stage, header);
@@ -727,7 +738,7 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
{
struct draw_context *draw = stage->draw;
struct aapoint_stage *aapoint = aapoint_stage(stage);
- struct pipe_context *pipe = aapoint->pipe;
+ struct pipe_context *pipe = draw->pipe;
stage->point = aapoint_first_point;
stage->next->flush( stage->next, flags );
@@ -735,6 +746,12 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
/* restore original frag shader */
draw->suspend_flushing = TRUE;
aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ }
+
draw->suspend_flushing = FALSE;
draw->extra_shader_outputs.slot = 0;
@@ -811,7 +828,7 @@ aapoint_create_fs_state(struct pipe_context *pipe,
aafs->state = *fs;
/* pass-through */
- aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
+ aafs->driver_fs = aapoint->driver_create_fs_state(pipe, fs);
return aafs;
}
@@ -825,7 +842,7 @@ aapoint_bind_fs_state(struct pipe_context *pipe, void *fs)
/* save current */
aapoint->fs = aafs;
/* pass-through */
- aapoint->driver_bind_fs_state(aapoint->pipe,
+ aapoint->driver_bind_fs_state(pipe,
(aafs ? aafs->driver_fs : NULL));
}
@@ -837,10 +854,10 @@ aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
/* pass-through */
- aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
+ aapoint->driver_delete_fs_state(pipe, aafs->driver_fs);
if (aafs->aapoint_fs)
- aapoint->driver_delete_fs_state(aapoint->pipe, aafs->aapoint_fs);
+ aapoint->driver_delete_fs_state(pipe, aafs->aapoint_fs);
FREE(aafs);
}
@@ -857,8 +874,6 @@ draw_install_aapoint_stage(struct draw_context *draw,
{
struct aapoint_stage *aapoint;
- pipe->draw = (void *) draw;
-
/*
* Create / install AA point drawing / prim stage
*/
@@ -866,8 +881,6 @@ draw_install_aapoint_stage(struct draw_context *draw,
if (aapoint == NULL)
return FALSE;
- aapoint->pipe = pipe;
-
/* save original driver functions */
aapoint->driver_create_fs_state = pipe->create_fs_state;
aapoint->driver_bind_fs_state = pipe->bind_fs_state;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
index 3073c87082..265a420d01 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
@@ -28,6 +28,7 @@
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
*/
+#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
@@ -142,9 +143,40 @@ static void wideline_line( struct draw_stage *stage,
}
+static void wideline_first_line( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
+ void *r;
+
+ /* Disable triangle culling, stippling, unfilled mode etc. */
+ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+ draw->suspend_flushing = TRUE;
+ pipe->bind_rasterizer_state(pipe, r);
+ draw->suspend_flushing = FALSE;
+
+ stage->line = wideline_line;
+
+ wideline_line(stage, header);
+}
+
+
static void wideline_flush( struct draw_stage *stage, unsigned flags )
{
+ struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+
+ stage->line = wideline_first_line;
stage->next->flush( stage->next, flags );
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ draw->suspend_flushing = TRUE;
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ draw->suspend_flushing = FALSE;
+ }
}
@@ -171,7 +203,7 @@ struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
wide->stage.name = "wide-line";
wide->stage.next = NULL;
wide->stage.point = draw_pipe_passthrough_point;
- wide->stage.line = wideline_line;
+ wide->stage.line = wideline_first_line;
wide->stage.tri = draw_pipe_passthrough_tri;
wide->stage.flush = wideline_flush;
wide->stage.reset_stipple_counter = wideline_reset_stipple_counter;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 6864b4015b..30116f4925 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -52,6 +52,7 @@
*/
+#include "pipe/p_context.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "pipe/p_defines.h"
@@ -216,33 +217,42 @@ static void widepoint_first_point( struct draw_stage *stage,
{
struct widepoint_stage *wide = widepoint_stage(stage);
struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+ const struct pipe_rasterizer_state *rast = draw->rasterizer;
+ void *r;
- wide->half_point_size = 0.5f * draw->rasterizer->point_size;
+ wide->half_point_size = 0.5f * rast->point_size;
wide->xbias = 0.0;
wide->ybias = 0.0;
- if (draw->rasterizer->gl_rasterization_rules) {
+ if (rast->gl_rasterization_rules) {
wide->xbias = 0.125;
}
+ /* Disable triangle culling, stippling, unfilled mode etc. */
+ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+ draw->suspend_flushing = TRUE;
+ pipe->bind_rasterizer_state(pipe, r);
+ draw->suspend_flushing = FALSE;
+
/* XXX we won't know the real size if it's computed by the vertex shader! */
- if ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) ||
- (draw->rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)) {
+ if ((rast->point_size > draw->pipeline.wide_point_threshold) ||
+ (rast->sprite_coord_enable && draw->pipeline.point_sprite)) {
stage->point = widepoint_point;
}
else {
stage->point = draw_pipe_passthrough_point;
}
- if (draw->rasterizer->sprite_coord_enable) {
+ if (rast->sprite_coord_enable) {
/* find vertex shader texcoord outputs */
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
uint i, j = 0;
- wide->texcoord_mode = draw->rasterizer->sprite_coord_mode;
+ wide->texcoord_mode = rast->sprite_coord_mode;
for (i = 0; i < vs->info.num_outputs; i++) {
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
wide->texcoord_slot[j] = i;
- wide->texcoord_enable[j] = (draw->rasterizer->sprite_coord_enable >> j) & 1;
+ wide->texcoord_enable[j] = (rast->sprite_coord_enable >> j) & 1;
j++;
}
}
@@ -262,7 +272,7 @@ static void widepoint_first_point( struct draw_stage *stage,
}
wide->psize_slot = -1;
- if (draw->rasterizer->point_size_per_vertex) {
+ if (rast->point_size_per_vertex) {
/* find PSIZ vertex output */
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
uint i;
@@ -280,9 +290,19 @@ static void widepoint_first_point( struct draw_stage *stage,
static void widepoint_flush( struct draw_stage *stage, unsigned flags )
{
+ struct draw_context *draw = stage->draw;
+ struct pipe_context *pipe = draw->pipe;
+
stage->point = widepoint_first_point;
stage->next->flush( stage->next, flags );
stage->draw->extra_shader_outputs.slot = 0;
+
+ /* restore original rasterizer state */
+ if (draw->rast_handle) {
+ draw->suspend_flushing = TRUE;
+ pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+ draw->suspend_flushing = FALSE;
+ }
}
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 33b0c196d4..0b3c9e69bd 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -86,6 +86,8 @@ struct vertex_header {
*/
struct draw_context
{
+ struct pipe_context *pipe;
+
/** Drawing/primitive pipeline stages */
struct {
struct draw_stage *first; /**< one of the following */
@@ -179,8 +181,14 @@ struct draw_context
double mrd; /**< minimum resolvable depth value, for polygon offset */
- /* pipe state that we need: */
+ /** Current rasterizer state given to us by the driver */
const struct pipe_rasterizer_state *rasterizer;
+ /** Driver CSO handle for the current rasterizer state */
+ void *rast_handle;
+
+ /** Rasterizer CSOs without culling/stipple/etc */
+ void *rasterizer_no_cull[2][2];
+
struct pipe_viewport_state viewport;
boolean identity_viewport;
@@ -244,6 +252,7 @@ struct draw_context
#ifdef HAVE_LLVM
LLVMExecutionEngineRef engine;
+ boolean use_llvm;
#endif
void *driver_private;
};
@@ -357,5 +366,10 @@ void draw_do_flush( struct draw_context *draw, unsigned flags );
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+ boolean scissor,
+ boolean flatshade );
+
#endif /* DRAW_PRIVATE_H */
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index aa1f7064a3..b5876bb1bd 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -142,7 +142,9 @@ boolean draw_pt_init( struct draw_context *draw )
return FALSE;
#if HAVE_LLVM
- draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit_llvm( draw );
+ draw->use_llvm = debug_get_bool_option("DRAW_USE_LLVM", TRUE);
+ if (draw->use_llvm)
+ draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit_llvm( draw );
#else
draw->pt.middle.general = NULL;
#endif
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
index 2daa8a3b58..186f8849b8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
@@ -263,8 +263,6 @@ lp_build_pack2(LLVMBuilderRef builder,
LLVMValueRef shuffle;
LLVMValueRef res;
- dst_vec_type = lp_build_vec_type(dst_type);
-
assert(!src_type.floating);
assert(!dst_type.floating);
assert(src_type.width == dst_type.width * 2);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 8c1af95c50..e287376385 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -119,6 +119,11 @@ struct lp_sampler_dynamic_state
unsigned unit);
LLVMValueRef
+ (*img_stride)( struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder,
+ unsigned unit);
+
+ LLVMValueRef
(*data_ptr)( struct lp_sampler_dynamic_state *state,
LLVMBuilderRef builder,
unsigned unit);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 767429ba06..c9b613e21c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -1534,7 +1534,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
LLVMValueRef height_vec,
LLVMValueRef depth_vec,
LLVMValueRef row_stride_array,
- LLVMValueRef img_stride_vec,
+ LLVMValueRef img_stride_array,
LLVMValueRef data_array,
LLVMValueRef *colors_out)
{
@@ -1602,8 +1602,9 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
row_stride0_vec = lp_build_get_level_stride_vec(bld, row_stride_array,
ilevel0);
if (dims == 3 || bld->static_state->target == PIPE_TEXTURE_CUBE) {
- img_stride0_vec = lp_build_mul(&bld->int_coord_bld,
- row_stride0_vec, height0_vec);
+ img_stride0_vec = lp_build_get_level_stride_vec(bld,
+ img_stride_array,
+ ilevel0);
if (dims == 3) {
depth0_vec = lp_build_minify(bld, depth_vec, ilevel0_vec);
}
@@ -1617,8 +1618,9 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
row_stride1_vec = lp_build_get_level_stride_vec(bld, row_stride_array,
ilevel1);
if (dims == 3 || bld->static_state->target == PIPE_TEXTURE_CUBE) {
- img_stride1_vec = lp_build_mul(&bld->int_coord_bld,
- row_stride1_vec, height1_vec);
+ img_stride1_vec = lp_build_get_level_stride_vec(bld,
+ img_stride_array,
+ ilevel1);
if (dims ==3) {
depth1_vec = lp_build_minify(bld, depth_vec, ilevel1_vec);
}
@@ -2002,7 +2004,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
LLVMValueRef width, width_vec;
LLVMValueRef height, height_vec;
LLVMValueRef depth, depth_vec;
- LLVMValueRef stride_array;
+ LLVMValueRef row_stride_array, img_stride_array;
LLVMValueRef data_array;
LLVMValueRef s;
LLVMValueRef t;
@@ -2033,7 +2035,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
width = dynamic_state->width(dynamic_state, builder, unit);
height = dynamic_state->height(dynamic_state, builder, unit);
depth = dynamic_state->depth(dynamic_state, builder, unit);
- stride_array = dynamic_state->row_stride(dynamic_state, builder, unit);
+ row_stride_array = dynamic_state->row_stride(dynamic_state, builder, unit);
+ img_stride_array = dynamic_state->img_stride(dynamic_state, builder, unit);
data_array = dynamic_state->data_ptr(dynamic_state, builder, unit);
/* Note that data_array is an array[level] of pointers to texture images */
@@ -2054,13 +2057,14 @@ lp_build_sample_soa(LLVMBuilderRef builder,
is_simple_wrap_mode(static_state->wrap_t)) {
/* special case */
lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec,
- stride_array, data_array, texel);
+ row_stride_array, data_array, texel);
}
else {
lp_build_sample_general(&bld, unit, s, t, r,
width, height, depth,
width_vec, height_vec, depth_vec,
- stride_array, NULL, data_array,
+ row_stride_array, img_stride_array,
+ data_array,
texel);
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index f853ea2820..11045e4ba2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1796,6 +1796,12 @@ exec_declaration(struct tgsi_exec_machine *mach,
last = decl->Range.Last;
mask = decl->Declaration.UsageMask;
+ /* XXX we could remove this special-case code since
+ * mach->InterpCoefs[first].a0 should already have the
+ * front/back-face value. But we should first update the
+ * ureg code to emit the right UsageMask value (WRITEMASK_X).
+ * Then, we could remove the tgsi_exec_machine::Face field.
+ */
if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
uint i;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 3d0455de7c..f725405ade 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1158,7 +1158,7 @@ static void emit_decl_range( struct ureg_program *ureg,
out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
out[0].decl.NrTokens = 2;
out[0].decl.File = file;
- out[0].decl.UsageMask = 0xf;
+ out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
out[0].decl.Semantic = 0;
@@ -1180,7 +1180,7 @@ emit_decl_range2D(struct ureg_program *ureg,
out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
out[0].decl.NrTokens = 3;
out[0].decl.File = file;
- out[0].decl.UsageMask = 0xf;
+ out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
out[0].decl.Dimension = 1;
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 7850f81e58..e45310b9bb 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -374,6 +374,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
texTemp.width0 = srcW;
texTemp.height0 = srcH;
texTemp.depth0 = 1;
+ texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
tex = screen->resource_create(screen, &texTemp);
if (!tex)
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index f3b42f7bf9..956aedc8a1 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -132,6 +132,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
ctx->blitter.saved_num_sampler_views = ~0;
ctx->blitter.saved_num_sampler_states = ~0;
+ ctx->blitter.saved_num_vertex_buffers = ~0;
/* blend state objects */
memset(&blend, 0, sizeof(blend));
@@ -318,6 +319,13 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
ctx->blitter.saved_sampler_views);
ctx->blitter.saved_num_sampler_views = ~0;
}
+
+ if (ctx->blitter.saved_num_vertex_buffers != ~0) {
+ pipe->set_vertex_buffers(pipe,
+ ctx->blitter.saved_num_vertex_buffers,
+ ctx->blitter.saved_vertex_buffers);
+ ctx->blitter.saved_num_vertex_buffers = ~0;
+ }
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 2ad7201a29..f6e3ce4874 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -57,6 +57,9 @@ struct blitter_context
int saved_num_sampler_views;
struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
+
+ int saved_num_vertex_buffers;
+ struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS];
};
/**
@@ -255,6 +258,19 @@ util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
num_views * sizeof(struct pipe_sampler_view *));
}
+static INLINE void
+util_blitter_save_vertex_buffers(struct blitter_context *blitter,
+ int num_vertex_buffers,
+ struct pipe_vertex_buffer *vertex_buffers)
+{
+ assert(num_vertex_buffers <= Elements(blitter->saved_vertex_buffers));
+
+ blitter->saved_num_vertex_buffers = num_vertex_buffers;
+ memcpy(blitter->saved_vertex_buffers,
+ vertex_buffers,
+ num_vertex_buffers * sizeof(struct pipe_vertex_buffer));
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_dirty_surfaces.h b/src/gallium/auxiliary/util/u_dirty_surfaces.h
new file mode 100644
index 0000000000..99f260bf96
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_dirty_surfaces.h
@@ -0,0 +1,88 @@
+#ifndef U_DIRTY_SURFACES_H_
+#define U_DIRTY_SURFACES_H_
+
+#include "util/u_double_list.h"
+#include "util/u_math.h"
+
+typedef void (*util_dirty_surface_flush_t) (struct pipe_context *, struct pipe_surface *);
+
+struct util_dirty_surfaces
+{
+ struct list_head dirty_list;
+};
+
+struct util_dirty_surface
+{
+ struct pipe_surface base;
+ struct list_head dirty_list;
+};
+
+static INLINE void
+util_dirty_surfaces_init(struct util_dirty_surfaces *ds)
+{
+ LIST_INITHEAD(&ds->dirty_list);
+}
+
+static INLINE void
+util_dirty_surfaces_use_for_sampling(struct pipe_context *pipe, struct util_dirty_surfaces *dss, util_dirty_surface_flush_t flush)
+{
+ struct list_head *p, *next;
+ for(p = dss->dirty_list.next; p != &dss->dirty_list; p = next)
+ {
+ struct util_dirty_surface *ds = LIST_ENTRY(struct util_dirty_surface, p, dirty_list);
+ next = p->next;
+
+ flush(pipe, &ds->base);
+ }
+}
+
+static INLINE void
+util_dirty_surfaces_use_levels_for_sampling(struct pipe_context *pipe, struct util_dirty_surfaces *dss, unsigned first, unsigned last, util_dirty_surface_flush_t flush)
+{
+ struct list_head *p, *next;
+ if(first > last)
+ return;
+ for(p = dss->dirty_list.next; p != &dss->dirty_list; p = next)
+ {
+ struct util_dirty_surface *ds = LIST_ENTRY(struct util_dirty_surface, p, dirty_list);
+ next = p->next;
+
+ if(ds->base.level >= first && ds->base.level <= last)
+ flush(pipe, &ds->base);
+ }
+}
+
+static INLINE void
+util_dirty_surfaces_use_for_sampling_with(struct pipe_context *pipe, struct util_dirty_surfaces *dss, struct pipe_sampler_view *psv, struct pipe_sampler_state *pss, util_dirty_surface_flush_t flush)
+{
+ if(!LIST_IS_EMPTY(&dss->dirty_list))
+ util_dirty_surfaces_use_levels_for_sampling(pipe, dss, (unsigned)pss->min_lod + psv->first_level, MIN2((unsigned)ceilf(pss->max_lod) + psv->first_level, psv->last_level), flush);
+}
+
+static INLINE void
+util_dirty_surface_init(struct util_dirty_surface *ds)
+{
+ LIST_INITHEAD(&ds->dirty_list);
+}
+
+static INLINE boolean
+util_dirty_surface_is_dirty(struct util_dirty_surface *ds)
+{
+ return !LIST_IS_EMPTY(&ds->dirty_list);
+}
+
+static INLINE void
+util_dirty_surface_set_dirty(struct util_dirty_surfaces *dss, struct util_dirty_surface *ds)
+{
+ if(LIST_IS_EMPTY(&ds->dirty_list))
+ LIST_ADDTAIL(&ds->dirty_list, &dss->dirty_list);
+}
+
+static INLINE void
+util_dirty_surface_set_clean(struct util_dirty_surfaces *dss, struct util_dirty_surface *ds)
+{
+ if(!LIST_IS_EMPTY(&ds->dirty_list))
+ LIST_DELINIT(&ds->dirty_list);
+}
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index c2f4f05990..089adcf382 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -35,6 +35,7 @@
#include "util/u_debug.h"
#include "util/u_atomic.h"
#include "util/u_box.h"
+#include "util/u_math.h"
#ifdef __cplusplus
@@ -121,6 +122,28 @@ pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_
*ptr = view;
}
+static INLINE void
+pipe_surface_reset(struct pipe_surface* ps, struct pipe_resource *pt,
+ unsigned face, unsigned level, unsigned zslice, unsigned flags)
+{
+ pipe_resource_reference(&ps->texture, pt);
+ ps->format = pt->format;
+ ps->width = u_minify(pt->width0, level);
+ ps->height = u_minify(pt->height0, level);
+ ps->usage = flags;
+ ps->face = face;
+ ps->level = level;
+ ps->zslice = zslice;
+}
+
+static INLINE void
+pipe_surface_init(struct pipe_surface* ps, struct pipe_resource *pt,
+ unsigned face, unsigned level, unsigned zslice, unsigned flags)
+{
+ ps->texture = 0;
+ pipe_reference_init(&ps->reference, 1);
+ pipe_surface_reset(ps, pt, face, level, zslice, flags);
+}
/*
* Convenience wrappers for screen buffer functions.
diff --git a/src/gallium/auxiliary/util/u_surfaces.c b/src/gallium/auxiliary/util/u_surfaces.c
new file mode 100644
index 0000000000..0be4609a20
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_surfaces.c
@@ -0,0 +1,112 @@
+#include "u_surfaces.h"
+#include "util/u_hash_table.h"
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+
+/* TODO: ouch, util_hash_table should do these by default when passed a null function pointer
+ * this indirect function call is quite bad
+ */
+static unsigned
+hash(void *key)
+{
+ return (unsigned)key;
+}
+
+static int
+compare(void *key1, void *key2)
+{
+ return (unsigned)key1 - (unsigned)key2;
+}
+
+struct pipe_surface *
+util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags)
+{
+ struct pipe_surface *ps;
+ void *key = NULL;
+
+ if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
+ { /* or 2D array */
+ if(!us->u.table)
+ us->u.table = util_hash_table_create(hash, compare);
+ key = (void *)(((zslice + face) << 8) | level);
+ /* TODO: ouch, should have a get-reference function...
+ * also, shouldn't allocate a two-pointer structure for each item... */
+ ps = util_hash_table_get(us->u.table, key);
+ }
+ else
+ {
+ if(!us->u.array)
+ us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *));
+ ps = us->u.array[level];
+ }
+
+ if(ps)
+ {
+ p_atomic_inc(&ps->reference.count);
+ return ps;
+ }
+
+ ps = (struct pipe_surface *)CALLOC(1, surface_struct_size);
+ if(!ps)
+ return NULL;
+
+ pipe_surface_init(ps, pt, face, level, zslice, flags);
+ ps->offset = ~0;
+
+ if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
+ util_hash_table_set(us->u.table, key, ps);
+ else
+ us->u.array[level] = ps;
+
+ return ps;
+}
+
+void
+util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps)
+{
+ struct pipe_resource *pt = ps->texture;
+ if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
+ { /* or 2D array */
+ void* key = (void*)(((ps->zslice + ps->face) << 8) | ps->level);
+ util_hash_table_remove(us->u.table, key);
+ }
+ else
+ us->u.array[ps->level] = 0;
+}
+
+static enum pipe_error
+util_surfaces_destroy_callback(void *key, void *value, void *data)
+{
+ void (*destroy_surface) (struct pipe_surface * ps) = data;
+ destroy_surface((struct pipe_surface *)value);
+ return PIPE_OK;
+}
+
+void
+util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *))
+{
+ if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)
+ { /* or 2D array */
+ if(us->u.table)
+ {
+ util_hash_table_foreach(us->u.table, util_surfaces_destroy_callback, destroy_surface);
+ util_hash_table_destroy(us->u.table);
+ us->u.table = NULL;
+ }
+ }
+ else
+ {
+ if(us->u.array)
+ {
+ unsigned i;
+ for(i = 0; i < pt->last_level; ++i)
+ {
+ struct pipe_surface *ps = us->u.array[i];
+ if(ps)
+ destroy_surface(ps);
+ }
+ free(us->u.array);
+ us->u.array = NULL;
+ }
+ }
+}
diff --git a/src/gallium/auxiliary/util/u_surfaces.h b/src/gallium/auxiliary/util/u_surfaces.h
new file mode 100644
index 0000000000..6de5e7cc17
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_surfaces.h
@@ -0,0 +1,54 @@
+#ifndef U_SURFACES_H_
+#define U_SURFACES_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "util/u_atomic.h"
+
+struct util_hash_table;
+
+struct util_surfaces
+{
+ union
+ {
+ struct util_hash_table *table;
+ struct pipe_surface **array;
+ } u;
+};
+
+struct pipe_surface *util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags);
+
+/* fast inline path for the very common case */
+static INLINE struct pipe_surface *
+util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags)
+{
+ if(likely(pt->target == PIPE_TEXTURE_2D && us->u.array))
+ {
+ struct pipe_surface *ps = us->u.array[level];
+ if(ps)
+ {
+ p_atomic_inc(&ps->reference.count);
+ return ps;
+ }
+ }
+
+ return util_surfaces_do_get(us, surface_struct_size, pscreen, pt, face, level, zslice, flags);
+}
+
+void util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps);
+
+static INLINE void
+util_surfaces_detach(struct util_surfaces *us, struct pipe_surface *ps)
+{
+ if(likely(ps->texture->target == PIPE_TEXTURE_2D))
+ {
+ us->u.array[ps->level] = 0;
+ return;
+ }
+
+ return util_surfaces_do_detach(us, ps);
+}
+
+void util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *));
+
+#endif
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index beddc13996..2af9bdac95 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -175,7 +175,7 @@ i915_create_context(struct pipe_screen *screen, void *priv)
/*
* Create drawing context and plug our rendering stage into it.
*/
- i915->draw = draw_create();
+ i915->draw = draw_create(&i915->base);
assert(i915->draw);
if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c
index d2f8afeee7..0744cc926a 100644
--- a/src/gallium/drivers/i915/i915_resource_buffer.c
+++ b/src/gallium/drivers/i915/i915_resource_buffer.c
@@ -33,7 +33,6 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
-#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 397647204b..f883883852 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -737,7 +737,8 @@ static void i915_bind_rasterizer_state( struct pipe_context *pipe,
/* pass-through to draw module */
draw_set_rasterizer_state(i915->draw,
- (i915->rasterizer ? i915->rasterizer->templ : NULL));
+ (i915->rasterizer ? i915->rasterizer->templ : NULL),
+ raster);
i915->dirty |= I915_NEW_RASTERIZER;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index 868e112ba3..f7cf06d8d4 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -45,10 +45,6 @@
#include "lp_query.h"
#include "lp_setup.h"
-
-#define USE_DRAW_LLVM 0
-
-
static void llvmpipe_destroy( struct pipe_context *pipe )
{
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
@@ -162,11 +158,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
/*
* Create drawing context and plug our rendering stage into it.
*/
-#if USE_DRAW_LLVM
- llvmpipe->draw = draw_create_with_llvm();
-#else
- llvmpipe->draw = draw_create();
-#endif
+ llvmpipe->draw = draw_create(&llvmpipe->pipe);
if (!llvmpipe->draw)
goto fail;
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 7e8a117cc8..8690941a50 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -51,7 +51,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
/* struct lp_jit_texture */
{
- LLVMTypeRef elem_types[6];
+ LLVMTypeRef elem_types[LP_JIT_TEXTURE_NUM_FIELDS];
elem_types[LP_JIT_TEXTURE_WIDTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
@@ -59,6 +59,8 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
+ elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
+ LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
elem_types[LP_JIT_TEXTURE_DATA] =
LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
LP_MAX_TEXTURE_LEVELS);
@@ -80,6 +82,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
screen->target, texture_type,
LP_JIT_TEXTURE_ROW_STRIDE);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_IMG_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 3790a71eab..5d0268c68c 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -52,6 +52,7 @@ struct lp_jit_texture
uint32_t depth;
uint32_t last_level;
uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
+ uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
const void *data[LP_MAX_TEXTURE_LEVELS];
};
@@ -62,7 +63,9 @@ enum {
LP_JIT_TEXTURE_DEPTH,
LP_JIT_TEXTURE_LAST_LEVEL,
LP_JIT_TEXTURE_ROW_STRIDE,
- LP_JIT_TEXTURE_DATA
+ LP_JIT_TEXTURE_IMG_STRIDE,
+ LP_JIT_TEXTURE_DATA,
+ LP_JIT_TEXTURE_NUM_FIELDS /* number of fields above */
};
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 4574f41145..527103c75c 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -162,7 +162,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
assert(cbuf);
lpt = llvmpipe_resource(cbuf->texture);
task->color_tiles[buf] = llvmpipe_get_texture_tile(lpt,
- cbuf->face,
+ cbuf->face + cbuf->zslice,
cbuf->level,
usage,
x, y);
@@ -184,7 +184,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
* and update the tile's layout info.
*/
(void) llvmpipe_get_texture_tile(lpt,
- zsbuf->face,
+ zsbuf->face + zsbuf->zslice,
zsbuf->level,
usage,
x, y);
@@ -344,7 +344,7 @@ lp_rast_load_color(struct lp_rasterizer_task *task,
assert(cbuf);
lpt = llvmpipe_texture(cbuf->texture);
task->color_tiles[buf] = llvmpipe_get_texture_tile(lpt,
- cbuf->face,
+ cbuf->face + cbuf->zslice,
cbuf->level,
usage,
task->x, task->y);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index ffbc7fc4ea..6be13c60a5 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -526,15 +526,11 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
/* regular texture - setup array of mipmap level pointers */
int j;
for (j = 0; j <= tex->last_level; j++) {
-#if 0
jit_tex->data[j] =
- (ubyte *) lp_tex->data + lp_tex->level_offset[j];
-#else
- jit_tex->data[j] =
- llvmpipe_get_texture_image(lp_tex, 0, j, LP_TEX_USAGE_READ,
- LP_TEX_LAYOUT_LINEAR);
-#endif
- jit_tex->row_stride[j] = lp_tex->stride[j];
+ llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
+ LP_TEX_LAYOUT_LINEAR);
+ jit_tex->row_stride[j] = lp_tex->row_stride[j];
+ jit_tex->img_stride[j] = lp_tex->img_stride[j];
}
}
else {
@@ -547,7 +543,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
struct sw_winsys *winsys = screen->winsys;
jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
PIPE_TRANSFER_READ);
- jit_tex->row_stride[0] = lp_tex->stride[0];
+ jit_tex->row_stride[0] = lp_tex->row_stride[0];
+ jit_tex->img_stride[0] = lp_tex->img_stride[0];
assert(jit_tex->data[0]);
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 25e6b3edfb..a95053444b 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -601,6 +601,9 @@ do_triangle_ccw(struct lp_setup_context *setup,
}
+/**
+ * Draw triangle if it's CW, cull otherwise.
+ */
static void triangle_cw( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
@@ -610,6 +613,9 @@ static void triangle_cw( struct lp_setup_context *setup,
}
+/**
+ * Draw triangle if it's CCW, cull otherwise.
+ */
static void triangle_ccw( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
@@ -619,6 +625,10 @@ static void triangle_ccw( struct lp_setup_context *setup,
}
+
+/**
+ * Draw triangle whether it's CW or CCW.
+ */
static void triangle_both( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 6aa1e581bb..18f28289e3 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -37,7 +37,7 @@
* - early depth test
* - fragment shader
* - alpha test
- * - depth/stencil test (stencil TBI)
+ * - depth/stencil test
* - blending
*
* This file has only the glue to assemble the fragment pipeline. The actual
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index 6df3ef25b0..47f65fe72d 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -38,19 +38,26 @@ void *
llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rast)
{
+ /* We do nothing special with rasterizer state.
+ * The CSO handle is just a pointer to a pipe_rasterizer_state object.
+ */
return mem_dup(rast, sizeof(*rast));
}
-void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
- void *rasterizer)
+
+
+void
+llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ const struct pipe_rasterizer_state *rasterizer =
+ (const struct pipe_rasterizer_state *) handle;
if (llvmpipe->rasterizer == rasterizer)
return;
/* pass-through to draw module */
- draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
+ draw_set_rasterizer_state(llvmpipe->draw, rasterizer, handle);
llvmpipe->rasterizer = rasterizer;
@@ -69,6 +76,7 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
llvmpipe->dirty |= LP_NEW_RASTERIZER;
}
+
void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
void *rasterizer)
{
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 4fee40fd09..1a116989d4 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -135,10 +135,11 @@ lp_surface_copy(struct pipe_context *pipe,
LP_TEX_LAYOUT_LINEAR);
util_copy_rect(dst_linear_ptr, format,
- dst_tex->stride[dst->level],
+ llvmpipe_resource_stride(&dst_tex->base, dst->level),
dstx, dsty,
width, height,
- src_linear_ptr, src_tex->stride[src->level],
+ src_linear_ptr,
+ llvmpipe_resource_stride(&src_tex->base, src->level),
srcx, srcy);
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 4715cfe4f6..74b7393e4e 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -148,6 +148,7 @@ 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(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE)
LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
@@ -205,6 +206,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
+ sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_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 2267fcb29c..45739e94cb 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -72,16 +72,16 @@ resource_is_texture(const struct pipe_resource *resource)
* The number of elements is width_in_tiles * height_in_tiles.
*/
static enum lp_texture_layout *
-alloc_layout_array(unsigned width, unsigned height)
+alloc_layout_array(unsigned num_slices, unsigned width, unsigned height)
{
const unsigned tx = align(width, TILE_SIZE) / TILE_SIZE;
const unsigned ty = align(height, TILE_SIZE) / TILE_SIZE;
- assert(tx * ty > 0);
+ assert(num_slices * tx * ty > 0);
assert(LP_TEX_LAYOUT_NONE == 0); /* calloc'ing LP_TEX_LAYOUT_NONE here */
return (enum lp_texture_layout *)
- calloc(tx * ty, sizeof(enum lp_texture_layout));
+ calloc(num_slices * tx * ty, sizeof(enum lp_texture_layout));
}
@@ -98,30 +98,41 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
unsigned level;
unsigned width = pt->width0;
unsigned height = pt->height0;
+ unsigned depth = pt->depth0;
assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
for (level = 0; level <= pt->last_level; level++) {
- const unsigned num_faces = lpr->base.target == PIPE_TEXTURE_CUBE ? 6 : 1;
- unsigned nblocksx, face;
+ const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
+ const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
+ unsigned nblocksx, num_slices;
+
+ if (lpr->base.target == PIPE_TEXTURE_CUBE)
+ num_slices = 6;
+ else if (lpr->base.target == PIPE_TEXTURE_3D)
+ num_slices = depth;
+ else
+ num_slices = 1;
/* Allocate storage for whole quads. This is particularly important
* for depth surfaces, which are currently stored in a swizzled format.
*/
nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE));
- lpr->stride[level] =
+ lpr->row_stride[level] =
align(nblocksx * util_format_get_blocksize(pt->format), 16);
- lpr->tiles_per_row[level] = align(width, TILE_SIZE) / TILE_SIZE;
+ lpr->img_stride[level] = lpr->row_stride[level] * align(height, TILE_SIZE);
- for (face = 0; face < num_faces; face++) {
- lpr->layout[face][level] = alloc_layout_array(width, height);
- }
+ lpr->tiles_per_row[level] = width_t;
+ lpr->tiles_per_image[level] = width_t * height_t;
+ lpr->num_slices_faces[level] = num_slices;
+ lpr->layout[level] = alloc_layout_array(num_slices, width, height);
width = u_minify(width, 1);
height = u_minify(height, 1);
+ depth = u_minify(depth, 1);
}
return TRUE;
@@ -138,19 +149,24 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
/* Round up the surface size to a multiple of the tile size to
* avoid tile clipping.
*/
- unsigned width = align(lpr->base.width0, TILE_SIZE);
- unsigned height = align(lpr->base.height0, TILE_SIZE);
+ const unsigned width = align(lpr->base.width0, TILE_SIZE);
+ const unsigned height = align(lpr->base.height0, TILE_SIZE);
+ const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
+ const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
- lpr->tiles_per_row[0] = align(width, TILE_SIZE) / TILE_SIZE;
+ lpr->tiles_per_row[0] = width_t;
+ lpr->tiles_per_image[0] = width_t * height_t;
+ lpr->num_slices_faces[0] = 1;
+ lpr->img_stride[0] = 0;
- lpr->layout[0][0] = alloc_layout_array(width, height);
+ lpr->layout[0] = alloc_layout_array(1, width, height);
lpr->dt = winsys->displaytarget_create(winsys,
lpr->base.bind,
lpr->base.format,
width, height,
16,
- &lpr->stride[0] );
+ &lpr->row_stride[0] );
return lpr->dt != NULL;
}
@@ -178,14 +194,14 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
/* displayable surface */
if (!llvmpipe_displaytarget_layout(screen, lpr))
goto fail;
- assert(lpr->layout[0][0][0] == LP_TEX_LAYOUT_NONE);
+ assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
}
else if (lpr->base.bind & (PIPE_BIND_SAMPLER_VIEW |
PIPE_BIND_DEPTH_STENCIL)) {
/* texture map */
if (!llvmpipe_texture_layout(screen, lpr))
goto fail;
- assert(lpr->layout[0][0][0] == LP_TEX_LAYOUT_NONE);
+ assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
}
else {
/* other data (vertex buffer, const buffer, etc) */
@@ -201,7 +217,7 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
}
if (resource_is_texture(&lpr->base)) {
- assert(lpr->layout[0][0]);
+ assert(lpr->layout[0]);
}
lpr->id = id_counter++;
@@ -228,8 +244,7 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
}
else if (resource_is_texture(pt)) {
/* regular texture */
- const uint num_faces = pt->target == PIPE_TEXTURE_CUBE ? 6 : 1;
- uint level, face;
+ uint level;
/* free linear image data */
for (level = 0; level < Elements(lpr->linear); level++) {
@@ -249,10 +264,8 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
/* free layout flag arrays */
for (level = 0; level < Elements(lpr->tiled); level++) {
- for (face = 0; face < num_faces; face++) {
- free(lpr->layout[face][level]);
- lpr->layout[face][level] = NULL;
- }
+ free(lpr->layout[level]);
+ lpr->layout[level] = NULL;
}
}
else if (!lpr->userBuffer) {
@@ -312,36 +325,24 @@ llvmpipe_resource_map(struct pipe_resource *resource,
/* install this linear image in texture data structure */
lpr->linear[level].data = map;
- map = llvmpipe_get_texture_image(lpr, face, level, tex_usage, layout);
+ map = llvmpipe_get_texture_image(lpr, face + zslice, level,
+ tex_usage, layout);
assert(map);
return map;
}
else if (resource_is_texture(resource)) {
/* regular texture */
- const unsigned tex_height = u_minify(resource->height0, level);
- const unsigned nblocksy =
- util_format_get_nblocksy(resource->format, tex_height);
- const unsigned stride = lpr->stride[level];
- unsigned offset = 0;
-
- if (resource->target == PIPE_TEXTURE_CUBE) {
- /* XXX incorrect
- offset = face * nblocksy * stride;
- */
- }
- else if (resource->target == PIPE_TEXTURE_3D) {
- offset = zslice * nblocksy * stride;
- }
- else {
+ if (resource->target != PIPE_TEXTURE_CUBE) {
assert(face == 0);
+ }
+ if (resource->target != PIPE_TEXTURE_3D) {
assert(zslice == 0);
- offset = 0;
}
- map = llvmpipe_get_texture_image(lpr, face, level, tex_usage, layout);
+ map = llvmpipe_get_texture_image(lpr, face + zslice, level,
+ tex_usage, layout);
assert(map);
- map += offset;
return map;
}
else {
@@ -371,7 +372,7 @@ llvmpipe_resource_unmap(struct pipe_resource *resource,
assert(zslice == 0);
/* make sure linear image is up to date */
- (void) llvmpipe_get_texture_image(lpr, 0, 0,
+ (void) llvmpipe_get_texture_image(lpr, face + zslice, level,
LP_TEX_USAGE_READ,
LP_TEX_LAYOUT_LINEAR);
@@ -411,7 +412,7 @@ llvmpipe_resource_from_handle(struct pipe_screen *screen,
lpr->dt = winsys->displaytarget_from_handle(winsys,
template,
whandle,
- &lpr->stride[0]);
+ &lpr->row_stride[0]);
if (!lpr->dt)
goto fail;
@@ -498,7 +499,7 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
pipe_resource_reference(&pt->resource, resource);
pt->box = *box;
pt->sr = sr;
- pt->stride = lprex->stride[sr.level];
+ pt->stride = lprex->row_stride[sr.level];
pt->usage = usage;
return pt;
@@ -659,37 +660,49 @@ llvmpipe_user_buffer_create(struct pipe_screen *screen,
/**
* Compute size (in bytes) need to store a texture image / mipmap level,
- * for just one cube face.
+ * for just one cube face or one 3D texture slice
*/
static unsigned
tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
enum lp_texture_layout layout)
{
- /* for tiled layout, force a 32bpp format */
- enum pipe_format format = layout == LP_TEX_LAYOUT_TILED
- ? PIPE_FORMAT_B8G8R8A8_UNORM : lpr->base.format;
+ const unsigned width = u_minify(lpr->base.width0, level);
const unsigned height = u_minify(lpr->base.height0, level);
- const unsigned depth = u_minify(lpr->base.depth0, level);
- const unsigned nblocksy =
- util_format_get_nblocksy(format, align(height, TILE_SIZE));
- const unsigned buffer_size =
- nblocksy * lpr->stride[level] *
- (lpr->base.target == PIPE_TEXTURE_3D ? depth : 1);
- return buffer_size;
+
+ assert(layout == LP_TEX_LAYOUT_TILED ||
+ layout == LP_TEX_LAYOUT_LINEAR);
+
+ if (layout == LP_TEX_LAYOUT_TILED) {
+ /* for tiled layout, force a 32bpp format */
+ const enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ const unsigned block_size = util_format_get_blocksize(format);
+ const unsigned nblocksy =
+ util_format_get_nblocksy(format, align(height, TILE_SIZE));
+ const unsigned nblocksx =
+ util_format_get_nblocksx(format, align(width, TILE_SIZE));
+ const unsigned buffer_size = block_size * nblocksy * nblocksx;
+ return buffer_size;
+ }
+ else {
+ const enum pipe_format format = lpr->base.format;
+ const unsigned nblocksy =
+ util_format_get_nblocksy(format, align(height, TILE_SIZE));
+ const unsigned buffer_size = nblocksy * lpr->row_stride[level];
+ return buffer_size;
+ }
}
/**
* Compute size (in bytes) need to store a texture image / mipmap level,
- * including all cube faces.
+ * including all cube faces or 3D image slices
*/
static unsigned
tex_image_size(const struct llvmpipe_resource *lpr, unsigned level,
enum lp_texture_layout layout)
{
const unsigned buf_size = tex_image_face_size(lpr, level, layout);
- const unsigned num_faces = lpr->base.target == PIPE_TEXTURE_CUBE ? 6 : 1;
- return buf_size * num_faces;
+ return buf_size * lpr->num_slices_faces[level];
}
@@ -780,15 +793,64 @@ llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
}
+static INLINE enum lp_texture_layout
+llvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpr,
+ unsigned face_slice, unsigned level,
+ unsigned x, unsigned y)
+{
+ uint i;
+ assert(resource_is_texture(&lpr->base));
+ assert(x < lpr->tiles_per_row[level]);
+ i = face_slice * lpr->tiles_per_image[level]
+ + y * lpr->tiles_per_row[level] + x;
+ return lpr->layout[level][i];
+}
+
+
+static INLINE void
+llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr,
+ unsigned face_slice, unsigned level,
+ unsigned x, unsigned y,
+ enum lp_texture_layout layout)
+{
+ uint i;
+ assert(resource_is_texture(&lpr->base));
+ assert(x < lpr->tiles_per_row[level]);
+ i = face_slice * lpr->tiles_per_image[level]
+ + y * lpr->tiles_per_row[level] + x;
+ lpr->layout[level][i] = layout;
+}
+
+
+/**
+ * Set the layout mode for all tiles in a particular image.
+ */
+static INLINE void
+llvmpipe_set_texture_image_layout(struct llvmpipe_resource *lpr,
+ unsigned face_slice, unsigned level,
+ unsigned width_t, unsigned height_t,
+ enum lp_texture_layout layout)
+{
+ const unsigned start = face_slice * lpr->tiles_per_image[level];
+ unsigned i;
+
+ for (i = 0; i < width_t * height_t; i++) {
+ lpr->layout[level][start + i] = layout;
+ }
+}
+
/**
- * Return pointer to texture image data (either linear or tiled layout).
+ * Return pointer to texture image data (either linear or tiled layout)
+ * for a particular cube face or 3D texture slice.
+ *
+ * \param face_slice the cube face or 3D slice of interest
* \param usage one of LP_TEX_USAGE_READ/WRITE_ALL/READ_WRITE
- * \param layout either LP_TEX_LAYOUT_LINEAR or LP_TEX_LAYOUT_TILED
+ * \param layout either LP_TEX_LAYOUT_LINEAR or _TILED or _NONE
*/
void *
llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_usage usage,
enum lp_texture_layout layout)
{
@@ -807,6 +869,7 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
enum lp_texture_layout other_layout;
+ boolean only_allocate;
assert(layout == LP_TEX_LAYOUT_NONE ||
layout == LP_TEX_LAYOUT_TILED ||
@@ -816,6 +879,15 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
usage == LP_TEX_USAGE_READ_WRITE ||
usage == LP_TEX_USAGE_WRITE_ALL);
+ /* check for the special case of layout == LP_TEX_LAYOUT_NONE */
+ if (layout == LP_TEX_LAYOUT_NONE) {
+ only_allocate = TRUE;
+ layout = LP_TEX_LAYOUT_TILED;
+ }
+ else {
+ only_allocate = FALSE;
+ }
+
if (lpr->dt) {
assert(lpr->linear[level].data);
}
@@ -842,30 +914,39 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
target_data = target_img->data;
}
- if (face > 0) {
- unsigned offset = face * tex_image_face_size(lpr, level, layout);
+ if (face_slice > 0) {
+ unsigned target_offset, other_offset;
+
+ target_offset = face_slice * tex_image_face_size(lpr, level, layout);
+ other_offset = face_slice * tex_image_face_size(lpr, level, other_layout);
if (target_data) {
- target_data = (uint8_t *) target_data + offset;
+ target_data = (uint8_t *) target_data + target_offset;
}
if (other_data) {
- other_data = (uint8_t *) other_data + offset;
+ other_data = (uint8_t *) other_data + other_offset;
}
}
- if (layout == LP_TEX_LAYOUT_NONE) {
- /* just allocating memory */
+ if (only_allocate) {
+ /* Just allocating tiled memory. Don't initialize it from the
+ * linear data if it exists.
+ */
+ llvmpipe_set_texture_image_layout(lpr, face_slice, level,
+ width_t, height_t, layout);
+
return target_data;
}
if (other_data) {
/* may need to convert other data to the requested layout */
enum lp_texture_layout new_layout;
- unsigned x, y, i = 0;
+ unsigned x, y;
/* loop over all image tiles, doing layout conversion where needed */
for (y = 0; y < height_t; y++) {
for (x = 0; x < width_t; x++) {
- enum lp_texture_layout cur_layout = lpr->layout[face][level][i];
+ enum lp_texture_layout cur_layout =
+ llvmpipe_get_texture_tile_layout(lpr, face_slice, level, x, y);
boolean convert;
layout_logic(cur_layout, layout, usage, &new_layout, &convert);
@@ -876,28 +957,26 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
lpr->base.format,
- lpr->stride[level]);
+ lpr->row_stride[level]);
}
else {
lp_tiled_to_linear(other_data, target_data,
x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
lpr->base.format,
- lpr->stride[level]);
+ lpr->row_stride[level]);
}
}
- lpr->layout[face][level][i] = new_layout;
- i++;
+ llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y,
+ new_layout);
}
}
}
else {
/* no other data */
- unsigned i;
- for (i = 0; i < width_t * height_t; i++) {
- lpr->layout[face][level][i] = layout;
- }
+ llvmpipe_set_texture_image_layout(lpr, face_slice, level,
+ width_t, height_t, layout);
}
assert(target_data);
@@ -906,33 +985,33 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
}
-static INLINE enum lp_texture_layout
-llvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
- unsigned x, unsigned y)
+/**
+ * Return pointer to start of a texture image (1D, 2D, 3D, CUBE).
+ * All cube faces and 3D slices will be converted to the requested
+ * layout if needed.
+ * This is typically used when we're about to sample from a texture.
+ */
+void *
+llvmpipe_get_texture_image_all(struct llvmpipe_resource *lpr,
+ unsigned level,
+ enum lp_texture_usage usage,
+ enum lp_texture_layout layout)
{
- uint i;
- assert(resource_is_texture(&lpr->base));
- assert(x < lpr->tiles_per_row[level]);
- i = y * lpr->tiles_per_row[level] + x;
- return lpr->layout[face][level][i];
-}
+ const int slices = lpr->num_slices_faces[level];
+ int slice;
+ void *map;
+ assert(slices > 0);
-static INLINE void
-llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
- unsigned x, unsigned y,
- enum lp_texture_layout layout)
-{
- uint i;
- assert(resource_is_texture(&lpr->base));
- assert(x < lpr->tiles_per_row[level]);
- i = y * lpr->tiles_per_row[level] + x;
- lpr->layout[face][level][i] = layout;
+ for (slice = slices - 1; slice >= 0; slice--) {
+ map = llvmpipe_get_texture_image(lpr, slice, level, usage, layout);
+ }
+
+ return map;
}
+
/**
* Get pointer to a linear image where the tile at (x,y) is known to be
* in linear layout.
@@ -941,7 +1020,7 @@ llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr,
*/
ubyte *
llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_usage usage,
unsigned x, unsigned y)
{
@@ -961,7 +1040,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
linear_img->data = align_malloc(buffer_size, 16);
}
- cur_layout = llvmpipe_get_texture_tile_layout(lpr, face, level, tx, ty);
+ cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage,
&new_layout, &convert);
@@ -969,15 +1048,15 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
if (convert) {
lp_tiled_to_linear(tiled_img->data, linear_img->data,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
- lpr->stride[level]);
+ lpr->row_stride[level]);
}
if (new_layout != cur_layout)
- llvmpipe_set_texture_tile_layout(lpr, face, level, tx, ty, new_layout);
+ llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
- if (face > 0) {
+ if (face_slice > 0) {
unsigned offset
- = face * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
+ = face_slice * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
return (ubyte *) linear_img->data + offset;
}
else {
@@ -992,7 +1071,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
*/
ubyte *
llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_usage usage,
unsigned x, unsigned y)
{
@@ -1012,21 +1091,21 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
tiled_img->data = align_malloc(buffer_size, 16);
}
- cur_layout = llvmpipe_get_texture_tile_layout(lpr, face, level, tx, ty);
+ cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert);
if (convert) {
lp_linear_to_tiled(linear_img->data, tiled_img->data,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
- lpr->stride[level]);
+ lpr->row_stride[level]);
}
if (new_layout != cur_layout)
- llvmpipe_set_texture_tile_layout(lpr, face, level, tx, ty, new_layout);
+ llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
/* compute, return address of the 64x64 tile */
{
- unsigned tiles_per_row, tile_offset, face_offset;
+ unsigned tiles_per_row, tile_offset, face_slice_offset;
tiles_per_row = align(width, TILE_SIZE) / TILE_SIZE;
@@ -1037,11 +1116,11 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
assert(tiled_img->data);
- face_offset = (face > 0)
- ? (face * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_TILED))
+ face_slice_offset = (face_slice > 0)
+ ? (face_slice * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_TILED))
: 0;
- return (ubyte *) tiled_img->data + face_offset + tile_offset;
+ return (ubyte *) tiled_img->data + face_slice_offset + tile_offset;
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 134666db6f..5862f979da 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -92,8 +92,13 @@ struct llvmpipe_resource
struct pipe_resource base;
/** Row stride in bytes */
- unsigned stride[LP_MAX_TEXTURE_LEVELS];
+ unsigned row_stride[LP_MAX_TEXTURE_LEVELS];
+ /** Image stride (for cube maps or 3D textures) in bytes */
+ unsigned img_stride[LP_MAX_TEXTURE_LEVELS];
unsigned tiles_per_row[LP_MAX_TEXTURE_LEVELS];
+ unsigned tiles_per_image[LP_MAX_TEXTURE_LEVELS];
+ /** Number of 3D slices or cube faces per level */
+ unsigned num_slices_faces[LP_MAX_TEXTURE_LEVELS];
/**
* Display target, for textures with the PIPE_BIND_DISPLAY_TARGET
@@ -112,8 +117,8 @@ struct llvmpipe_resource
*/
void *data;
- /** per-tile layout info */
- enum lp_texture_layout *layout[PIPE_TEX_FACE_MAX][LP_MAX_TEXTURE_LEVELS];
+ /** array [level][face or slice][tile_y][tile_x] of layout values) */
+ enum lp_texture_layout *layout[LP_MAX_TEXTURE_LEVELS];
boolean userBuffer; /** Is this a user-space buffer? */
unsigned timestamp;
@@ -161,13 +166,13 @@ llvmpipe_resource_stride(struct pipe_resource *resource,
{
struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
assert(level < LP_MAX_TEXTURE_2D_LEVELS);
- return lpr->stride[level];
+ return lpr->row_stride[level];
}
void *
llvmpipe_resource_map(struct pipe_resource *resource,
- unsigned face,
+ unsigned face_slice,
unsigned level,
unsigned zslice,
enum lp_texture_usage tex_usage,
@@ -175,7 +180,7 @@ llvmpipe_resource_map(struct pipe_resource *resource,
void
llvmpipe_resource_unmap(struct pipe_resource *resource,
- unsigned face,
+ unsigned face_slice,
unsigned level,
unsigned zslice);
@@ -186,25 +191,30 @@ llvmpipe_resource_data(struct pipe_resource *resource);
void *
llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_layout layout);
void *
llvmpipe_get_texture_image(struct llvmpipe_resource *resource,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_usage usage,
enum lp_texture_layout layout);
+void *
+llvmpipe_get_texture_image_all(struct llvmpipe_resource *lpr,
+ unsigned level,
+ enum lp_texture_usage usage,
+ enum lp_texture_layout layout);
ubyte *
llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_usage usage,
unsigned x, unsigned y);
ubyte *
llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
- unsigned face, unsigned level,
+ unsigned face_slice, unsigned level,
enum lp_texture_usage usage,
unsigned x, unsigned y);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 747fd15acd..8eacdff035 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -1,6 +1,8 @@
#ifndef __NOUVEAU_SCREEN_H__
#define __NOUVEAU_SCREEN_H__
+#include "pipe/p_screen.h"
+
struct nouveau_screen {
struct pipe_screen base;
struct nouveau_device *device;
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index f543b3c504..915a925402 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -97,7 +97,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50_init_query_functions(nv50);
nv50_init_resource_functions(&nv50->pipe);
- nv50->draw = draw_create();
+ nv50->draw = draw_create(&nv50->pipe);
assert(nv50->draw);
draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 092333a3b1..40ebbee72e 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -2,7 +2,8 @@
#define __NV50_SCREEN_H__
#include "nouveau/nouveau_screen.h"
-#include "nv50_context.h"
+
+struct nv50_context;
struct nv50_screen {
struct nouveau_screen base;
diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.c b/src/gallium/drivers/nvfx/nv04_surface_2d.c
index a1507bbb3c..4ed574227d 100644
--- a/src/gallium/drivers/nvfx/nv04_surface_2d.c
+++ b/src/gallium/drivers/nvfx/nv04_surface_2d.c
@@ -497,6 +497,9 @@ struct nv04_surface*
nv04_surface_wrap_for_render(struct pipe_screen *pscreen,
struct nv04_surface_2d* eng2d, struct nv04_surface* ns)
{
+ struct pipe_resource templ;
+ struct pipe_resource* temp_tex;
+ struct nv04_surface* temp_ns;
int temp_flags;
temp_flags = (ns->base.usage |
@@ -506,7 +509,6 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen,
ns->base.usage = (PIPE_BIND_BLIT_SOURCE |
PIPE_BIND_BLIT_DESTINATION);
- struct pipe_resource templ;
memset(&templ, 0, sizeof(templ));
templ.format = ns->base.texture->format;
templ.target = PIPE_TEXTURE_2D;
@@ -520,8 +522,8 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen,
templ.bind = ns->base.texture->bind | PIPE_BIND_RENDER_TARGET;
- struct pipe_resource* temp_tex = pscreen->resource_create(pscreen, &templ);
- struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags);
+ temp_tex = pscreen->resource_create(pscreen, &templ);
+ temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags);
temp_ns->backing = ns;
if(ns->base.usage & PIPE_BIND_BLIT_SOURCE)
diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.h b/src/gallium/drivers/nvfx/nv04_surface_2d.h
index b2b237b9df..2123c3ed08 100644
--- a/src/gallium/drivers/nvfx/nv04_surface_2d.h
+++ b/src/gallium/drivers/nvfx/nv04_surface_2d.h
@@ -1,6 +1,10 @@
#ifndef __NV04_SURFACE_2D_H__
#define __NV04_SURFACE_2D_H__
+#include "pipe/p_state.h"
+
+struct nouveau_screen;
+
struct nv04_surface {
struct pipe_surface base;
unsigned pitch;
diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c
index 1faa0af31f..6d2dc4d5bf 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.c
+++ b/src/gallium/drivers/nvfx/nvfx_context.c
@@ -70,7 +70,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
nvfx_init_resource_functions(&nvfx->pipe);
/* Create, configure, and install fallback swtnl path */
- nvfx->draw = draw_create();
+ nvfx->draw = draw_create(&nvfx->pipe);
draw_wide_point_threshold(nvfx->draw, 9999999.0);
draw_wide_line_threshold(nvfx->draw, 9999999.0);
draw_enable_line_stipple(nvfx->draw, FALSE);
diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c
index aaa30bd60e..6772d9bd51 100644
--- a/src/gallium/drivers/nvfx/nvfx_fragprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c
@@ -846,6 +846,8 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
if (!fp->translated)
{
+ const int min_size = 4096;
+
nvfx_fragprog_translate(nvfx, fp);
if (!fp->translated) {
static unsigned dummy[8] = {1, 0, 0, 0, 1, 0, 0, 0};
@@ -866,7 +868,6 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
fp->prog_size = (fp->insn_len * 4 + 63) & ~63;
- int min_size = 4096;
if(fp->prog_size >= min_size)
fp->progs_per_bo = 1;
else
@@ -874,10 +875,15 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
fp->bo_prog_idx = fp->progs_per_bo - 1;
}
- if (nvfx->dirty & NVFX_NEW_FRAGCONST)
+ /* we must update constants even on "just" fragprog changes, because
+ we don't check whether the current constant buffer matches the latest
+ one bound to this fragment program */
+ if (nvfx->dirty & (NVFX_NEW_FRAGCONST | NVFX_NEW_FRAGPROG))
update = TRUE;
if(update) {
+ int offset;
+
++fp->bo_prog_idx;
if(fp->bo_prog_idx >= fp->progs_per_bo)
{
@@ -888,6 +894,8 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
else
{
struct nvfx_fragment_program_bo* fpbo = os_malloc_aligned(sizeof(struct nvfx_fragment_program) + fp->prog_size * fp->progs_per_bo, 16);
+ char *map, *buf;
+
if(fp->fpbo)
{
fpbo->next = fp->fpbo->next;
@@ -900,8 +908,8 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
nouveau_bo_new(nvfx->screen->base.device, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 64, fp->prog_size * fp->progs_per_bo, &fpbo->bo);
nouveau_bo_map(fpbo->bo, NOUVEAU_BO_NOSYNC);
- char* map = fpbo->bo->map;
- char* buf = fpbo->insn;
+ map = fpbo->bo->map;
+ buf = fpbo->insn;
for(int i = 0; i < fp->progs_per_bo; ++i)
{
memcpy(buf, fp->insn, fp->insn_len * 4);
@@ -913,7 +921,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
fp->bo_prog_idx = 0;
}
- int offset = fp->bo_prog_idx * fp->prog_size;
+ offset = fp->bo_prog_idx * fp->prog_size;
if(nvfx->constbuf[PIPE_SHADER_FRAGMENT]) {
struct pipe_resource* constbuf = nvfx->constbuf[PIPE_SHADER_FRAGMENT];
diff --git a/src/gallium/drivers/nvfx/nvfx_fragtex.c b/src/gallium/drivers/nvfx/nvfx_fragtex.c
index f5f6b0c0cb..0b4a434fec 100644
--- a/src/gallium/drivers/nvfx/nvfx_fragtex.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragtex.c
@@ -40,11 +40,14 @@ nvfx_fragtex_relocate(struct nvfx_context *nvfx)
samplers = nvfx->hw_samplers;
while (samplers) {
+ struct nvfx_miptree* mt;
+ struct nouveau_bo *bo;
+
unit = ffs(samplers) - 1;
samplers &= ~(1 << unit);
- struct nvfx_miptree* mt = (struct nvfx_miptree*)nvfx->fragment_sampler_views[unit]->texture;
- struct nouveau_bo *bo = mt->base.bo;
+ mt = (struct nvfx_miptree*)nvfx->fragment_sampler_views[unit]->texture;
+ bo = mt->base.bo;
MARK_RING(chan, 3, 3);
OUT_RELOC(chan, bo, RING_3D(NV34TCL_TX_OFFSET(unit), 2), tex_flags | NOUVEAU_BO_DUMMY, 0, 0);
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 04b456d408..9f03ab1833 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -316,6 +316,7 @@ nvfx_screen_get_vertex_buffer_flags(struct nvfx_screen* screen)
struct pipe_screen *
nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
+ static const unsigned query_sizes[] = {(4096 - 4 * 32) / 32, 3 * 1024 / 32, 2 * 1024 / 32, 1024 / 32};
struct nvfx_screen *screen = CALLOC_STRUCT(nvfx_screen);
struct nouveau_channel *chan;
struct pipe_screen *pscreen;
@@ -401,7 +402,6 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
}
/* Query objects */
- unsigned query_sizes[] = {(4096 - 4 * 32) / 32, 3 * 1024 / 32, 2 * 1024 / 32, 1024 / 32};
for(i = 0; i < sizeof(query_sizes) / sizeof(query_sizes[0]); ++i)
{
ret = nouveau_notifier_alloc(chan, 0xbeef0302, query_sizes[i], &screen->query);
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index 127d8919af..5e1c3945ae 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -4,7 +4,8 @@
#include "util/u_double_list.h"
#include "nouveau/nouveau_screen.h"
#include "nv04_surface_2d.h"
-#include "nvfx_context.h"
+
+struct nvfx_context;
struct nvfx_screen {
struct nouveau_screen base;
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
index 4137849bf0..f91ae19ecd 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_emit.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -159,7 +159,8 @@ nvfx_state_validate_swtnl(struct nvfx_context *nvfx)
draw_bind_vertex_shader(draw, nvfx->vertprog->draw);
if (nvfx->draw_dirty & NVFX_NEW_RAST)
- draw_set_rasterizer_state(draw, &nvfx->rasterizer->pipe);
+ draw_set_rasterizer_state(draw, &nvfx->rasterizer->pipe,
+ nvfx->rasterizer);
if (nvfx->draw_dirty & NVFX_NEW_UCP)
draw_set_clip_state(draw, &nvfx->clip);
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index d441d032d9..4d7b7f181d 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -122,11 +122,12 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx,
struct pipe_transfer *transfer;
struct nouveau_channel* chan = nvfx->screen->base.channel;
void *map;
+ float *v;
map = pipe_buffer_map(&nvfx->pipe, vb->buffer, PIPE_TRANSFER_READ, &transfer);
- map += vb->buffer_offset + ve->src_offset;
+ map = (uint8_t *) map + vb->buffer_offset + ve->src_offset;
- float *v = map;
+ v = map;
switch (ncomp) {
case 4:
@@ -173,11 +174,11 @@ nvfx_draw_arrays(struct pipe_context *pipe,
}
while (count) {
- unsigned vc, nr;
+ unsigned vc, nr, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 256,
@@ -229,11 +230,11 @@ nvfx_draw_elements_u08(struct nvfx_context *nvfx, void *ib,
while (count) {
uint8_t *elts = (uint8_t *)ib + start;
- unsigned vc, push, restart = 0;
+ unsigned vc, push, restart = 0, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 2,
@@ -282,11 +283,11 @@ nvfx_draw_elements_u16(struct nvfx_context *nvfx, void *ib,
while (count) {
uint16_t *elts = (uint16_t *)ib + start;
- unsigned vc, push, restart = 0;
+ unsigned vc, push, restart = 0, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 2,
@@ -335,11 +336,11 @@ nvfx_draw_elements_u32(struct nvfx_context *nvfx, void *ib,
while (count) {
uint32_t *elts = (uint32_t *)ib + start;
- unsigned vc, push, restart = 0;
+ unsigned vc, push, restart = 0, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 5, 1,
@@ -416,11 +417,11 @@ nvfx_draw_elements_vbo(struct pipe_context *pipe,
unsigned restart = 0;
while (count) {
- unsigned nr, vc;
+ unsigned nr, vc, avail;
nvfx_state_emit(nvfx);
- unsigned avail = AVAIL_RING(chan);
+ avail = AVAIL_RING(chan);
avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
vc = nouveau_vbuf_split(avail, 6, 256,
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index e84b79ae90..e15c71eef6 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -37,6 +37,9 @@ static void r300_blitter_save_states(struct r300_context* r300)
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);
+ /* XXX this crashes the driver
+ util_blitter_save_vertex_buffers(r300->blitter, r300->vertex_buffer_count,
+ r300->vertex_buffer); */
}
/* Clear currently bound buffers. */
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 9b2163e44c..928a310bd8 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -108,6 +108,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x3150:
case 0x3152:
case 0x3154:
+ case 0x3155:
case 0x3E50:
case 0x3E54:
caps->family = CHIP_FAMILY_RV380;
@@ -370,4 +371,6 @@ void r300_parse_chipset(struct r300_capabilities* caps)
fprintf(stderr, "r300: Warning: Unknown chipset 0x%x\n",
caps->pci_id);
}
+
+ caps->is_rv350 = caps->family >= CHIP_FAMILY_RV350;
}
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index ff957b7c29..ab649c3857 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -42,18 +42,28 @@ struct r300_capabilities {
unsigned num_tex_units;
/* Whether or not TCL is physically present */
boolean has_tcl;
- /* Whether or not this is R400. The differences compared to their R3xx
+ /* Whether or not this is RV350 or newer, including all r400 and r500
+ * chipsets. The differences compared to the oldest r300 chips are:
+ * - Blend LTE/GTE thresholds
+ * - Better MACRO_SWITCH in texture tiling
+ * - Half float vertex
+ * - More HyperZ optimizations */
+ boolean is_rv350;
+ /* Whether or not this is R400. The differences compared their rv350
* cousins are:
* - Extended fragment shader registers
- * - Blend LTE/GTE thresholds */
+ * - 3DC texture compression (RGTC2) */
boolean is_r400;
/* Whether or not this is an RV515 or newer; R500s have many differences
- * that require extra consideration, compared to their R3xx cousins:
+ * that require extra consideration, compared to their rv350 cousins:
* - Extra bit of width and height on texture sizes
* - Blend color is split across two registers
- * - Blend LTE/GTE thresholds
* - Universal Shader (US) block used for fragment shaders
- * - FP16 blending and multisampling */
+ * - FP16 blending and multisampling
+ * - Full RGTC texture compression
+ * - 24-bit depth textures
+ * - Stencil back-face reference value
+ * - Ability to render up to 2^24 - 1 vertices with signed index offset */
boolean is_r500;
/* Whether or not the second pixel pipe is accessed with the high bit */
boolean high_second_pipe;
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 503af3e78a..deaa03e1f6 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -186,7 +186,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
/* Create a Draw. This is used for SW TCL. */
- r300->draw = draw_create();
+ r300->draw = draw_create(&r300->context);
/* Enable our renderer. */
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
/* Enable Draw's clipping. */
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 398edb9d10..5c27796e89 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -25,10 +25,8 @@
#include "r300_context.h"
#include "r300_screen.h"
-#include "r300_cs.h"
#include "r300_emit.h"
#include "r300_query.h"
-#include "r300_reg.h"
#include <stdio.h>
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 007f01ace3..23b61df89c 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -152,9 +152,9 @@ static boolean immd_is_good_idea(struct r300_context *r300,
if (!checked[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
- if (r300->context.is_resource_referenced(&r300->context,
- vbuf->buffer,
- 0, 0)) {
+ if (r300_buffer_is_referenced(&r300->context,
+ vbuf->buffer,
+ R300_REF_CS | R300_REF_HW)) {
/* It's a very bad idea to map it... */
return FALSE;
}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index 739f723f16..20a9ffb9f6 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -26,7 +26,6 @@
#include <stdio.h>
#include "util/u_inlines.h"
-#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_upload_mgr.h"
#include "util/u_math.h"
@@ -34,9 +33,9 @@
#include "r300_screen_buffer.h"
#include "r300_winsys.h"
-static unsigned r300_buffer_is_referenced(struct pipe_context *context,
- struct pipe_resource *buf,
- unsigned face, unsigned level)
+unsigned r300_buffer_is_referenced(struct pipe_context *context,
+ struct pipe_resource *buf,
+ enum r300_reference_domain domain)
{
struct r300_context *r300 = r300_context(context);
struct r300_buffer *rbuf = r300_buffer(buf);
@@ -44,12 +43,19 @@ static unsigned r300_buffer_is_referenced(struct pipe_context *context,
if (r300_buffer_is_user_buffer(buf))
return PIPE_UNREFERENCED;
- if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf))
+ if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf, domain))
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
return PIPE_UNREFERENCED;
}
+static unsigned r300_buffer_is_referenced_by_cs(struct pipe_context *context,
+ struct pipe_resource *buf,
+ unsigned face, unsigned level)
+{
+ return r300_buffer_is_referenced(context, buf, R300_REF_CS);
+}
+
/* External helper, not required to implent u_resource_vtbl:
*/
int r300_upload_index_buffer(struct r300_context *r300,
@@ -174,7 +180,6 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
rws->buffer_reference(rws, &rbuf->buf, NULL);
rbuf->num_ranges = 0;
- rbuf->map = NULL;
rbuf->buf = r300_winsys_buffer_create(r300screen,
16,
rbuf->b.b.bind, /* XXX */
@@ -243,7 +248,7 @@ struct u_resource_vtbl r300_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
r300_buffer_destroy, /* resource_destroy */
- r300_buffer_is_referenced, /* is_buffer_referenced */
+ r300_buffer_is_referenced_by_cs, /* is_buffer_referenced */
u_default_get_transfer, /* get_transfer */
u_default_transfer_destroy, /* transfer_destroy */
r300_buffer_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
index 82660d3e1a..57f48229b2 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.h
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -55,8 +55,6 @@ struct r300_buffer
void *user_buffer;
struct r300_buffer_range ranges[R300_BUFFER_MAX_RANGES];
unsigned num_ranges;
-
- void *map;
};
/* Functions. */
@@ -77,6 +75,10 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
unsigned bytes,
unsigned usage);
+unsigned r300_buffer_is_referenced(struct pipe_context *context,
+ struct pipe_resource *buf,
+ enum r300_reference_domain domain);
+
/* Inline functions. */
static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 371e52d208..9eb8539a65 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -889,7 +889,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_rasterizer_state(r300->draw, &rs->rs);
+ draw_set_rasterizer_state(r300->draw, &rs->rs, state);
}
if (rs) {
@@ -1192,14 +1192,13 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
}
if (vbo->max_index == ~0) {
- /* Bogus value from broken state tracker; hax it. */
- /* TODO - more hax - fixes doom3 from almos on irc */
- if (!vbo->stride) {
- fprintf(stderr, "r300: got a VBO with stride 0 fixing up to stide 4\n");
- vbo->stride = 4;
- }
- vbo->max_index =
- (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
+ /* if no VBO stride then only one vertex value so max index is 1 */
+ /* should think about converting to VS constants like svga does */
+ if (!vbo->stride)
+ vbo->max_index = 1;
+ else
+ vbo->max_index =
+ (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
}
max_index = MIN2(vbo->max_index, max_index);
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index ffb175febf..64d1d18b45 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -41,10 +41,9 @@ struct pipe_viewport_state r300_viewport_identity = {
void r300_emit_invariant_state(struct r300_context* r300,
unsigned size, void* state)
{
- struct r300_capabilities* caps = &r300_screen(r300->context.screen)->caps;
CS_LOCALS(r300);
- BEGIN_CS(12 + (caps->has_tcl ? 2: 0));
+ BEGIN_CS(12 + (r300->screen->caps.has_tcl ? 2 : 0));
/*** Graphics Backend (GB) ***/
/* Subpixel multisampling for AA
@@ -66,7 +65,7 @@ void r300_emit_invariant_state(struct r300_context* r300,
/* Sign/normalize control */
OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
/* TCL-only stuff */
- if (caps->has_tcl) {
+ if (r300->screen->caps.has_tcl) {
/* Amount of time to wait for vertex fetches in PVS */
OUT_CS_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff);
}
@@ -74,10 +73,10 @@ void r300_emit_invariant_state(struct r300_context* r300,
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(38 + (caps->has_tcl ? 7 : 0) +
- (caps->family >= CHIP_FAMILY_RV350 ? 4 : 0));
+ BEGIN_CS(38 + (r300->screen->caps.has_tcl ? 7 : 0) +
+ (r300->screen->caps.is_rv350 ? 4 : 0));
- if (caps->has_tcl) {
+ if (r300->screen->caps.has_tcl) {
/*Flushing PVS is required before the VAP_GB registers can be changed*/
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
@@ -107,7 +106,7 @@ void r300_emit_invariant_state(struct r300_context* r300,
OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525);
OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000);
- if (caps->family >= CHIP_FAMILY_RV350) {
+ if (r300->screen->caps.is_rv350) {
OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101);
OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE);
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index a4a3f2166f..8bebeacf86 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -787,7 +787,7 @@ static void r300_setup_miptree(struct r300_screen* screen,
{
struct pipe_resource* base = &tex->b.b;
unsigned stride, size, layer_size, nblocksy, i;
- boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_RV350;
+ boolean rv350_mode = screen->caps.is_rv350;
SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
util_format_name(base->format));
@@ -834,7 +834,7 @@ static void r300_setup_tiling(struct pipe_screen *screen,
{
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
enum pipe_format format = tex->b.b.format;
- boolean rv350_mode = r300_screen(screen)->caps.family >= CHIP_FAMILY_RV350;
+ boolean rv350_mode = r300_screen(screen)->caps.is_rv350;
boolean is_zb = util_format_is_depth_or_stencil(format);
boolean dbg_no_tiling = SCREEN_DBG_ON(r300_screen(screen), DBG_NO_TILING);
@@ -880,7 +880,7 @@ static unsigned r300_texture_is_referenced(struct pipe_context *context,
struct r300_context *r300 = r300_context(context);
struct r300_texture *rtex = (struct r300_texture *)texture;
- if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer))
+ if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer, R300_REF_CS))
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
return PIPE_UNREFERENCED;
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index 21a1c45982..f6428ed760 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -115,10 +115,10 @@ static unsigned translate_opcode(unsigned opcode)
/* case TGSI_OPCODE_ENDREP: return RC_OPCODE_ENDREP; */
/* case TGSI_OPCODE_PUSHA: return RC_OPCODE_PUSHA; */
/* case TGSI_OPCODE_POPA: return RC_OPCODE_POPA; */
- /* case TGSI_OPCODE_CEIL: return RC_OPCODE_CEIL; */
+ case TGSI_OPCODE_CEIL: return RC_OPCODE_CEIL;
/* case TGSI_OPCODE_I2F: return RC_OPCODE_I2F; */
/* case TGSI_OPCODE_NOT: return RC_OPCODE_NOT; */
- /* case TGSI_OPCODE_TRUNC: return RC_OPCODE_TRUNC; */
+ case TGSI_OPCODE_TRUNC: return RC_OPCODE_FLR;
/* case TGSI_OPCODE_SHL: return RC_OPCODE_SHL; */
/* case TGSI_OPCODE_ISHR: return RC_OPCODE_SHR; */
/* case TGSI_OPCODE_AND: return RC_OPCODE_AND; */
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 9c348d9115..2bd40176d1 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -42,6 +42,11 @@ enum r300_value_id {
R300_VID_TEX3D_MIP_BUG,
};
+enum r300_reference_domain { /* bitfield */
+ R300_REF_CS = 1,
+ R300_REF_HW = 2
+};
+
struct r300_winsys_screen {
void (*destroy)(struct r300_winsys_screen *ws);
@@ -160,9 +165,8 @@ struct r300_winsys_screen {
struct winsys_handle *whandle);
boolean (*is_buffer_referenced)(struct r300_winsys_screen *winsys,
- struct r300_winsys_buffer *buffer);
-
-
+ struct r300_winsys_buffer *buffer,
+ enum r300_reference_domain domain);
};
struct r300_winsys_screen *
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index d0c2978c24..9dcb5586c6 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -93,6 +93,7 @@ softpipe_destroy( struct pipe_context *pipe )
softpipe->quad.shade->destroy( softpipe->quad.shade );
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
softpipe->quad.blend->destroy( softpipe->quad.blend );
+ softpipe->quad.pstipple->destroy( softpipe->quad.pstipple );
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
@@ -296,12 +297,13 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
+ softpipe->quad.pstipple = sp_quad_polygon_stipple_stage(softpipe);
/*
* Create drawing context and plug our rendering stage into it.
*/
- softpipe->draw = draw_create();
+ softpipe->draw = draw_create(&softpipe->pipe);
if (!softpipe->draw)
goto fail;
@@ -330,7 +332,9 @@ softpipe_create_context( struct pipe_screen *screen,
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
/* Do polygon stipple w/ texture map + frag prog? */
+#if DO_PSTIPPLE_IN_DRAW_MODULE
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
+#endif
sp_init_surface_functions(softpipe);
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index be8f2cb3e0..92607874b6 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -38,6 +38,10 @@
#include "sp_quad_pipe.h"
+/** Do polygon stipple in the driver here, or in the draw module? */
+#define DO_PSTIPPLE_IN_DRAW_MODULE 1
+
+
struct softpipe_vbuf_render;
struct draw_context;
struct draw_stage;
@@ -126,6 +130,7 @@ struct softpipe_context {
struct quad_stage *shade;
struct quad_stage *depth_test;
struct quad_stage *blend;
+ struct quad_stage *pstipple;
struct quad_stage *first; /**< points to one of the above stages */
} quad;
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 4ee31969e6..72117c233e 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -520,6 +520,9 @@ depth_stencil_test_quad(struct quad_stage *qs,
face = 0;
}
+ /* 0 = front-face, 1 = back-face */
+ assert(face == 0 || face == 1);
+
/* choose front or back face function, operator, etc */
/* XXX we could do these initializations once per primitive */
func = softpipe->depth_stencil->stencil[face].func;
diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c
index 1b5bab4eca..43b8e88e33 100644
--- a/src/gallium/drivers/softpipe/sp_quad_pipe.c
+++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c
@@ -59,5 +59,10 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
sp_push_quad_first( sp, sp->quad.depth_test );
sp_push_quad_first( sp, sp->quad.shade );
}
+
+#if !DO_PSTIPPLE_IN_DRAW_MODULE
+ if (sp->rasterizer->poly_stipple_enable)
+ sp_push_quad_first( sp, sp->quad.pstipple );
+#endif
}
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index e136cb7cf7..86354664e4 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -47,6 +47,7 @@
#define DEBUG_VERTS 0
#define DEBUG_FRAGS 0
+
/**
* Triangle edge info
*/
@@ -59,11 +60,16 @@ struct edge {
};
+/**
+ * Max number of quads (2x2 pixel blocks) to process per batch.
+ * This can't be arbitrarily increased since we depend on some 32-bit
+ * bitmasks (two bits per quad).
+ */
#define MAX_QUADS 16
/**
- * Triangle setup info (derived from draw_stage).
+ * Triangle setup info.
* Also used for line drawing (taking some liberties).
*/
struct setup_context {
@@ -140,7 +146,7 @@ cull_tri(const struct setup_context *setup, float det)
* Clip setup->quad against the scissor/surface bounds.
*/
static INLINE void
-quad_clip( struct setup_context *setup, struct quad_header *quad )
+quad_clip(struct setup_context *setup, struct quad_header *quad)
{
const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
const int minx = (int) cliprect->minx;
@@ -171,7 +177,7 @@ quad_clip( struct setup_context *setup, struct quad_header *quad )
* Emit a quad (pass to next stage) with clipping.
*/
static INLINE void
-clip_emit_quad( struct setup_context *setup, struct quad_header *quad )
+clip_emit_quad(struct setup_context *setup, struct quad_header *quad)
{
quad_clip( setup, quad );
@@ -188,12 +194,15 @@ clip_emit_quad( struct setup_context *setup, struct quad_header *quad )
* Given an X or Y coordinate, return the block/quad coordinate that it
* belongs to.
*/
-static INLINE int block( int x )
+static INLINE int
+block(int x)
{
return x & ~(2-1);
}
-static INLINE int block_x( int x )
+
+static INLINE int
+block_x(int x)
{
return x & ~(16-1);
}
@@ -202,9 +211,10 @@ static INLINE int block_x( int x )
/**
* Render a horizontal span of quads
*/
-static void flush_spans( struct setup_context *setup )
+static void
+flush_spans(struct setup_context *setup)
{
- const int step = 16;
+ const int step = MAX_QUADS;
const int xleft0 = setup->span.left[0];
const int xleft1 = setup->span.left[1];
const int xright0 = setup->span.right[0];
@@ -265,8 +275,9 @@ static void flush_spans( struct setup_context *setup )
#if DEBUG_VERTS
-static void print_vertex(const struct setup_context *setup,
- const float (*v)[4])
+static void
+print_vertex(const struct setup_context *setup,
+ const float (*v)[4])
{
int i;
debug_printf(" Vertex: (%p)\n", (void *) v);
@@ -280,16 +291,18 @@ static void print_vertex(const struct setup_context *setup,
}
#endif
+
/**
* Sort the vertices from top to bottom order, setting up the triangle
* edge fields (ebot, emaj, etop).
* \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise
*/
-static boolean setup_sort_vertices( struct setup_context *setup,
- float det,
- const float (*v0)[4],
- const float (*v1)[4],
- const float (*v2)[4] )
+static boolean
+setup_sort_vertices(struct setup_context *setup,
+ float det,
+ const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4])
{
setup->vprovoke = v2;
@@ -374,6 +387,7 @@ static boolean setup_sort_vertices( struct setup_context *setup,
/* We need to know if this is a front or back-facing triangle for:
* - the GLSL gl_FrontFacing fragment attribute (bool)
* - two-sided stencil test
+ * 0 = front-facing, 1 = back-facing
*/
setup->facing =
((det > 0.0) ^
@@ -446,9 +460,10 @@ tri_apply_cylindrical_wrap(float v0,
* \param slot which attribute slot
* \param i which component of the slot (0..3)
*/
-static void const_coeff( struct setup_context *setup,
- struct tgsi_interp_coef *coef,
- uint vertSlot, uint i)
+static void
+const_coeff(struct setup_context *setup,
+ struct tgsi_interp_coef *coef,
+ uint vertSlot, uint i)
{
assert(i <= 3);
@@ -590,7 +605,8 @@ setup_fragcoord_coeff(struct setup_context *setup, uint slot)
* Compute the setup->coef[] array dadx, dady, a0 values.
* Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
*/
-static void setup_tri_coefficients( struct setup_context *setup )
+static void
+setup_tri_coefficients(struct setup_context *setup)
{
struct softpipe_context *softpipe = setup->softpipe;
const struct sp_fragment_shader *spfs = softpipe->fs;
@@ -649,7 +665,8 @@ static void setup_tri_coefficients( struct setup_context *setup )
}
if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
- setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
+ /* convert 0 to 1.0 and 1 to -1.0 */
+ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f;
setup->coef[fragSlot].dadx[0] = 0.0;
setup->coef[fragSlot].dady[0] = 0.0;
}
@@ -657,8 +674,8 @@ static void setup_tri_coefficients( struct setup_context *setup )
}
-
-static void setup_tri_edges( struct setup_context *setup )
+static void
+setup_tri_edges(struct setup_context *setup)
{
float vmin_x = setup->vmin[0][0] + setup->pixel_offset;
float vmid_x = setup->vmid[0][0] + setup->pixel_offset;
@@ -669,17 +686,17 @@ static void setup_tri_edges( struct setup_context *setup )
setup->emaj.sy = ceilf(vmin_y);
setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy);
- setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy;
+ setup->emaj.dxdy = setup->emaj.dy ? setup->emaj.dx / setup->emaj.dy : .0f;
setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy;
setup->etop.sy = ceilf(vmid_y);
setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy);
- setup->etop.dxdy = setup->etop.dx / setup->etop.dy;
+ setup->etop.dxdy = setup->etop.dy ? setup->etop.dx / setup->etop.dy : .0f;
setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy;
setup->ebot.sy = ceilf(vmin_y);
setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy);
- setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy;
+ setup->ebot.dxdy = setup->ebot.dy ? setup->ebot.dx / setup->ebot.dy : .0f;
setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy;
}
@@ -688,10 +705,11 @@ static void setup_tri_edges( struct setup_context *setup )
* Render the upper or lower half of a triangle.
* Scissoring/cliprect is applied here too.
*/
-static void subtriangle( struct setup_context *setup,
- struct edge *eleft,
- struct edge *eright,
- int lines )
+static void
+subtriangle(struct setup_context *setup,
+ struct edge *eleft,
+ struct edge *eright,
+ int lines)
{
const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
const int minx = (int) cliprect->minx;
@@ -765,9 +783,9 @@ static void subtriangle( struct setup_context *setup,
* calculate it here.
*/
static float
-calc_det( const float (*v0)[4],
- const float (*v1)[4],
- const float (*v2)[4] )
+calc_det(const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4])
{
/* edge vectors e = v0 - v2, f = v1 - v2 */
const float ex = v0[0][0] - v2[0][0];
@@ -783,10 +801,11 @@ calc_det( const float (*v0)[4],
/**
* Do setup for triangle rasterization, then render the triangle.
*/
-void sp_setup_tri( struct setup_context *setup,
- const float (*v0)[4],
- const float (*v1)[4],
- const float (*v2)[4] )
+void
+sp_setup_tri(struct setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4])
{
float det;
@@ -926,7 +945,7 @@ line_persp_coeff(const struct setup_context *setup,
* Compute the setup->coef[] array dadx, dady, a0 values.
* Must be called after setup->vmin,vmax are initialized.
*/
-static INLINE boolean
+static boolean
setup_line_coefficients(struct setup_context *setup,
const float (*v0)[4],
const float (*v1)[4])
@@ -1002,7 +1021,8 @@ setup_line_coefficients(struct setup_context *setup,
}
if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
- setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
+ /* convert 0 to 1.0 and 1 to -1.0 */
+ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f;
setup->coef[fragSlot].dadx[0] = 0.0;
setup->coef[fragSlot].dady[0] = 0.0;
}
@@ -1047,8 +1067,8 @@ plot(struct setup_context *setup, int x, int y)
*/
void
sp_setup_line(struct setup_context *setup,
- const float (*v0)[4],
- const float (*v1)[4])
+ const float (*v0)[4],
+ const float (*v1)[4])
{
int x0 = (int) v0[0][0];
int x1 = (int) v1[0][0];
@@ -1176,8 +1196,8 @@ point_persp_coeff(const struct setup_context *setup,
* XXX could optimize a lot for 1-pixel points.
*/
void
-sp_setup_point( struct setup_context *setup,
- const float (*v0)[4] )
+sp_setup_point(struct setup_context *setup,
+ const float (*v0)[4])
{
struct softpipe_context *softpipe = setup->softpipe;
const struct sp_fragment_shader *spfs = softpipe->fs;
@@ -1248,7 +1268,8 @@ sp_setup_point( struct setup_context *setup,
}
if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
- setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
+ /* convert 0 to 1.0 and 1 to -1.0 */
+ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f;
setup->coef[fragSlot].dadx[0] = 0.0;
setup->coef[fragSlot].dady[0] = 0.0;
}
@@ -1377,7 +1398,12 @@ sp_setup_point( struct setup_context *setup,
}
}
-void sp_setup_prepare( struct setup_context *setup )
+
+/**
+ * Called by vbuf code just before we start buffering primitives.
+ */
+void
+sp_setup_prepare(struct setup_context *setup)
{
struct softpipe_context *sp = setup->softpipe;
@@ -1403,8 +1429,8 @@ void sp_setup_prepare( struct setup_context *setup )
}
-
-void sp_setup_destroy_context( struct setup_context *setup )
+void
+sp_setup_destroy_context(struct setup_context *setup)
{
FREE( setup );
}
@@ -1413,7 +1439,8 @@ void sp_setup_destroy_context( struct setup_context *setup )
/**
* Create a new primitive setup/render stage.
*/
-struct setup_context *sp_setup_create_context( struct softpipe_context *softpipe )
+struct setup_context *
+sp_setup_create_context(struct softpipe_context *softpipe)
{
struct setup_context *setup = CALLOC_STRUCT(setup_context);
unsigned i;
@@ -1430,4 +1457,3 @@ struct setup_context *sp_setup_create_context( struct softpipe_context *softpipe
return setup;
}
-
diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
index a5b00336d4..c9ede09f26 100644
--- a/src/gallium/drivers/softpipe/sp_state_rasterizer.c
+++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
@@ -49,7 +49,7 @@ void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
return;
/* pass-through to draw module */
- draw_set_rasterizer_state(softpipe->draw, rasterizer);
+ draw_set_rasterizer_state(softpipe->draw, rasterizer, rasterizer);
softpipe->rasterizer = rasterizer;
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
index 3571778867..5253c45cb2 100644
--- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -222,7 +222,8 @@ static void svga_bind_rasterizer_state( struct pipe_context *pipe,
svga->curr.rast = raster;
- draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL);
+ draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL,
+ state);
svga->dirty |= SVGA_NEW_RAST;
}
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index 4504bf71fd..eb71c23195 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -143,7 +143,7 @@ boolean svga_init_swtnl( struct svga_context *svga )
/*
* Create drawing context and plug our rendering stage into it.
*/
- svga->swtnl.draw = draw_create();
+ svga->swtnl.draw = draw_create(&svga->pipe);
if (svga->swtnl.draw == NULL)
goto fail;
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 246d34e649..a759238293 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -113,7 +113,8 @@ static int update_swtnl_draw( struct svga_context *svga,
if (dirty & SVGA_NEW_RAST)
draw_set_rasterizer_state(svga->swtnl.draw,
- &svga->curr.rast->templ);
+ &svga->curr.rast->templ,
+ (void *) svga->curr.rast);
if (dirty & SVGA_NEW_FRAME_BUFFER)
draw_set_mrd(svga->swtnl.draw,
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index 09d6b6c9e2..9b31555f1b 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -182,6 +182,44 @@ typedef unsigned char boolean;
#endif
-
+/* You should use these macros to mark if blocks where the if condition
+ * is either likely to be true, or unlikely to be true.
+ *
+ * This will inform human readers of this fact, and will also inform
+ * the compiler, who will in turn inform the CPU.
+ *
+ * CPUs often start executing code inside the if or the else blocks
+ * without knowing whether the condition is true or not, and will have
+ * to throw the work away if they find out later they executed the
+ * wrong part of the if.
+ *
+ * If these macros are used, the CPU is more likely to correctly predict
+ * the right path, and will avoid speculatively executing the wrong branch,
+ * thus not throwing away work, resulting in better performance.
+ *
+ * In light of this, it is also a good idea to mark as "likely" a path
+ * which is not necessarily always more likely, but that will benefit much
+ * more from performance improvements since it is already much faster than
+ * the other path, or viceversa with "unlikely".
+ *
+ * Example usage:
+ * if(unlikely(do_we_need_a_software_fallback()))
+ * do_software_fallback();
+ * else
+ * render_with_gpu();
+ *
+ * The macros follow the Linux kernel convention, and more examples can
+ * be found there.
+ *
+ * Note that profile guided optimization can offer better results, but
+ * needs an appropriate coverage suite and does not inform human readers.
+ */
+#ifdef __GNUC__
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#else
+#define likely(x) !!(x)
+#define unlikely(x) !!(x)
+#endif
#endif /* P_COMPILER_H */
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 794785006f..1768241352 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -16,6 +16,7 @@ x11_INCLUDES = \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/glx \
-I$(TOP)/src/mesa \
+ $(X11_CFLAGS) \
$(shell pkg-config --cflags-only-I libdrm)
x11_SOURCES = $(wildcard x11/*.c) \
diff --git a/src/gallium/targets/libgl-xlib/Makefile b/src/gallium/targets/libgl-xlib/Makefile
index 6cd00cad45..add3a27394 100644
--- a/src/gallium/targets/libgl-xlib/Makefile
+++ b/src/gallium/targets/libgl-xlib/Makefile
@@ -20,7 +20,8 @@ INCLUDE_DIRS = \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/state_trackers/glx/xlib \
- -I$(TOP)/src/gallium/auxiliary
+ -I$(TOP)/src/gallium/auxiliary \
+ $(X11_CFLAGS)
DEFINES += \
-DGALLIUM_SOFTPIPE
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
index 8782d675df..b48b6358e0 100644
--- a/src/gallium/winsys/radeon/drm/radeon_buffer.h
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -86,5 +86,6 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
struct winsys_handle *whandle);
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf);
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+ enum r300_reference_domain domain);
#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index c9179a3620..9824ada5b3 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -381,13 +381,25 @@ void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
}
}
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf)
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+ enum r300_reference_domain domain)
{
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
- uint32_t domain;
+ uint32_t tmp;
+
+ if (domain & R300_REF_CS) {
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ return TRUE;
+ }
+ }
+
+ if (domain & R300_REF_HW) {
+ if (radeon_bo_is_busy(buf->bo, &tmp)) {
+ return TRUE;
+ }
+ }
- return (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs) ||
- radeon_bo_is_busy(buf->bo, &domain));
+ return FALSE;
}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index d1e65f87c3..2fcf7cf982 100644
--- a/src/gallium/winsys/radeon/drm/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -111,11 +111,12 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
}
static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws,
- struct r300_winsys_buffer *buf)
+ struct r300_winsys_buffer *buf,
+ enum r300_reference_domain domain)
{
struct pb_buffer *_buf = radeon_pb_buffer(buf);
- return radeon_drm_bufmgr_is_buffer_referenced(_buf);
+ return radeon_drm_bufmgr_is_buffer_referenced(_buf, domain);
}
static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 06f3d8b71c..3a53ce91b3 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -175,6 +175,8 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
{
__GLXDRIdrawablePrivate *pdraw;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+ __GLXdisplayPrivate *dpyPriv;
+ __GLXDRIdisplayPrivate *pdp;
pdraw = Xmalloc(sizeof(*pdraw));
if (!pdraw)
@@ -185,10 +187,12 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
pdraw->base.drawable = drawable;
pdraw->base.psc = psc;
pdraw->bufferCount = 0;
- pdraw->swap_interval = 0;
+ pdraw->swap_interval = 1;
DRI2CreateDrawable(psc->dpy, xDrawable);
+ dpyPriv = __glXInitialize(psc->dpy);
+ pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;;
/* Create a new drawable */
pdraw->base.driDrawable =
(*psc->dri2->createNewDrawable) (psc->__driScreen,
@@ -200,6 +204,13 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
return NULL;
}
+ /*
+ * Make sure server has the same swap interval we do for the new
+ * drawable.
+ */
+ if (pdp->swapAvailable)
+ DRI2SwapInterval(psc->dpy, xDrawable, pdraw->swap_interval);
+
return &pdraw->base;
}
diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c
index de4500a39b..738b1ae97f 100644
--- a/src/mesa/drivers/dri/common/xmlconfig.c
+++ b/src/mesa/drivers/dri/common/xmlconfig.c
@@ -65,7 +65,7 @@ extern char *program_invocation_name, *program_invocation_short_name;
#endif
#if !defined(GET_PROGRAM_NAME)
-# if defined(OpenBSD) || defined(NetBSD) || defined(__UCLIBC__)
+# if defined(__OpenBSD__) || defined(NetBSD) || defined(__UCLIBC__)
/* This is a hack. It's said to work on OpenBSD, NetBSD and GNU.
* Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's
* used as a last resort, if there is no documented facility available. */
diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
index c8acd3a333..e432afc3d4 100644
--- a/src/mesa/drivers/dri/r300/compiler/Makefile
+++ b/src/mesa/drivers/dri/r300/compiler/Makefile
@@ -8,6 +8,7 @@ LIBNAME = r300compiler
C_SOURCES = \
radeon_code.c \
radeon_compiler.c \
+ radeon_emulate_branches.c \
radeon_program.c \
radeon_program_print.c \
radeon_opcodes.c \
diff --git a/src/mesa/drivers/dri/r300/compiler/memory_pool.h b/src/mesa/drivers/dri/r300/compiler/memory_pool.h
index ce23c319ad..42344d0e3b 100644
--- a/src/mesa/drivers/dri/r300/compiler/memory_pool.h
+++ b/src/mesa/drivers/dri/r300/compiler/memory_pool.h
@@ -46,4 +46,35 @@ void memory_pool_init(struct memory_pool * pool);
void memory_pool_destroy(struct memory_pool * pool);
void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes);
+
+/**
+ * Generic helper for growing an array that has separate size/count
+ * and reserved counters to accomodate up to num new element.
+ *
+ * type * Array;
+ * unsigned int Size;
+ * unsigned int Reserved;
+ *
+ * memory_pool_array_reserve(pool, type, Array, Size, Reserved, k);
+ * assert(Size + k < Reserved);
+ *
+ * \note Size is not changed by this macro.
+ *
+ * \warning Array, Size, Reserved have to be lvalues and may be evaluated
+ * several times.
+ */
+#define memory_pool_array_reserve(pool, type, array, size, reserved, num) do { \
+ unsigned int _num = (num); \
+ if ((size) + _num > (reserved)) { \
+ unsigned int newreserve = (reserved) * 2; \
+ type * newarray; \
+ if (newreserve < _num) \
+ newreserve = 4 * _num; /* arbitrary heuristic */ \
+ newarray = memory_pool_malloc((pool), newreserve * sizeof(type)); \
+ memcpy(newarray, (array), (size) * sizeof(type)); \
+ (array) = newarray; \
+ (reserved) = newreserve; \
+ } \
+} while(0)
+
#endif /* MEMORY_POOL_H */
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
index 5fe10dbfe8..25bf373b6f 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include "radeon_dataflow.h"
+#include "radeon_emulate_branches.h"
#include "radeon_program_alu.h"
#include "radeon_program_tex.h"
#include "r300_fragprog.h"
@@ -85,10 +86,27 @@ static void rewrite_depth_out(struct r300_fragment_program_compiler * c)
}
}
+static void debug_program_log(struct r300_fragment_program_compiler* c, const char * where)
+{
+ if (c->Base.Debug) {
+ fprintf(stderr, "Fragment Program: %s\n", where);
+ rc_print_program(&c->Base.Program);
+ }
+}
+
void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
{
rewrite_depth_out(c);
+ debug_program_log(c, "before compilation");
+
+ /* XXX Ideally this should be done only for r3xx, but since
+ * we don't have branching support for r5xx, we use the emulation
+ * on all chipsets. */
+ rc_emulate_branches(&c->Base);
+
+ debug_program_log(c, "after emulate branches");
+
if (c->is_r500) {
struct radeon_program_transformation transformations[] = {
{ &r500_transform_IF, 0 },
@@ -98,6 +116,8 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
};
radeonLocalTransform(&c->Base, 4, transformations);
+ debug_program_log(c, "after native rewrite part 1");
+
c->Base.SwizzleCaps = &r500_swizzle_caps;
} else {
struct radeon_program_transformation transformations[] = {
@@ -106,6 +126,8 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
};
radeonLocalTransform(&c->Base, 2, transformations);
+ debug_program_log(c, "after native rewrite part 1");
+
c->Base.SwizzleCaps = &r300_swizzle_caps;
}
@@ -119,62 +141,41 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
common_transformations[0].function = &radeonTransformALU;
radeonLocalTransform(&c->Base, 1, common_transformations);
- if (c->Base.Debug) {
- fprintf(stderr, "Fragment Program: After native rewrite:\n");
- rc_print_program(&c->Base.Program);
- fflush(stderr);
- }
+ if (c->Base.Error)
+ return;
+
+ debug_program_log(c, "after native rewrite part 2");
rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_use, c);
if (c->Base.Error)
return;
- if (c->Base.Debug) {
- fprintf(stderr, "Fragment Program: After deadcode:\n");
- rc_print_program(&c->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(c, "after deadcode");
rc_dataflow_swizzles(&c->Base);
if (c->Base.Error)
return;
- if (c->Base.Debug) {
- fprintf(stderr, "Compiler: after dataflow passes:\n");
- rc_print_program(&c->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(c, "after dataflow passes");
rc_pair_translate(c);
if (c->Base.Error)
return;
- if (c->Base.Debug) {
- fprintf(stderr, "Compiler: after pair translate:\n");
- rc_print_program(&c->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(c, "after pair translate");
rc_pair_schedule(c);
if (c->Base.Error)
return;
- if (c->Base.Debug) {
- fprintf(stderr, "Compiler: after pair scheduling:\n");
- rc_print_program(&c->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(c, "after pair scheduling");
rc_pair_regalloc(c, c->max_temp_regs);
if (c->Base.Error)
return;
- if (c->Base.Debug) {
- fprintf(stderr, "Compiler: after pair register allocation:\n");
- rc_print_program(&c->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(c, "after register allocation");
if (c->is_r500) {
r500BuildFragmentProgramHwCode(c);
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 1b2cb8dde7..4a0b6c02ef 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -29,7 +29,7 @@
#include "radeon_dataflow.h"
#include "radeon_program_alu.h"
#include "radeon_swizzle.h"
-
+#include "radeon_emulate_branches.h"
/*
* Take an already-setup and valid source then swizzle it appropriately to
@@ -566,6 +566,14 @@ static int swizzle_is_native(rc_opcode opcode, struct rc_src_register reg)
return 1;
}
+static void debug_program_log(struct r300_vertex_program_compiler* c, const char * where)
+{
+ if (c->Base.Debug) {
+ fprintf(stderr, "Vertex Program: %s\n", where);
+ rc_print_program(&c->Base.Program);
+ }
+}
+
static struct rc_swizzle_caps r300_vertprog_swizzle_caps = {
.IsNative = &swizzle_is_native,
@@ -579,6 +587,15 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
addArtificialOutputs(compiler);
+ debug_program_log(compiler, "before compilation");
+
+ /* XXX Ideally this should be done only for r3xx, but since
+ * we don't have branching support for r5xx, we use the emulation
+ * on all chipsets. */
+ rc_emulate_branches(&compiler->Base);
+
+ debug_program_log(compiler, "after emulate branches");
+
{
struct radeon_program_transformation transformations[] = {
{ &r300_transform_vertex_alu, 0 },
@@ -586,11 +603,7 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
radeonLocalTransform(&compiler->Base, 1, transformations);
}
- if (compiler->Base.Debug) {
- fprintf(stderr, "Vertex program after native rewrite:\n");
- rc_print_program(&compiler->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(compiler, "after native rewrite");
{
/* Note: This pass has to be done seperately from ALU rewrite,
@@ -603,29 +616,17 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
radeonLocalTransform(&compiler->Base, 1, transformations);
}
- if (compiler->Base.Debug) {
- fprintf(stderr, "Vertex program after source conflict resolve:\n");
- rc_print_program(&compiler->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(compiler, "after source conflict resolve");
rc_dataflow_deadcode(&compiler->Base, &dataflow_outputs_mark_used, compiler);
- if (compiler->Base.Debug) {
- fprintf(stderr, "Vertex program after deadcode:\n");
- rc_print_program(&compiler->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(compiler, "after deadcode");
rc_dataflow_swizzles(&compiler->Base);
allocate_temporary_registers(compiler);
- if (compiler->Base.Debug) {
- fprintf(stderr, "Vertex program after dataflow:\n");
- rc_print_program(&compiler->Base.Program);
- fflush(stderr);
- }
+ debug_program_log(compiler, "after dataflow");
translate_vertex_program(compiler);
diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
index b6dfe28def..10c5e2349e 100644
--- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
@@ -348,21 +348,6 @@ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_inst
return 1;
}
-static void grow_branches(struct emit_state * s)
-{
- unsigned int newreserved = s->BranchesReserved * 2;
- struct branch_info * newbranches;
-
- if (!newreserved)
- newreserved = 4;
-
- newbranches = memory_pool_malloc(&s->C->Pool, newreserved*sizeof(struct branch_info));
- memcpy(newbranches, s->Branches, s->CurrentBranchDepth*sizeof(struct branch_info));
-
- s->Branches = newbranches;
- s->BranchesReserved = newreserved;
-}
-
static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst)
{
if (s->Code->inst_end >= 511) {
@@ -380,8 +365,8 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
return;
}
- if (s->CurrentBranchDepth >= s->BranchesReserved)
- grow_branches(s);
+ memory_pool_array_reserve(&s->C->Pool, struct branch_info,
+ s->Branches, s->CurrentBranchDepth, s->BranchesReserved, 1);
struct branch_info * branch = &s->Branches[s->CurrentBranchDepth++];
branch->If = newip;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
index cce9166e64..16e2f3a218 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
@@ -160,3 +160,92 @@ void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void *
writes_pair(inst, cb, userdata);
}
}
+
+
+static void remap_normal_instruction(struct rc_instruction * fullinst,
+ rc_remap_register_fn cb, void * userdata)
+{
+ struct rc_sub_instruction * inst = &fullinst->U.I;
+ const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
+
+ if (opcode->HasDstReg) {
+ rc_register_file file = inst->DstReg.File;
+ unsigned int index = inst->DstReg.Index;
+
+ cb(userdata, fullinst, &file, &index);
+
+ inst->DstReg.File = file;
+ inst->DstReg.Index = index;
+ }
+
+ for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
+ rc_register_file file = inst->SrcReg[src].File;
+ unsigned int index = inst->SrcReg[src].Index;
+
+ cb(userdata, fullinst, &file, &index);
+
+ inst->SrcReg[src].File = file;
+ inst->SrcReg[src].Index = index;
+ }
+}
+
+static void remap_pair_instruction(struct rc_instruction * fullinst,
+ rc_remap_register_fn cb, void * userdata)
+{
+ struct rc_pair_instruction * inst = &fullinst->U.P;
+
+ if (inst->RGB.WriteMask) {
+ rc_register_file file = RC_FILE_TEMPORARY;
+ unsigned int index = inst->RGB.DestIndex;
+
+ cb(userdata, fullinst, &file, &index);
+
+ inst->RGB.DestIndex = index;
+ }
+
+ if (inst->Alpha.WriteMask) {
+ rc_register_file file = RC_FILE_TEMPORARY;
+ unsigned int index = inst->Alpha.DestIndex;
+
+ cb(userdata, fullinst, &file, &index);
+
+ inst->Alpha.DestIndex = index;
+ }
+
+ for(unsigned int src = 0; src < 3; ++src) {
+ if (inst->RGB.Src[src].Used) {
+ rc_register_file file = inst->RGB.Src[src].File;
+ unsigned int index = inst->RGB.Src[src].Index;
+
+ cb(userdata, fullinst, &file, &index);
+
+ inst->RGB.Src[src].File = file;
+ inst->RGB.Src[src].Index = index;
+ }
+
+ if (inst->Alpha.Src[src].Used) {
+ rc_register_file file = inst->Alpha.Src[src].File;
+ unsigned int index = inst->Alpha.Src[src].Index;
+
+ cb(userdata, fullinst, &file, &index);
+
+ inst->Alpha.Src[src].File = file;
+ inst->Alpha.Src[src].Index = index;
+ }
+ }
+}
+
+
+/**
+ * Remap all register accesses according to the given function.
+ * That is, call the function \p cb for each referenced register (both read and written)
+ * and update the given instruction \p inst accordingly
+ * if it modifies its \ref pfile and \ref pindex contents.
+ */
+void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata)
+{
+ if (inst->Type == RC_INSTRUCTION_NORMAL)
+ remap_normal_instruction(inst, cb, userdata);
+ else
+ remap_pair_instruction(inst, cb, userdata);
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
index 5aa4cb64f3..62cda20eea 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
@@ -36,13 +36,17 @@ struct rc_swizzle_caps;
/**
- * Help analyze the register accesses of instructions.
+ * Help analyze and modify the register accesses of instructions.
*/
/*@{*/
typedef void (*rc_read_write_fn)(void * userdata, struct rc_instruction * inst,
rc_register_file file, unsigned int index, unsigned int chan);
void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata);
void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata);
+
+typedef void (*rc_remap_register_fn)(void * userdata, struct rc_instruction * inst,
+ rc_register_file * pfile, unsigned int * pindex);
+void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata);
/*@}*/
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
index f3734852cc..e3c2c83c0c 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
@@ -80,19 +80,8 @@ static void or_updatemasks(
static void push_branch(struct deadcode_state * s)
{
- if (s->BranchStackSize >= s->BranchStackReserved) {
- unsigned int new_reserve = 2 * s->BranchStackReserved;
- struct branchinfo * new_stack;
-
- if (!new_reserve)
- new_reserve = 4;
-
- new_stack = memory_pool_malloc(&s->C->Pool, new_reserve * sizeof(struct branchinfo));
- memcpy(new_stack, s->BranchStack, s->BranchStackSize * sizeof(struct branchinfo));
-
- s->BranchStack = new_stack;
- s->BranchStackReserved = new_reserve;
- }
+ memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack,
+ s->BranchStackSize, s->BranchStackReserved, 1);
struct branchinfo * branch = &s->BranchStack[s->BranchStackSize++];
branch->HaveElse = 0;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
new file mode 100644
index 0000000000..d889612f4f
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@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 "radeon_emulate_branches.h"
+
+#include <stdio.h>
+
+#include "radeon_compiler.h"
+#include "radeon_dataflow.h"
+
+#define VERBOSE 0
+
+#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
+
+
+struct proxy_info {
+ unsigned int Proxied:1;
+ unsigned int Index:RC_REGISTER_INDEX_BITS;
+};
+
+struct register_proxies {
+ struct proxy_info Temporary[RC_REGISTER_MAX_INDEX];
+};
+
+struct branch_info {
+ struct rc_instruction * If;
+ struct rc_instruction * Else;
+};
+
+struct emulate_branch_state {
+ struct radeon_compiler * C;
+
+ struct branch_info * Branches;
+ unsigned int BranchCount;
+ unsigned int BranchReserved;
+};
+
+
+static void handle_if(struct emulate_branch_state * s, struct rc_instruction * inst)
+{
+ memory_pool_array_reserve(&s->C->Pool, struct branch_info,
+ s->Branches, s->BranchCount, s->BranchReserved, 1);
+
+ DBG("%s\n", __FUNCTION__);
+
+ struct branch_info * branch = &s->Branches[s->BranchCount++];
+ memset(branch, 0, sizeof(struct branch_info));
+ branch->If = inst;
+
+ /* Make a safety copy of the decision register, because we will need
+ * it at ENDIF time and it might be overwritten in both branches. */
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, inst->Prev);
+ inst_mov->U.I.Opcode = RC_OPCODE_MOV;
+ inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
+ inst_mov->U.I.DstReg.Index = rc_find_free_temporary(s->C);
+ inst_mov->U.I.DstReg.WriteMask = RC_MASK_X;
+ inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+
+ inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+ inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index;
+ inst->U.I.SrcReg[0].Swizzle = 0;
+ inst->U.I.SrcReg[0].Abs = 0;
+ inst->U.I.SrcReg[0].Negate = 0;
+}
+
+static void handle_else(struct emulate_branch_state * s, struct rc_instruction * inst)
+{
+ if (!s->BranchCount) {
+ rc_error(s->C, "Encountered ELSE outside of branches");
+ return;
+ }
+
+ DBG("%s\n", __FUNCTION__);
+
+ struct branch_info * branch = &s->Branches[s->BranchCount - 1];
+ branch->Else = inst;
+}
+
+
+struct state_and_proxies {
+ struct emulate_branch_state * S;
+ struct register_proxies * Proxies;
+};
+
+static struct proxy_info * get_proxy_info(struct state_and_proxies * sap,
+ rc_register_file file, unsigned int index)
+{
+ if (file == RC_FILE_TEMPORARY) {
+ return &sap->Proxies->Temporary[index];
+ } else {
+ return 0;
+ }
+}
+
+static void scan_write(void * userdata, struct rc_instruction * inst,
+ rc_register_file file, unsigned int index, unsigned int comp)
+{
+ struct state_and_proxies * sap = userdata;
+ struct proxy_info * proxy = get_proxy_info(sap, file, index);
+
+ if (proxy && !proxy->Proxied) {
+ proxy->Proxied = 1;
+ proxy->Index = rc_find_free_temporary(sap->S->C);
+ }
+}
+
+static void remap_proxy_function(void * userdata, struct rc_instruction * inst,
+ rc_register_file * pfile, unsigned int * pindex)
+{
+ struct state_and_proxies * sap = userdata;
+ struct proxy_info * proxy = get_proxy_info(sap, *pfile, *pindex);
+
+ if (proxy && proxy->Proxied) {
+ *pfile = RC_FILE_TEMPORARY;
+ *pindex = proxy->Index;
+ }
+}
+
+/**
+ * Redirect all writes in the instruction range [begin, end) to proxy
+ * temporary registers.
+ */
+static void allocate_and_insert_proxies(struct emulate_branch_state * s,
+ struct register_proxies * proxies,
+ struct rc_instruction * begin,
+ struct rc_instruction * end)
+{
+ struct state_and_proxies sap;
+
+ sap.S = s;
+ sap.Proxies = proxies;
+
+ for(struct rc_instruction * inst = begin; inst != end; inst = inst->Next) {
+ rc_for_all_writes(inst, scan_write, &sap);
+ rc_remap_registers(inst, remap_proxy_function, &sap);
+ }
+
+ for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) {
+ if (proxies->Temporary[index].Proxied) {
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, begin->Prev);
+ inst_mov->U.I.Opcode = RC_OPCODE_MOV;
+ inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
+ inst_mov->U.I.DstReg.Index = proxies->Temporary[index].Index;
+ inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZW;
+ inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+ inst_mov->U.I.SrcReg[0].Index = index;
+ }
+ }
+}
+
+
+static void inject_cmp(struct emulate_branch_state * s,
+ struct rc_instruction * inst_if,
+ struct rc_instruction * inst_endif,
+ rc_register_file file, unsigned int index,
+ struct proxy_info ifproxy,
+ struct proxy_info elseproxy)
+{
+ struct rc_instruction * inst_cmp = rc_insert_new_instruction(s->C, inst_endif);
+ inst_cmp->U.I.Opcode = RC_OPCODE_CMP;
+ inst_cmp->U.I.DstReg.File = file;
+ inst_cmp->U.I.DstReg.Index = index;
+ inst_cmp->U.I.DstReg.WriteMask = RC_MASK_XYZW;
+ inst_cmp->U.I.SrcReg[0] = inst_if->U.I.SrcReg[0];
+ inst_cmp->U.I.SrcReg[0].Abs = 1;
+ inst_cmp->U.I.SrcReg[0].Negate = RC_MASK_XYZW;
+ inst_cmp->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
+ inst_cmp->U.I.SrcReg[1].Index = ifproxy.Proxied ? ifproxy.Index : index;
+ inst_cmp->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
+ inst_cmp->U.I.SrcReg[2].Index = elseproxy.Proxied ? elseproxy.Index : index;
+}
+
+static void handle_endif(struct emulate_branch_state * s, struct rc_instruction * inst)
+{
+ if (!s->BranchCount) {
+ rc_error(s->C, "Encountered ENDIF outside of branches");
+ return;
+ }
+
+ DBG("%s\n", __FUNCTION__);
+
+ struct branch_info * branch = &s->Branches[s->BranchCount - 1];
+ struct register_proxies IfProxies;
+ struct register_proxies ElseProxies;
+
+ memset(&IfProxies, 0, sizeof(IfProxies));
+ memset(&ElseProxies, 0, sizeof(ElseProxies));
+
+ allocate_and_insert_proxies(s, &IfProxies, branch->If->Next, branch->Else ? branch->Else : inst);
+
+ if (branch->Else)
+ allocate_and_insert_proxies(s, &ElseProxies, branch->Else->Next, inst);
+
+ /* Insert the CMP instructions at the end. */
+ for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) {
+ if (IfProxies.Temporary[index].Proxied || ElseProxies.Temporary[index].Proxied) {
+ inject_cmp(s, branch->If, inst, RC_FILE_TEMPORARY, index,
+ IfProxies.Temporary[index], ElseProxies.Temporary[index]);
+ }
+ }
+
+ /* Remove all traces of the branch instructions */
+ rc_remove_instruction(branch->If);
+ if (branch->Else)
+ rc_remove_instruction(branch->Else);
+ rc_remove_instruction(inst);
+
+ s->BranchCount--;
+
+ if (VERBOSE) {
+ DBG("Program after ENDIF handling:\n");
+ rc_print_program(&s->C->Program);
+ }
+}
+
+
+struct remap_output_data {
+ unsigned int Output:RC_REGISTER_INDEX_BITS;
+ unsigned int Temporary:RC_REGISTER_INDEX_BITS;
+};
+
+static void remap_output_function(void * userdata, struct rc_instruction * inst,
+ rc_register_file * pfile, unsigned int * pindex)
+{
+ struct remap_output_data * data = userdata;
+
+ if (*pfile == RC_FILE_OUTPUT && *pindex == data->Output) {
+ *pfile = RC_FILE_TEMPORARY;
+ *pindex = data->Temporary;
+ }
+}
+
+
+/**
+ * Output registers cannot be read from and so cannot be dealt with like
+ * temporary registers.
+ *
+ * We do the simplest thing: If an output registers is written within
+ * a branch, then *all* writes to this register are proxied to a
+ * temporary register, and a final MOV is appended to the end of
+ * the program.
+ */
+static void fix_output_writes(struct emulate_branch_state * s, struct rc_instruction * inst)
+{
+ if (!s->BranchCount)
+ return;
+
+ const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ if (!opcode->HasDstReg)
+ return;
+
+ if (inst->U.I.DstReg.File == RC_FILE_OUTPUT) {
+ struct remap_output_data remap;
+
+ remap.Output = inst->U.I.DstReg.Index;
+ remap.Temporary = rc_find_free_temporary(s->C);
+
+ for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
+ inst != &s->C->Program.Instructions;
+ inst = inst->Next) {
+ rc_remap_registers(inst, &remap_output_function, &remap);
+ }
+
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, s->C->Program.Instructions.Prev);
+ inst_mov->U.I.Opcode = RC_OPCODE_MOV;
+ inst_mov->U.I.DstReg.File = RC_FILE_OUTPUT;
+ inst_mov->U.I.DstReg.Index = remap.Output;
+ inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZW;
+ inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+ inst_mov->U.I.SrcReg[0].Index = remap.Temporary;
+ }
+}
+
+/**
+ * Remove branch instructions; instead, execute both branches
+ * on different register sets and choose between their results
+ * using CMP instructions in place of the original ENDIF.
+ */
+void rc_emulate_branches(struct radeon_compiler * c)
+{
+ struct emulate_branch_state s;
+
+ memset(&s, 0, sizeof(s));
+ s.C = c;
+
+ /* Untypical loop because we may remove the current instruction */
+ struct rc_instruction * ptr = c->Program.Instructions.Next;
+ while(ptr != &c->Program.Instructions) {
+ struct rc_instruction * inst = ptr;
+ ptr = ptr->Next;
+
+ if (inst->Type == RC_INSTRUCTION_NORMAL) {
+ switch(inst->U.I.Opcode) {
+ case RC_OPCODE_IF:
+ handle_if(&s, inst);
+ break;
+ case RC_OPCODE_ELSE:
+ handle_else(&s, inst);
+ break;
+ case RC_OPCODE_ENDIF:
+ handle_endif(&s, inst);
+ break;
+ default:
+ fix_output_writes(&s, inst);
+ break;
+ }
+ } else {
+ rc_error(c, "%s: unhandled instruction type\n", __FUNCTION__);
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h
new file mode 100644
index 0000000000..e07279f093
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@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 RADEON_EMULATE_BRANCHES_H
+#define RADEON_EMULATE_BRANCHES_H
+
+struct radeon_compiler;
+
+void rc_emulate_branches(struct radeon_compiler * c);
+
+#endif /* RADEON_EMULATE_BRANCHES_H */
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
index ffc91241ab..d593b3e81a 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
@@ -60,6 +60,13 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
.HasDstReg = 1
},
{
+ .Opcode = RC_OPCODE_CEIL,
+ .Name = "CEIL",
+ .NumSrcRegs = 1,
+ .HasDstReg = 1,
+ .IsComponentwise = 1
+ },
+ {
.Opcode = RC_OPCODE_CMP,
.Name = "CMP",
.NumSrcRegs = 3,
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
index 1c9b34df78..87a2e23084 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
@@ -47,6 +47,9 @@ typedef enum {
* dst.x = floor(src.x), where dst must be an address register */
RC_OPCODE_ARL,
+ /** vec4 instruction: dst.c = ceil(src0.c) */
+ RC_OPCODE_CEIL,
+
/** vec4 instruction: dst.c = src0.c < 0.0 ? src1.c : src2.c */
RC_OPCODE_CMP,
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
index b2fe7f76b2..fdfee86701 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -196,9 +196,10 @@ static void compute_live_intervals(struct regalloc_state * s)
}
}
-static void rewrite_register(struct regalloc_state * s,
+static void remap_register(void * data, struct rc_instruction * inst,
rc_register_file * file, unsigned int * index)
{
+ struct regalloc_state * s = data;
const struct register_info * reg;
if (*file == RC_FILE_TEMPORARY)
@@ -214,74 +215,6 @@ static void rewrite_register(struct regalloc_state * s,
}
}
-static void rewrite_normal_instruction(struct regalloc_state * s, struct rc_sub_instruction * inst)
-{
- const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
-
- if (opcode->HasDstReg) {
- rc_register_file file = inst->DstReg.File;
- unsigned int index = inst->DstReg.Index;
-
- rewrite_register(s, &file, &index);
-
- inst->DstReg.File = file;
- inst->DstReg.Index = index;
- }
-
- for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
- rc_register_file file = inst->SrcReg[src].File;
- unsigned int index = inst->SrcReg[src].Index;
-
- rewrite_register(s, &file, &index);
-
- inst->SrcReg[src].File = file;
- inst->SrcReg[src].Index = index;
- }
-}
-
-static void rewrite_pair_instruction(struct regalloc_state * s, struct rc_pair_instruction * inst)
-{
- if (inst->RGB.WriteMask) {
- rc_register_file file = RC_FILE_TEMPORARY;
- unsigned int index = inst->RGB.DestIndex;
-
- rewrite_register(s, &file, &index);
-
- inst->RGB.DestIndex = index;
- }
-
- if (inst->Alpha.WriteMask) {
- rc_register_file file = RC_FILE_TEMPORARY;
- unsigned int index = inst->Alpha.DestIndex;
-
- rewrite_register(s, &file, &index);
-
- inst->Alpha.DestIndex = index;
- }
-
- for(unsigned int src = 0; src < 3; ++src) {
- if (inst->RGB.Src[src].Used) {
- rc_register_file file = inst->RGB.Src[src].File;
- unsigned int index = inst->RGB.Src[src].Index;
-
- rewrite_register(s, &file, &index);
-
- inst->RGB.Src[src].File = file;
- inst->RGB.Src[src].Index = index;
- }
-
- if (inst->Alpha.Src[src].Used) {
- rc_register_file file = inst->Alpha.Src[src].File;
- unsigned int index = inst->Alpha.Src[src].Index;
-
- rewrite_register(s, &file, &index);
-
- inst->Alpha.Src[src].File = file;
- inst->Alpha.Src[src].Index = index;
- }
- }
-}
-
static void do_regalloc(struct regalloc_state * s)
{
/* Simple and stupid greedy register allocation */
@@ -310,10 +243,7 @@ static void do_regalloc(struct regalloc_state * s)
for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
inst != &s->C->Program.Instructions;
inst = inst->Next) {
- if (inst->Type == RC_INSTRUCTION_NORMAL)
- rewrite_normal_instruction(s, &inst->U.I);
- else
- rewrite_pair_instruction(s, &inst->U.P);
+ rc_remap_registers(inst, &remap_register, s);
}
}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
index f5b7d57eab..05b874ba7c 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
@@ -175,6 +175,26 @@ static void transform_ABS(struct radeon_compiler* c,
rc_remove_instruction(inst);
}
+static void transform_CEIL(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ /* Assuming:
+ * ceil(x) = -floor(-x)
+ *
+ * After inlining floor:
+ * ceil(x) = -(-x-frac(-x))
+ *
+ * After simplification:
+ * ceil(x) = x+frac(-x)
+ */
+
+ int tempreg = rc_find_free_temporary(c);
+ emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstreg(RC_FILE_TEMPORARY, tempreg), negate(inst->U.I.SrcReg[0]));
+ emit2(c, inst->Prev, RC_OPCODE_ADD, inst->U.I.SaturateMode, inst->U.I.DstReg,
+ inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, tempreg));
+ rc_remove_instruction(inst);
+}
+
static void transform_DP3(struct radeon_compiler* c,
struct rc_instruction* inst)
{
@@ -458,7 +478,7 @@ static void transform_XPD(struct radeon_compiler* c,
* no userData necessary.
*
* Eliminates the following ALU instructions:
- * ABS, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD
+ * ABS, CEIL, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD
* using:
* MOV, ADD, MUL, MAD, FRC, DP3, LG2, EX2, CMP
*
@@ -474,6 +494,7 @@ int radeonTransformALU(
{
switch(inst->U.I.Opcode) {
case RC_OPCODE_ABS: transform_ABS(c, inst); return 1;
+ case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
case RC_OPCODE_DST: transform_DST(c, inst); return 1;
case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
@@ -511,37 +532,26 @@ static void transform_r300_vertex_CMP(struct radeon_compiler* c,
{
/* There is no decent CMP available, so let's rig one up.
* CMP is defined as dst = src0 < 0.0 ? src1 : src2
- * The following sequence consumes two temps and three extra slots,
+ * The following sequence consumes two temps and two extra slots
+ * (the second temp and the second slot is consumed by transform_LRP),
* but should be equivalent:
*
* SLT tmp0, src0, 0.0
- * SGE tmp1, src0, 0.0
- * MUL tmp0, tmp0, src1
- * MAD dst, src2, tmp1, tmp0
+ * LRP dst, tmp0, src1, src2
*
- * Yes, I know, I'm a mad scientist. ~ C. */
+ * Yes, I know, I'm a mad scientist. ~ C. & M. */
int tempreg0 = rc_find_free_temporary(c);
- int tempreg1 = rc_find_free_temporary(c);
/* SLT tmp0, src0, 0.0 */
emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
dstreg(RC_FILE_TEMPORARY, tempreg0),
inst->U.I.SrcReg[0], builtin_zero);
- /* SGE tmp1, src0, 0.0 */
- emit2(c, inst->Prev, RC_OPCODE_SGE, 0,
- dstreg(RC_FILE_TEMPORARY, tempreg1),
- inst->U.I.SrcReg[0], builtin_zero);
-
- /* MUL tmp0, tmp0, src1 */
- emit2(c, inst->Prev, RC_OPCODE_MUL, 0,
- dstreg(RC_FILE_TEMPORARY, tempreg0),
- srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1]);
-
- /* MAD dst, src2, tmp1, tmp0 */
- emit3(c, inst->Prev, RC_OPCODE_MAD, inst->U.I.SaturateMode,
- inst->U.I.DstReg,
- inst->U.I.SrcReg[2], srcreg(RC_FILE_TEMPORARY, tempreg1), srcreg(RC_FILE_TEMPORARY, tempreg0));
+ /* LRP dst, tmp0, src1, src2 */
+ transform_LRP(c,
+ emit3(c, inst->Prev, RC_OPCODE_LRP, 0,
+ inst->U.I.DstReg,
+ srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1], inst->U.I.SrcReg[2]));
rc_remove_instruction(inst);
}
@@ -557,6 +567,7 @@ int r300_transform_vertex_alu(
{
switch(inst->U.I.Opcode) {
case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
+ case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1;
case RC_OPCODE_DP3: transform_DP3(c, inst); return 1;
case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h
index 98732c810c..b7ee9a134b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_chipset.h
+++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h
@@ -12,6 +12,7 @@
#define PCI_CHIP_RV380_3150 0x3150
#define PCI_CHIP_RV380_3152 0x3152
#define PCI_CHIP_RV380_3154 0x3154
+#define PCI_CHIP_RV380_3155 0x3155
#define PCI_CHIP_RV380_3E50 0x3E50
#define PCI_CHIP_RV380_3E54 0x3E54
#define PCI_CHIP_RS100_4136 0x4136
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index cc951a12cb..c2722a4e19 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -326,7 +326,7 @@ static int cs_emit(struct radeon_cs_int *cs)
(!IS_R600_CLASS(csm->ctx->radeonScreen))) { /* +r6/r7 : No irq for r6/r7 yet. */
drm_radeon_irq_emit_t emit_cmd;
emit_cmd.irq_seq = (int*)&csm->pending_age;
- r = drmCommandWrite(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd));
+ r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd));
if (r) {
return r;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index 7f5fb99fa4..6cd1d87de2 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -526,8 +526,10 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
unsigned mtCount = 0;
unsigned maxMtIndex = 0;
radeon_mipmap_tree *tmp;
+ unsigned int level;
+ int i;
- for (unsigned level = firstLevel; level <= lastLevel; ++level) {
+ for (level = firstLevel; level <= lastLevel; ++level) {
radeon_texture_image *img = get_radeon_texture_image(texObj->base.Image[0][level]);
unsigned found = 0;
// TODO: why this hack??
@@ -537,7 +539,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
if (!img->mt)
continue;
- for (int i = 0; i < mtCount; ++i) {
+ for (i = 0; i < mtCount; ++i) {
if (mts[i] == img->mt) {
found = 1;
mtSizes[i] += img->mt->levels[img->mtlevel].size;
@@ -558,7 +560,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj,
return NULL;
}
- for (int i = 1; i < mtCount; ++i) {
+ for (i = 1; i < mtCount; ++i) {
if (mtSizes[i] > mtSizes[maxMtIndex]) {
maxMtIndex = i;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 4d7255f47e..fca0f8173b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -516,6 +516,7 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
case PCI_CHIP_RV380_3150:
case PCI_CHIP_RV380_3152:
case PCI_CHIP_RV380_3154:
+ case PCI_CHIP_RV380_3155:
case PCI_CHIP_RV380_3E50:
case PCI_CHIP_RV380_3E54:
screen->chip_family = CHIP_FAMILY_RV380;
diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c
index 6f07ac275e..c3a53ea5e2 100644
--- a/src/mesa/drivers/dri/savage/savage_xmesa.c
+++ b/src/mesa/drivers/dri/savage/savage_xmesa.c
@@ -44,6 +44,7 @@
#include "tnl/t_pipeline.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
#include "savagedd.h"
#include "savagestate.h"
@@ -473,6 +474,8 @@ savageCreateContext( const __GLcontextModes *mesaVis,
imesa->CurrentTexObj[0] = 0;
imesa->CurrentTexObj[1] = 0;
+ _mesa_meta_init( ctx );
+
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext( ctx );
@@ -564,6 +567,8 @@ savageDestroyContext(__DRIcontext *driContextPriv)
free(imesa->cmdBuf.base);
free(imesa->clientVtxBuf.buf);
+ _mesa_meta_free( imesa->glCtx );
+
_swsetup_DestroyContext(imesa->glCtx );
_tnl_DestroyContext( imesa->glCtx );
_vbo_DestroyContext( imesa->glCtx );
diff --git a/src/mesa/glapi/gen/GL3.xml b/src/mesa/glapi/gen/GL3.xml
new file mode 100644
index 0000000000..0d8d935f0a
--- /dev/null
+++ b/src/mesa/glapi/gen/GL3.xml
@@ -0,0 +1,581 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="3.0">
+
+ <enum name="COMPARE_REF_TO_TEXTURE" value="0x884E"/>
+ <enum name="CLIP_DISTANCE0" value="0x3000"/>
+ <enum name="CLIP_DISTANCE1" value="0x3001"/>
+ <enum name="CLIP_DISTANCE2" value="0x3002"/>
+ <enum name="CLIP_DISTANCE3" value="0x3003"/>
+ <enum name="CLIP_DISTANCE4" value="0x3004"/>
+ <enum name="CLIP_DISTANCE5" value="0x3005"/>
+ <enum name="CLIP_DISTANCE6" value="0x3006"/>
+ <enum name="CLIP_DISTANCE7" value="0x3007"/>
+ <enum name="MAX_CLIP_DISTANCES" value="0x0D32"/>
+ <enum name="MAJOR_VERSION" value="0x821B"/>
+ <enum name="MINOR_VERSION" value="0x821C"/>
+ <enum name="NUM_EXTENSIONS" value="0x821D"/>
+ <enum name="CONTEXT_FLAGS" value="0x821E"/>
+ <enum name="DEPTH_BUFFER" value="0x8223"/>
+ <enum name="STENCIL_BUFFER" value="0x8224"/>
+ <enum name="COMPRESSED_RED" value="0x8225"/>
+ <enum name="COMPRESSED_RG" value="0x8226"/>
+ <enum name="CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT" value="0x0001"/>
+ <enum name="RGBA32F" value="0x8814"/>
+ <enum name="RGB32F" value="0x8815"/>
+ <enum name="RGBA16F" value="0x881A"/>
+ <enum name="RGB16F" value="0x881B"/>
+ <enum name="VERTEX_ATTRIB_ARRAY_INTEGER" value="0x88FD"/>
+ <enum name="MAX_ARRAY_TEXTURE_LAYERS" value="0x88FF"/>
+ <enum name="MIN_PROGRAM_TEXEL_OFFSET" value="0x8904"/>
+ <enum name="MAX_PROGRAM_TEXEL_OFFSET" value="0x8905"/>
+ <enum name="CLAMP_READ_COLOR" value="0x891C"/>
+ <enum name="FIXED_ONLY" value="0x891D"/>
+ <enum name="MAX_VARYING_COMPONENTS" value="0x8B4B"/>
+ <enum name="TEXTURE_1D_ARRAY" value="0x8C18"/>
+ <enum name="PROXY_TEXTURE_1D_ARRAY" value="0x8C19"/>
+ <enum name="TEXTURE_2D_ARRAY" value="0x8C1A"/>
+ <enum name="PROXY_TEXTURE_2D_ARRAY" value="0x8C1B"/>
+ <enum name="TEXTURE_BINDING_1D_ARRAY" value="0x8C1C"/>
+ <enum name="TEXTURE_BINDING_2D_ARRAY" value="0x8C1D"/>
+ <enum name="R11F_G11F_B10F" value="0x8C3A"/>
+ <enum name="UNSIGNED_INT_10F_11F_11F_REV" value="0x8C3B"/>
+ <enum name="RGB9_E5" value="0x8C3D"/>
+ <enum name="UNSIGNED_INT_5_9_9_9_REV" value="0x8C3E"/>
+ <enum name="TEXTURE_SHARED_SIZE" value="0x8C3F"/>
+ <enum name="TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH" value="0x8C76"/>
+ <enum name="TRANSFORM_FEEDBACK_BUFFER_MODE" value="0x8C7F"/>
+ <enum name="MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS" value="0x8C80"/>
+ <enum name="TRANSFORM_FEEDBACK_VARYINGS" value="0x8C83"/>
+ <enum name="TRANSFORM_FEEDBACK_BUFFER_START" value="0x8C84"/>
+ <enum name="TRANSFORM_FEEDBACK_BUFFER_SIZE" value="0x8C85"/>
+ <enum name="PRIMITIVES_GENERATED" value="0x8C87"/>
+ <enum name="TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN" value="0x8C88"/>
+ <enum name="RASTERIZER_DISCARD" value="0x8C89"/>
+ <enum name="MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS" value="0x8C8A"/>
+ <enum name="MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS" value="0x8C8B"/>
+ <enum name="INTERLEAVED_ATTRIBS" value="0x8C8C"/>
+ <enum name="SEPARATE_ATTRIBS" value="0x8C8D"/>
+ <enum name="TRANSFORM_FEEDBACK_BUFFER" value="0x8C8E"/>
+ <enum name="TRANSFORM_FEEDBACK_BUFFER_BINDING" value="0x8C8F"/>
+ <enum name="RGBA32UI" value="0x8D70"/>
+ <enum name="RGB32UI" value="0x8D71"/>
+ <enum name="RGBA16UI" value="0x8D76"/>
+ <enum name="RGB16UI" value="0x8D77"/>
+ <enum name="RGBA8UI" value="0x8D7C"/>
+ <enum name="RGB8UI" value="0x8D7D"/>
+ <enum name="RGBA32I" value="0x8D82"/>
+ <enum name="RGB32I" value="0x8D83"/>
+ <enum name="RGBA16I" value="0x8D88"/>
+ <enum name="RGB16I" value="0x8D89"/>
+ <enum name="RGBA8I" value="0x8D8E"/>
+ <enum name="RGB8I" value="0x8D8F"/>
+ <enum name="RED_INTEGER" value="0x8D94"/>
+ <enum name="GREEN_INTEGER" value="0x8D95"/>
+ <enum name="BLUE_INTEGER" value="0x8D96"/>
+ <enum name="RGB_INTEGER" value="0x8D98"/>
+ <enum name="RGBA_INTEGER" value="0x8D99"/>
+ <enum name="BGR_INTEGER" value="0x8D9A"/>
+ <enum name="BGRA_INTEGER" value="0x8D9B"/>
+ <enum name="SAMPLER_1D_ARRAY" value="0x8DC0"/>
+ <enum name="SAMPLER_2D_ARRAY" value="0x8DC1"/>
+ <enum name="SAMPLER_1D_ARRAY_SHADOW" value="0x8DC3"/>
+ <enum name="SAMPLER_2D_ARRAY_SHADOW" value="0x8DC4"/>
+ <enum name="SAMPLER_CUBE_SHADOW" value="0x8DC5"/>
+ <enum name="UNSIGNED_INT_VEC2" value="0x8DC6"/>
+ <enum name="UNSIGNED_INT_VEC3" value="0x8DC7"/>
+ <enum name="UNSIGNED_INT_VEC4" value="0x8DC8"/>
+ <enum name="INT_SAMPLER_1D" value="0x8DC9"/>
+ <enum name="INT_SAMPLER_2D" value="0x8DCA"/>
+ <enum name="INT_SAMPLER_3D" value="0x8DCB"/>
+ <enum name="INT_SAMPLER_CUBE" value="0x8DCC"/>
+ <enum name="INT_SAMPLER_1D_ARRAY" value="0x8DCE"/>
+ <enum name="INT_SAMPLER_2D_ARRAY" value="0x8DCF"/>
+ <enum name="UNSIGNED_INT_SAMPLER_1D" value="0x8DD1"/>
+ <enum name="UNSIGNED_INT_SAMPLER_2D" value="0x8DD2"/>
+ <enum name="UNSIGNED_INT_SAMPLER_3D" value="0x8DD3"/>
+ <enum name="UNSIGNED_INT_SAMPLER_CUBE" value="0x8DD4"/>
+ <enum name="UNSIGNED_INT_SAMPLER_1D_ARRAY" value="0x8DD6"/>
+ <enum name="UNSIGNED_INT_SAMPLER_2D_ARRAY" value="0x8DD7"/>
+ <enum name="QUERY_WAIT" value="0x8E13"/>
+ <enum name="QUERY_NO_WAIT" value="0x8E14"/>
+ <enum name="QUERY_BY_REGION_WAIT" value="0x8E15"/>
+ <enum name="QUERY_BY_REGION_NO_WAIT" value="0x8E16"/>
+ <enum name="BUFFER_ACCESS_FLAGS" value="0x911F"/>
+ <enum name="BUFFER_MAP_LENGTH" value="0x9120"/>
+ <enum name="BUFFER_MAP_OFFSET" value="0x9121"/>
+
+ <function name="ClearBufferiv" offset="assign">
+ <param name="buffer" type="GLenum"/>
+ <param name="drawbuffer" type="GLint"/>
+ <param name="value" type="const GLint *"/>
+ </function>
+
+ <function name="ClearBufferuiv" offset="assign">
+ <param name="buffer" type="GLenum"/>
+ <param name="drawbuffer" type="GLint"/>
+ <param name="value" type="const GLuint *"/>
+ </function>
+
+ <function name="ClearBufferfv" offset="assign">
+ <param name="buffer" type="GLenum"/>
+ <param name="drawbuffer" type="GLint"/>
+ <param name="value" type="const GLfloat *"/>
+ </function>
+
+ <function name="ClearBufferfi" offset="assign">
+ <param name="buffer" type="GLenum"/>
+ <param name="drawbuffer" type="GLint"/>
+ <param name="depth" type="const GLfloat"/>
+ <param name="stencil" type="const GLint"/>
+ </function>
+
+ <function name="GetStringi" offset="assign">
+ <param name="name" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <return type="const GLubyte *"/>
+ </function>
+
+ <function name="IsEnabledi" offset="assign">
+ <param name="cap" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <return type="GLboolean"/>
+ </function>
+
+ <function name="GetFragDataLocation" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="name" type="const GLchar *"/>
+ <return type="GLint"/>
+ </function>
+
+ <function name="BindFragDataLocation" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="color" type="GLuint"/>
+ <param name="name" type="const GLchar *"/>
+ </function>
+
+ <function name="ColorMaski" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="r" type="GLboolean"/>
+ <param name="g" type="GLboolean"/>
+ <param name="b" type="GLboolean"/>
+ <param name="a" type="GLboolean"/>
+ </function>
+
+ <function name="GetBooleani_v" offset="assign">
+ <param name="cap" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="value" type="GLboolean *"/>
+ </function>
+
+ <function name="GetIntegeri_v" offset="assign">
+ <param name="cap" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="value" type="GLint *"/>
+ </function>
+
+ <function name="Enablei" offset="assign">
+ <param name="cap" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ </function>
+
+ <function name="Disablei" offset="assign">
+ <param name="cap" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ </function>
+
+ <function name="BeginTransformFeedback" offset="assign">
+ <param name="mode" type="GLenum"/>
+ </function>
+
+ <function name="EndTransformFeedback" offset="assign">
+ </function>
+
+ <function name="BindBufferRange" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="buffer" type="GLuint"/>
+ <param name="offset" type="GLintptr"/>
+ <param name="size" type="GLsizeiptr"/>
+ </function>
+
+ <function name="BindBufferBase" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="buffer" type="GLuint"/>
+ </function>
+
+ <function name="TransformFeedbackVaryings" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="varyings" type="const GLchar* *"/>
+ <param name="bufferMode" type="GLenum"/>
+ </function>
+
+ <function name="GetTransformFeedbackVarying" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="index" type="GLuint"/>
+ <param name="bufSize" type="GLsizei"/>
+ <param name="length" type="GLsizei *"/>
+ <param name="size" type="GLsizei *"/>
+ <param name="type" type="GLenum *"/>
+ <param name="name" type="GLchar *"/>
+ </function>
+
+ <function name="ClampColor" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="clamp" type="GLenum"/>
+ </function>
+
+ <function name="BeginConditionalRender" offset="assign">
+ <param name="id" type="GLuint"/>
+ <param name="mode" type="GLenum"/>
+ </function>
+
+ <function name="EndConditionalRender" offset="assign">
+ </function>
+
+ <function name="VertexAttribIPointer" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="size" type="GLint"/>
+ <param name="type" type="GLenum"/>
+ <param name="stride" type="GLsizei"/>
+ <param name="pointer" type="const GLvoid *"/>
+ </function>
+
+ <function name="GetVertexAttribIiv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLint *"/>
+ </function>
+
+ <function name="GetVertexAttribIuiv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLuint *"/>
+ </function>
+
+ <function name="VertexAttribI1i" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLint"/>
+ </function>
+
+ <function name="VertexAttribI2i" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLint"/>
+ <param name="y" type="GLint"/>
+ </function>
+
+ <function name="VertexAttribI3i" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLint"/>
+ <param name="y" type="GLint"/>
+ <param name="z" type="GLint"/>
+ </function>
+
+ <function name="VertexAttribI4i" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLint"/>
+ <param name="y" type="GLint"/>
+ <param name="z" type="GLint"/>
+ <param name="w" type="GLint"/>
+ </function>
+
+ <function name="VertexAttribI1ui" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribI2ui" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLuint"/>
+ <param name="y" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribI3ui" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLuint"/>
+ <param name="y" type="GLuint"/>
+ <param name="z" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribI4ui" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="x" type="GLuint"/>
+ <param name="y" type="GLuint"/>
+ <param name="z" type="GLuint"/>
+ <param name="w" type="GLuint"/>
+ </function>
+
+ <function name="VertexAttribI1iv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLint *"/>
+ </function>
+
+ <function name="VertexAttribI2iv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLint *"/>
+ </function>
+
+ <function name="VertexAttribI3iv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLint *"/>
+ </function>
+
+ <function name="VertexAttribI4iv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLint *"/>
+ </function>
+
+ <function name="VertexAttribI1uiv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLuint *"/>
+ </function>
+
+ <function name="VertexAttribI2uiv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLuint *"/>
+ </function>
+
+ <function name="VertexAttribI3uiv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLuint *"/>
+ </function>
+
+ <function name="VertexAttribI4uiv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLuint *"/>
+ </function>
+
+ <function name="VertexAttribI4bv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLbyte *"/>
+ </function>
+
+ <function name="VertexAttribI4sv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLshort *"/>
+ </function>
+
+ <function name="VertexAttribI4ubv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLubyte *"/>
+ </function>
+
+ <function name="VertexAttribI4usv" offset="assign">
+ <param name="index" type="GLuint"/>
+ <param name="v" type="const GLushort *"/>
+ </function>
+
+ <function name="GetUniformuiv" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="location" type="GLint"/>
+ <param name="params" type="GLuint *"/>
+ </function>
+
+ <function name="Uniform1ui" offset="assign">
+ <param name="locatoin" type="GLint"/>
+ <param name="x" type="GLuint"/>
+ </function>
+
+ <function name="Uniform2ui" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="x" type="GLuint"/>
+ <param name="y" type="GLuint"/>
+ </function>
+
+ <function name="Uniform3ui" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="x" type="GLuint"/>
+ <param name="y" type="GLuint"/>
+ <param name="z" type="GLuint"/>
+ </function>
+
+ <function name="Uniform4ui" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="x" type="GLuint"/>
+ <param name="y" type="GLuint"/>
+ <param name="z" type="GLuint"/>
+ <param name="w" type="GLuint"/>
+ </function>
+
+ <function name="Uniform1uiv" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="value" type="const GLuint *"/>
+ </function>
+
+ <function name="Uniform2uiv" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="value" type="const GLuint *"/>
+ </function>
+
+ <function name="Uniform3uiv" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="value" type="const GLuint *"/>
+ </function>
+
+ <function name="Uniform4uiv" offset="assign">
+ <param name="location" type="GLint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="value" type="const GLuint *"/>
+ </function>
+
+ <function name="TexParameterIiv" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="value" type="const GLint *"/>
+ </function>
+
+ <function name="TexParameterIuiv" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="value" type="const GLuint *"/>
+ </function>
+
+ <function name="GetTexParameterIiv" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="value" type="GLint *"/>
+ </function>
+
+ <function name="GetTexParameterIuiv" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="value" type="GLuint *"/>
+ </function>
+
+</category>
+
+
+<category name="3.1">
+
+ <enum name="SAMPLER_2D_RECT" value="0x8B63"/>
+ <enum name="SAMPLER_2D_RECT_SHADOW" value="0x8B64"/>
+ <enum name="SAMPLER_BUFFER" value="0x8DC2"/>
+ <enum name="INT_SAMPLER_2D_RECT" value="0x8DCD"/>
+ <enum name="INT_SAMPLER_BUFFER" value="0x8DD0"/>
+ <enum name="UNSIGNED_INT_SAMPLER_2D_RECT" value="0x8DD5"/>
+ <enum name="UNSIGNED_INT_SAMPLER_BUFFER" value="0x8DD8"/>
+ <enum name="TEXTURE_BUFFER" value="0x8C2A"/>
+ <enum name="MAX_TEXTURE_BUFFER_SIZE" value="0x8C2B"/>
+ <enum name="TEXTURE_BINDING_BUFFER" value="0x8C2C"/>
+ <enum name="TEXTURE_BUFFER_DATA_STORE_BINDING" value="0x8C2D"/>
+ <enum name="TEXTURE_BUFFER_FORMAT" value="0x8C2E"/>
+ <enum name="TEXTURE_RECTANGLE" value="0x84F5"/>
+ <enum name="TEXTURE_BINDING_RECTANGLE" value="0x84F6"/>
+ <enum name="PROXY_TEXTURE_RECTANGLE" value="0x84F7"/>
+ <enum name="MAX_RECTANGLE_TEXTURE_SIZE" value="0x84F8"/>
+ <enum name="RED_SNORM" value="0x8F90"/>
+ <enum name="RG_SNORM" value="0x8F91"/>
+ <enum name="RGB_SNORM" value="0x8F92"/>
+ <enum name="RGBA_SNORM" value="0x8F93"/>
+ <enum name="R8_SNORM" value="0x8F94"/>
+ <enum name="RG8_SNORM" value="0x8F95"/>
+ <enum name="RGB8_SNORM" value="0x8F96"/>
+ <enum name="RGBA8_SNORM" value="0x8F97"/>
+ <enum name="R16_SNORM" value="0x8F98"/>
+ <enum name="RG16_SNORM" value="0x8F99"/>
+ <enum name="RGB16_SNORM" value="0x8F9A"/>
+ <enum name="RGBA16_SNORM" value="0x8F9B"/>
+ <enum name="SIGNED_NORMALIZED" value="0x8F9C"/>
+ <enum name="PRIMITIVE_RESTART" value="0x8F9D"/>
+ <enum name="PRIMITIVE_RESTART_INDEX" value="0x8F9E"/>
+
+ <function name="DrawArraysInstanced" offset="assign">
+ <param name="mode" type="GLenum"/>
+ <param name="first" type="GLint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="primcount" type="GLsizei"/>
+ </function>
+
+ <function name="DrawElementsInstanced" offset="assign">
+ <param name="mode" type="GLenum"/>
+ <param name="count" type="GLsizei"/>
+ <param name="type" type="GLenum"/>
+ <param name="indices" type="const GLvoid *"/>
+ <param name="primcount" type="GLsizei"/>
+ </function>
+
+ <function name="TexBuffer" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="internalFormat" type="GLenum"/>
+ <param name="buffer" type="GLuint"/>
+ </function>
+
+ <function name="glPrimitiveRestartIndex" offset="assign">
+ <param name="index" type="GLuint"/>
+ </function>
+
+</category>
+
+
+<category name="3.2">
+
+ <enum name="CONTEXT_CORE_PROFILE_BIT" value="0x00000001"/>
+ <enum name="CONTEXT_COMPATIBILITY_PROFILE_BIT" value="0x00000002"/>
+ <enum name="LINES_ADJACENCY" value="0x000A"/>
+ <enum name="LINE_STRIP_ADJACENCY" value="0x000B"/>
+ <enum name="TRIANGLES_ADJACENCY" value="0x000C"/>
+ <enum name="TRIANGLE_STRIP_ADJACENCY" value="0x000D"/>
+ <enum name="PROGRAM_POINT_SIZE" value="0x8642"/>
+ <enum name="MAX_GEOMETRY_TEXTURE_IMAGE_UNITS" value="0x8C29"/>
+ <enum name="FRAMEBUFFER_ATTACHMENT_LAYERED" value="0x8DA7"/>
+ <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS" value="0x8DA8"/>
+ <enum name="GEOMETRY_SHADER" value="0x8DD9"/>
+ <enum name="GEOMETRY_VERTICES_OUT" value="0x8916"/>
+ <enum name="GEOMETRY_INPUT_TYPE" value="0x8917"/>
+ <enum name="GEOMETRY_OUTPUT_TYPE" value="0x8918"/>
+ <enum name="MAX_GEOMETRY_UNIFORM_COMPONENTS" value="0x8DDF"/>
+ <enum name="MAX_GEOMETRY_OUTPUT_VERTICES" value="0x8DE0"/>
+ <enum name="MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS" value="0x8DE1"/>
+ <enum name="MAX_VERTEX_OUTPUT_COMPONENTS" value="0x9122"/>
+ <enum name="MAX_GEOMETRY_INPUT_COMPONENTS" value="0x9123"/>
+ <enum name="MAX_GEOMETRY_OUTPUT_COMPONENTS" value="0x9124"/>
+ <enum name="MAX_FRAGMENT_INPUT_COMPONENTS" value="0x9125"/>
+ <enum name="CONTEXT_PROFILE_MASK" value="0x9126"/>
+
+ <function name="GetInteger64i_v" offset="assign">
+ <param name="cap" type="GLenum"/>
+ <param name="index" type="GLuint"/>
+ <param name="data" type="GLint64 *"/>
+ </function>
+
+ <function name="GetBufferParameteri64v" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLint64 *"/>
+ </function>
+
+ <function name="ProgramParameteri" offset="assign">
+ <param name="program" type="GLuint"/>
+ <param name="pname" type="GLenum"/>
+ <param name="value" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTexture" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTextureFace" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="face" type="GLenum"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 1ae0853364..b1389b25f2 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -564,7 +564,8 @@ _mesa_ffsll(int64_t val)
unsigned int
_mesa_bitcount(unsigned int n)
{
-#if defined(__GNUC__)
+#if defined(__GNUC__) && \
+ ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
return __builtin_popcount(n);
#else
unsigned int bits;
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index d28f4ad125..1c263aabca 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -404,7 +404,8 @@ _mesa_is_pow_two(int x)
static INLINE int32_t
_mesa_next_pow_two_32(uint32_t x)
{
-#ifdef __GNUC__
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
uint32_t y = (x != 1);
return (1 + y) << ((__builtin_clz(x - y) ^ 31) );
#else
@@ -422,7 +423,8 @@ _mesa_next_pow_two_32(uint32_t x)
static INLINE int64_t
_mesa_next_pow_two_64(uint64_t x)
{
-#ifdef __GNUC__
+#if defined(__GNUC__) && \
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4)
uint64_t y = (x != 1);
if (sizeof(x) == sizeof(long))
return (1 + y) << ((__builtin_clzl(x - y) ^ 63));
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 4aac5bd97f..e8e67f8030 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -256,7 +256,7 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key)
/* create the colormap/texture now if not already done */
if (!st->pixel_xfer.pixelmap_texture) {
st->pixel_xfer.pixelmap_texture = create_color_map_texture(ctx);
- st->pixel_xfer.pixelmap_sampler_view = st_sampler_view_from_texture(ctx->st->pipe,
+ st->pixel_xfer.pixelmap_sampler_view = st_create_texture_sampler_view(ctx->st->pipe,
st->pixel_xfer.pixelmap_texture);
}
diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
index 5e0c51cff0..56b1383ae3 100644
--- a/src/mesa/state_tracker/st_atom_scissor.c
+++ b/src/mesa/state_tracker/st_atom_scissor.c
@@ -72,12 +72,15 @@ update_scissor( struct st_context *st )
scissor.minx = scissor.miny = scissor.maxx = scissor.maxy = 0;
}
- /* Now invert Y. Pipe drivers use the convention Y=0=top for surfaces
+ /* Now invert Y if needed.
+ * Gallium drivers use the convention Y=0=top for surfaces.
*/
- miny = fb->Height - scissor.maxy;
- maxy = fb->Height - scissor.miny;
- scissor.miny = miny;
- scissor.maxy = maxy;
+ if (st_fb_orientation(fb) == Y_0_TOP) {
+ miny = fb->Height - scissor.maxy;
+ maxy = fb->Height - scissor.miny;
+ scissor.miny = miny;
+ scissor.maxy = maxy;
+ }
if (memcmp(&scissor, &st->state.scissor, sizeof(scissor)) != 0) {
/* state has changed */
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 241c001f94..f4294ac1e6 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -46,6 +46,7 @@
static void
update_textures(struct st_context *st)
{
+ struct pipe_context *pipe = st->pipe;
struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
@@ -84,7 +85,7 @@ update_textures(struct st_context *st)
st->state.num_textures = su + 1;
- sampler_view = st_get_stobj_sampler_view(stObj);
+ sampler_view = st_get_texture_sampler_view(stObj, pipe);
}
/*
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 074fc27711..12bba050a6 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -622,7 +622,7 @@ st_flush_bitmap_cache(struct st_context *st)
cache->trans = NULL;
}
- sv = st_sampler_view_from_texture(st->pipe, cache->texture);
+ sv = st_create_texture_sampler_view(st->pipe, cache->texture);
if (sv) {
draw_bitmap_quad(st->ctx,
cache->xpos,
@@ -756,7 +756,7 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
if (pt) {
- struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt);
+ struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt);
assert(pt->target == PIPE_TEXTURE_2D);
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 0498080ccf..d6fdfaccd6 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -133,7 +133,7 @@ st_BlitFramebuffer(GLcontext *ctx,
return;
util_blit_pixels(st->blit,
- srcSurf, st_get_stobj_sampler_view(srcObj),
+ srcSurf, st_get_texture_sampler_view(srcObj, pipe),
srcX0, srcY0, srcX1, srcY1,
dstSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
@@ -146,7 +146,7 @@ st_BlitFramebuffer(GLcontext *ctx,
struct st_renderbuffer *dstRb =
st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
struct pipe_surface *srcSurf = srcRb->surface;
- struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcRb, pipe);
+ struct pipe_sampler_view *srcView = st_get_renderbuffer_sampler_view(srcRb, pipe);
struct pipe_surface *dstSurf = dstRb->surface;
util_blit_pixels(st->blit,
@@ -182,7 +182,7 @@ st_BlitFramebuffer(GLcontext *ctx,
if ((mask & depthStencil) == depthStencil &&
srcDepthSurf == srcStencilSurf &&
dstDepthSurf == dstStencilSurf) {
- struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcDepthRb, pipe);
+ struct pipe_sampler_view *srcView = st_get_renderbuffer_sampler_view(srcDepthRb, pipe);
/* Blitting depth and stencil values between combined
* depth/stencil buffers. This is the ideal case for such buffers.
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 955e371398..2c18ded2ab 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -834,7 +834,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
struct pipe_resource *pt
= make_texture(st, width, height, format, type, unpack, pixels);
if (pt) {
- struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt);
+ struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt);
if (sv) {
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
@@ -1041,7 +1041,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
if (!pt)
return;
- sv = st_sampler_view_from_texture(st->pipe, pt);
+ sv = st_create_texture_sampler_view(st->pipe, pt);
if (!sv) {
pipe_resource_reference(&pt, NULL);
return;
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
index 3c4fe32090..a924f87223 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -126,7 +126,6 @@ st_bind_surface(GLcontext *ctx, GLenum target,
texImage->TexFormat = st_pipe_format_to_mesa_format(ps->format);
_mesa_set_fetch_functions(texImage, 2);
- stObj->pipe = ctx->st->pipe;
/* FIXME create a non-default sampler view from the pipe_surface? */
pipe_resource_reference(&stImage->pt, ps->texture);
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index aec487b001..de1b8e7dc0 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -310,10 +310,12 @@ st_render_texture(GLcontext *ctx,
struct gl_framebuffer *fb,
struct gl_renderbuffer_attachment *att)
{
+ struct st_context *st = ctx->st;
+ struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = ctx->st->pipe->screen;
struct st_renderbuffer *strb;
struct gl_renderbuffer *rb;
- struct pipe_resource *pt = st_get_texobj_texture(att->Texture);
+ struct pipe_resource *pt = st_get_texobj_resource(att->Texture);
struct st_texture_object *stObj;
const struct gl_texture_image *texImage;
GLint pt_level;
@@ -360,7 +362,8 @@ st_render_texture(GLcontext *ctx,
pipe_surface_reference(&strb->surface, NULL);
- pipe_sampler_view_reference(&strb->sampler_view, st_get_stobj_sampler_view(stObj));
+ pipe_sampler_view_reference(&strb->sampler_view,
+ st_get_texture_sampler_view(stObj, pipe));
assert(strb->rtt_level <= strb->texture->last_level);
@@ -542,11 +545,11 @@ void st_init_fbo_functions(struct dd_function_table *functions)
}
struct pipe_sampler_view *
-st_renderbuffer_get_sampler_view(struct st_renderbuffer *rb,
+st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb,
struct pipe_context *pipe)
{
if (!rb->sampler_view) {
- rb->sampler_view = st_sampler_view_from_texture(pipe, rb->texture);
+ rb->sampler_view = st_create_texture_sampler_view(pipe, rb->texture);
}
return rb->sampler_view;
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index 5f11a7cd8a..beb26ab4da 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -74,7 +74,7 @@ extern void
st_init_fbo_functions(struct dd_function_table *functions);
extern struct pipe_sampler_view *
-st_renderbuffer_get_sampler_view(struct st_renderbuffer *rb,
+st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb,
struct pipe_context *pipe);
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 9479819e83..89f10284ce 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -322,8 +322,6 @@ guess_and_alloc_texture(struct st_context *st,
depth,
usage);
- stObj->pipe = st->pipe;
-
DBG("%s - success\n", __FUNCTION__);
}
@@ -838,7 +836,8 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
struct pipe_screen *screen = pipe->screen;
struct st_texture_image *stImage = st_texture_image(texImage);
struct st_texture_object *stObj = st_texture_object(texObj);
- struct pipe_sampler_view *src_view = st_get_stobj_sampler_view(stObj);
+ struct pipe_sampler_view *src_view =
+ st_get_texture_sampler_view(stObj, pipe);
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
struct pipe_surface *dst_surface;
@@ -1624,7 +1623,7 @@ st_copy_texsubimage(GLcontext *ctx,
}
util_blit_pixels_writemask(ctx->st->blit,
strb->surface,
- st_renderbuffer_get_sampler_view(strb, pipe),
+ st_get_renderbuffer_sampler_view(strb, pipe),
srcX, srcY0,
srcX + width, srcY1,
dest_surface,
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index c753fdca34..5fcb6b9dcf 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -129,7 +129,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
_vbo_CreateContext(ctx);
#if FEATURE_feedback || FEATURE_drawpix
- st->draw = draw_create(); /* for selection/feedback */
+ st->draw = draw_create(pipe); /* for selection/feedback */
/* Disable draw options that might convert points/lines to tris, etc.
* as that would foul-up feedback/selection mode.
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index a28ad8eebb..0889f1a522 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -137,7 +137,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
assert(draw);
draw_set_viewport_state(draw, &st->state.viewport);
draw_set_clip_state(draw, &st->state.clip);
- draw_set_rasterizer_state(draw, &st->state.rasterizer);
+ draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
set_feedback_vertex_format(ctx);
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index f0fe31967c..5b7a962037 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -84,7 +84,7 @@ st_render_mipmap(struct st_context *st,
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_sampler_view *psv = st_get_stobj_sampler_view(stObj);
+ struct pipe_sampler_view *psv = st_get_texture_sampler_view(stObj, pipe);
const uint face = _mesa_tex_target_to_face(target);
assert(target != GL_TEXTURE_3D); /* not done yet */
@@ -107,7 +107,7 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj)
{
struct pipe_context *pipe = ctx->st->pipe;
- struct pipe_resource *pt = st_get_texobj_texture(texObj);
+ struct pipe_resource *pt = st_get_texobj_resource(texObj);
const uint baseLevel = texObj->BaseLevel;
const uint lastLevel = pt->last_level;
const uint face = _mesa_tex_target_to_face(target), zslice = 0;
@@ -213,7 +213,7 @@ st_generate_mipmap(GLcontext *ctx, GLenum target,
{
struct st_context *st = ctx->st;
struct st_texture_object *stObj = st_texture_object(texObj);
- struct pipe_resource *pt = st_get_texobj_texture(texObj);
+ struct pipe_resource *pt = st_get_texobj_resource(texObj);
const uint baseLevel = texObj->BaseLevel;
uint lastLevel;
uint dstLevel;
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 26f9554c9e..5cf17fe530 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -556,7 +556,6 @@ st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target
_mesa_clear_texture_image(ctx, texImage);
}
- stObj->pipe = st->pipe;
pipe_resource_reference(&stImage->pt, tex);
_mesa_dirty_texobj(ctx, texObj, GL_TRUE);
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 76ea7e6950..416468478b 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -34,7 +34,7 @@
#include "main/mtypes.h"
-struct pipe_context;
+
struct pipe_resource;
@@ -76,8 +76,6 @@ struct st_texture_object
*/
struct pipe_sampler_view *sampler_view;
- struct pipe_context *pipe;
-
GLboolean teximage_realloc;
/* True if there is/was a surface bound to this texture object. It helps
@@ -101,7 +99,7 @@ st_texture_object(struct gl_texture_object *obj)
static INLINE struct pipe_resource *
-st_get_texobj_texture(struct gl_texture_object *texObj)
+st_get_texobj_resource(struct gl_texture_object *texObj)
{
struct st_texture_object *stObj = st_texture_object(texObj);
return stObj ? stObj->pt : NULL;
@@ -109,15 +107,15 @@ st_get_texobj_texture(struct gl_texture_object *texObj)
static INLINE struct pipe_resource *
-st_get_stobj_texture(struct st_texture_object *stObj)
+st_get_stobj_resource(struct st_texture_object *stObj)
{
return stObj ? stObj->pt : NULL;
}
static INLINE struct pipe_sampler_view *
-st_sampler_view_from_texture(struct pipe_context *pipe,
- struct pipe_resource *texture)
+st_create_texture_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *texture)
{
struct pipe_sampler_view templ;
@@ -130,14 +128,16 @@ st_sampler_view_from_texture(struct pipe_context *pipe,
static INLINE struct pipe_sampler_view *
-st_get_stobj_sampler_view(struct st_texture_object *stObj)
+st_get_texture_sampler_view(struct st_texture_object *stObj,
+ struct pipe_context *pipe)
+
{
if (!stObj || !stObj->pt) {
return NULL;
}
if (!stObj->sampler_view) {
- stObj->sampler_view = st_sampler_view_from_texture(stObj->pipe, stObj->pt);
+ stObj->sampler_view = st_create_texture_sampler_view(pipe, stObj->pt);
}
return stObj->sampler_view;
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index e83bd9e404..0ccbb42383 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -850,8 +850,11 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
NULL);
}
- /* Free the vertex buffer:
+ /* Free the vertex buffer. Unmap first if needed.
*/
+ if (_mesa_bufferobj_mapped(exec->vtx.bufferobj)) {
+ ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, exec->vtx.bufferobj);
+ }
_mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
}