summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2009-12-17 22:37:15 +0100
committerMichal Krol <[email protected]>2009-12-17 22:37:15 +0100
commit16c6dce013f089d072256652f012b3b604781bfd (patch)
tree077623708990a855f9be2dfeb3925f727e6207e7 /src/gallium/drivers/llvmpipe
parent440fc5bf788201a265892ff2e12bf102e63a2896 (diff)
parent294bd53d4b6b15a6890599c46f14b205a3c738bf (diff)
Merge branch 'master' into pipe-format-simplify
Conflicts: src/gallium/auxiliary/draw/draw_pipe_aaline.c src/gallium/auxiliary/draw/draw_pipe_pstipple.c src/gallium/auxiliary/util/u_blit.c src/gallium/auxiliary/util/u_gen_mipmap.c src/gallium/auxiliary/util/u_surface.c src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c src/gallium/drivers/cell/ppu/cell_texture.c src/gallium/drivers/llvmpipe/lp_texture.c src/gallium/drivers/r300/r300_emit.c src/gallium/drivers/r300/r300_texture.c src/gallium/drivers/softpipe/sp_texture.c src/gallium/drivers/softpipe/sp_tile_cache.c src/gallium/drivers/svga/svga_state_vs.c src/gallium/include/pipe/p_format.h src/gallium/state_trackers/dri/dri_drawable.c src/gallium/state_trackers/egl/egl_surface.c src/gallium/state_trackers/python/p_device.i src/gallium/state_trackers/python/st_softpipe_winsys.c src/gallium/state_trackers/vega/api_filters.c src/gallium/state_trackers/vega/image.c src/gallium/state_trackers/vega/mask.c src/gallium/state_trackers/vega/paint.c src/gallium/state_trackers/vega/renderer.c src/gallium/state_trackers/vega/vg_tracker.c src/gallium/state_trackers/xorg/xorg_crtc.c src/gallium/state_trackers/xorg/xorg_dri2.c src/gallium/state_trackers/xorg/xorg_exa.c src/gallium/state_trackers/xorg/xorg_renderer.c src/gallium/state_trackers/xorg/xorg_xv.c src/gallium/state_trackers/xorg/xvmc/surface.c src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c src/gallium/winsys/drm/radeon/core/radeon_buffer.c src/gallium/winsys/egl_xlib/sw_winsys.c src/gallium/winsys/g3dvl/xlib/xsp_winsys.c src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c src/gallium/winsys/gdi/gdi_softpipe_winsys.c src/gallium/winsys/xlib/xlib_cell.c src/gallium/winsys/xlib/xlib_llvmpipe.c src/gallium/winsys/xlib/xlib_softpipe.c src/mesa/state_tracker/st_cb_fbo.c src/mesa/state_tracker/st_cb_texture.c src/mesa/state_tracker/st_texture.c
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_arit.c11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_debug.c13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_clear.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_debug.h71
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c26
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c117
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c59
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_cache.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c48
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_cache.c11
16 files changed, 308 insertions, 112 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
index 9c59677a741..eea6b5d6a5c 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
@@ -629,7 +629,8 @@ lp_build_abs(struct lp_build_context *bld,
if(type.floating) {
/* Mask out the sign bit */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long)1 << type.width) - 1);
+ unsigned long absMask = ~(1 << (type.width - 1));
+ LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
@@ -1083,7 +1084,7 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log(2) */
- LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
+ LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
}
@@ -1095,7 +1096,7 @@ lp_build_log(struct lp_build_context *bld,
/**
* Generate polynomial.
- * Ex: x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
+ * Ex: coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
*/
static LLVMValueRef
lp_build_polynomial(struct lp_build_context *bld,
@@ -1285,13 +1286,13 @@ lp_build_log2_approx(struct lp_build_context *bld,
/* mant = (float) mantissa(x) */
mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
mant = LLVMBuildOr(bld->builder, mant, one, "");
- mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
+ mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
Elements(lp_build_log2_polynomial));
/* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
- logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
+ logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_debug.c b/src/gallium/drivers/llvmpipe/lp_bld_debug.c
index 59d8f492e60..39dfc51e503 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_debug.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_debug.c
@@ -77,10 +77,10 @@ lp_disassemble(const void* func)
while (ud_disassemble(&ud_obj)) {
#ifdef PIPE_ARCH_X86
- debug_printf("%08lx: ", (unsigned long)ud_insn_off(&ud_obj));
+ debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj));
#endif
#ifdef PIPE_ARCH_X86_64
- debug_printf("%016llx: ", (unsigned long long)ud_insn_off(&ud_obj));
+ debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj));
#endif
#if 0
@@ -115,9 +115,16 @@ lp_disassemble(const void* func)
}
}
- if (ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret)
+ if ((ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret) ||
+ ud_obj.mnemonic == UD_Iinvalid)
break;
}
+
+#if 0
+ /* Print GDB command, useful to verify udis86 output */
+ debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc);
+#endif
+
debug_printf("\n");
#else
(void)func;
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index fe2db04d8fa..a67c70ff25a 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -560,9 +560,9 @@ emit_instruction(
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
- LLVMValueRef *p_floor_log2;
- LLVMValueRef *p_exp;
- LLVMValueRef *p_log2;
+ LLVMValueRef *p_floor_log2 = NULL;
+ LLVMValueRef *p_exp = NULL;
+ LLVMValueRef *p_log2 = NULL;
src0 = emit_fetch( bld, inst, 0, CHAN_X );
src0 = lp_build_abs( &bld->base, src0 );
@@ -763,7 +763,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
tmp0 = lp_build_floor(&bld->base, src0);
- tmp0 = lp_build_sub(&bld->base, tmp0, src0);
+ tmp0 = lp_build_sub(&bld->base, src0, tmp0);
dst0[chan_index] = tmp0;
}
break;
diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c
index bdcff94b9bf..08d9f2e2735 100644
--- a/src/gallium/drivers/llvmpipe/lp_clear.c
+++ b/src/gallium/drivers/llvmpipe/lp_clear.c
@@ -50,6 +50,7 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
double depth, unsigned stencil)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ union util_color uc;
unsigned cv;
uint i;
@@ -64,8 +65,8 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i];
- util_pack_color(rgba, ps->format, &cv);
- lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv);
+ util_pack_color(rgba, ps->format, &uc);
+ lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, uc.ui);
}
llvmpipe->dirty_render_cache = TRUE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index c081f6de036..679e2442743 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -118,6 +118,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
pipe_texture_reference(&llvmpipe->texture[i], NULL);
}
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ lp_destroy_tex_tile_cache(llvmpipe->vertex_tex_cache[i]);
+ pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL);
+ }
+
for (i = 0; i < Elements(llvmpipe->constants); i++) {
if (llvmpipe->constants[i].buffer) {
pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL);
@@ -145,6 +150,11 @@ llvmpipe_is_texture_referenced( struct pipe_context *pipe,
llvmpipe->framebuffer.zsbuf->texture == texture)
return PIPE_REFERENCED_FOR_WRITE;
}
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ if (llvmpipe->vertex_tex_cache[i] &&
+ llvmpipe->vertex_tex_cache[i]->texture == texture)
+ return PIPE_REFERENCED_FOR_READ;
+ }
return PIPE_UNREFERENCED;
}
@@ -181,6 +191,7 @@ llvmpipe_create( struct pipe_screen *screen )
llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states;
+ llvmpipe->pipe.bind_vertex_sampler_states = llvmpipe_bind_vertex_sampler_states;
llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
@@ -206,6 +217,7 @@ llvmpipe_create( struct pipe_screen *screen )
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures;
+ llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures;
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
@@ -234,13 +246,15 @@ llvmpipe_create( struct pipe_screen *screen )
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
llvmpipe->tex_cache[i] = lp_create_tex_tile_cache( screen );
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
+ llvmpipe->vertex_tex_cache[i] = lp_create_tex_tile_cache(screen);
/* vertex shader samplers */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples;
llvmpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX;
- llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->tex_cache[i];
+ llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->vertex_tex_cache[i];
llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i];
}
@@ -260,7 +274,7 @@ llvmpipe_create( struct pipe_screen *screen )
goto fail;
draw_texture_samplers(llvmpipe->draw,
- PIPE_MAX_SAMPLERS,
+ PIPE_MAX_VERTEX_SAMPLERS,
(struct tgsi_sampler **)
llvmpipe->tgsi.vert_samplers_list);
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 3ad95d0bfc2..cc4d5ad5fd9 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -55,6 +55,7 @@ struct llvmpipe_context {
/** Constant state objects */
const struct pipe_blend_state *blend;
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
const struct pipe_depth_stencil_alpha_state *depth_stencil;
const struct pipe_rasterizer_state *rasterizer;
struct lp_fragment_shader *fs;
@@ -68,12 +69,15 @@ struct llvmpipe_context {
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
unsigned num_textures;
+ unsigned num_vertex_samplers;
+ unsigned num_vertex_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers;
@@ -136,6 +140,7 @@ struct llvmpipe_context {
unsigned tex_timestamp;
struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
+ struct llvmpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
unsigned no_rast : 1;
diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h
new file mode 100644
index 00000000000..74b27574942
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_debug.h
@@ -0,0 +1,71 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_DEBUG_H
+#define LP_DEBUG_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+
+extern void
+st_print_current(void);
+
+
+#define DEBUG_PIPE 0x1
+#define DEBUG_TGSI 0x2
+#define DEBUG_TEX 0x4
+#define DEBUG_ASM 0x8
+#define DEBUG_SETUP 0x10
+#define DEBUG_RAST 0x20
+#define DEBUG_QUERY 0x40
+#define DEBUG_SCREEN 0x80
+#define DEBUG_JIT 0x100
+
+#ifdef DEBUG
+extern int LP_DEBUG;
+#else
+#define LP_DEBUG 0
+#endif
+
+void st_debug_init( void );
+
+static INLINE void
+LP_DBG( unsigned flag, const char *fmt, ... )
+{
+ if (LP_DEBUG & flag)
+ {
+ va_list args;
+
+ va_start( args, fmt );
+ debug_vprintf( fmt, args );
+ va_end( args );
+ }
+}
+
+
+#endif /* LP_DEBUG_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index a6ecaa0b2be..9b47415f003 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -36,6 +36,24 @@
#include "lp_winsys.h"
#include "lp_jit.h"
#include "lp_screen.h"
+#include "lp_debug.h"
+
+#ifdef DEBUG
+int LP_DEBUG = 0;
+
+static const struct debug_named_value lp_debug_flags[] = {
+ { "pipe", DEBUG_PIPE },
+ { "tgsi", DEBUG_TGSI },
+ { "tex", DEBUG_TEX },
+ { "asm", DEBUG_ASM },
+ { "setup", DEBUG_SETUP },
+ { "rast", DEBUG_RAST },
+ { "query", DEBUG_QUERY },
+ { "screen", DEBUG_SCREEN },
+ { "jit", DEBUG_JIT },
+ {NULL, 0}
+};
+#endif
static const char *
@@ -59,7 +77,9 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return PIPE_MAX_SAMPLERS;
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- return 0;
+ return PIPE_MAX_VERTEX_SAMPLERS;
+ case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+ return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -257,6 +277,10 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
{
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
+#ifdef DEBUG
+ LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
+#endif
+
if (!screen)
return NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index ffcbc9a379f..b4aabd4d7cc 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -166,7 +166,7 @@ shade_quads(struct llvmpipe_context *llvmpipe,
assert((y % 2) == 0);
depth = llvmpipe->zsbuf_map +
y*llvmpipe->zsbuf_transfer->stride +
- 2*x*llvmpipe->zsbuf_transfer->block.size;
+ 2*x*pf_get_blocksize(llvmpipe->zsbuf_transfer->texture->format);
}
else
depth = NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 7b26ce61a38..d1c74ab07b5 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -126,6 +126,10 @@ void *
llvmpipe_create_sampler_state(struct pipe_context *,
const struct pipe_sampler_state *);
void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
+void
+llvmpipe_bind_vertex_sampler_states(struct pipe_context *,
+ unsigned num_samplers,
+ void **samplers);
void llvmpipe_delete_sampler_state(struct pipe_context *, void *);
void *
@@ -172,6 +176,11 @@ void llvmpipe_set_sampler_textures( struct pipe_context *,
unsigned num,
struct pipe_texture ** );
+void
+llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
+ unsigned num_textures,
+ struct pipe_texture **);
+
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index c753b183c0c..e703964aaa8 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -198,10 +198,14 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe )
unsigned i;
/* vertex shader samplers */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->sampler[i];
- llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->texture[i];
- llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->vertex_samplers[i];
+ llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->vertex_textures[i];
+ llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples;
+ }
+
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ lp_tex_tile_cache_validate_texture( llvmpipe->vertex_tex_cache[i] );
}
/* fragment shader samplers */
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index ee0f69b2af9..22683ff8b42 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -87,6 +87,7 @@
#include "lp_state.h"
#include "lp_quad.h"
#include "lp_tex_sample.h"
+#include "lp_debug.h"
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
@@ -408,59 +409,58 @@ generate_fragment(struct llvmpipe_context *lp,
unsigned i;
unsigned chan;
-#ifdef DEBUG
- tgsi_dump(shader->base.tokens, 0);
- if(key->depth.enabled) {
- debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
- debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
- debug_printf("depth.writemask = %u\n", key->depth.writemask);
- }
- if(key->alpha.enabled) {
- debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
- debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
- }
- if(key->blend.logicop_enable) {
- debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
- }
- else if(key->blend.blend_enable) {
- debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
- debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
- debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
- debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
- debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
- debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
- }
- debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
- for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
- if(key->sampler[i].format) {
- debug_printf("sampler[%u] = \n", i);
- debug_printf(" .format = %s\n",
- pf_name(key->sampler[i].format));
- debug_printf(" .target = %s\n",
- debug_dump_tex_target(key->sampler[i].target, TRUE));
- debug_printf(" .pot = %u %u %u\n",
- key->sampler[i].pot_width,
- key->sampler[i].pot_height,
- key->sampler[i].pot_depth);
- debug_printf(" .wrap = %s %s %s\n",
- debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
- debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
- debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
- debug_printf(" .min_img_filter = %s\n",
- debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
- debug_printf(" .min_mip_filter = %s\n",
- debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
- debug_printf(" .mag_img_filter = %s\n",
- debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
- if(key->sampler[i].compare_mode)
- debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
- debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
- debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
+ if (LP_DEBUG & DEBUG_JIT) {
+ tgsi_dump(shader->base.tokens, 0);
+ if(key->depth.enabled) {
+ debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
+ debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
+ debug_printf("depth.writemask = %u\n", key->depth.writemask);
+ }
+ if(key->alpha.enabled) {
+ debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
+ debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
+ }
+ if(key->blend.logicop_enable) {
+ debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
+ }
+ else if(key->blend.blend_enable) {
+ debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
+ debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
+ debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
+ debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
+ debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
+ debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
+ }
+ debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
+ for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
+ if(key->sampler[i].format) {
+ debug_printf("sampler[%u] = \n", i);
+ debug_printf(" .format = %s\n",
+ pf_name(key->sampler[i].format));
+ debug_printf(" .target = %s\n",
+ debug_dump_tex_target(key->sampler[i].target, TRUE));
+ debug_printf(" .pot = %u %u %u\n",
+ key->sampler[i].pot_width,
+ key->sampler[i].pot_height,
+ key->sampler[i].pot_depth);
+ debug_printf(" .wrap = %s %s %s\n",
+ debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
+ debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
+ debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
+ debug_printf(" .min_img_filter = %s\n",
+ debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
+ debug_printf(" .min_mip_filter = %s\n",
+ debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
+ debug_printf(" .mag_img_filter = %s\n",
+ debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
+ if(key->sampler[i].compare_mode)
+ debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
+ debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
+ debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
+ }
}
}
-#endif
-
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
if(!variant)
return NULL;
@@ -599,8 +599,8 @@ generate_fragment(struct llvmpipe_context *lp,
}
lp_build_conv_mask(builder, fs_type, blend_type,
- fs_mask, num_fs,
- &blend_mask, 1);
+ fs_mask, num_fs,
+ &blend_mask, 1);
/*
* Blending.
@@ -631,16 +631,15 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMRunFunctionPassManager(screen->pass, variant->function);
-#ifdef DEBUG
- LLVMDumpValue(variant->function);
- debug_printf("\n");
-#endif
+ if (LP_DEBUG & DEBUG_JIT) {
+ LLVMDumpValue(variant->function);
+ debug_printf("\n");
+ }
variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
-#ifdef DEBUG
- lp_disassemble(variant->jit_function);
-#endif
+ if (LP_DEBUG & DEBUG_ASM)
+ lp_disassemble(variant->jit_function);
variant->next = shader->variants;
shader->variants = variant;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 8333805a3fd..d382f9ca87e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -78,6 +78,34 @@ llvmpipe_bind_sampler_states(struct pipe_context *pipe,
void
+llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
+ unsigned num_samplers,
+ void **samplers)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ unsigned i;
+
+ assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
+
+ /* Check for no-op */
+ if (num_samplers == llvmpipe->num_vertex_samplers &&
+ !memcmp(llvmpipe->vertex_samplers, samplers, num_samplers * sizeof(void *)))
+ return;
+
+ draw_flush(llvmpipe->draw);
+
+ for (i = 0; i < num_samplers; ++i)
+ llvmpipe->vertex_samplers[i] = samplers[i];
+ for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+ llvmpipe->vertex_samplers[i] = NULL;
+
+ llvmpipe->num_vertex_samplers = num_samplers;
+
+ llvmpipe->dirty |= LP_NEW_SAMPLER;
+}
+
+
+void
llvmpipe_set_sampler_textures(struct pipe_context *pipe,
unsigned num, struct pipe_texture **texture)
{
@@ -117,6 +145,37 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,
void
+llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
+ unsigned num_textures,
+ struct pipe_texture **textures)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ uint i;
+
+ assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+
+ /* Check for no-op */
+ if (num_textures == llvmpipe->num_vertex_textures &&
+ !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ return;
+ }
+
+ draw_flush(llvmpipe->draw);
+
+ for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+ struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+
+ pipe_texture_reference(&llvmpipe->vertex_textures[i], tex);
+ lp_tex_tile_cache_set_texture(llvmpipe->vertex_tex_cache[i], tex);
+ }
+
+ llvmpipe->num_vertex_textures = num_textures;
+
+ llvmpipe->dirty |= LP_NEW_TEXTURE;
+}
+
+
+void
llvmpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.c b/src/gallium/drivers/llvmpipe/lp_tex_cache.c
index c7c4143bc62..a6d9a2c1acf 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_cache.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.c
@@ -155,7 +155,6 @@ lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc)
if (lpt->timestamp != tc->timestamp) {
/* texture was modified, invalidate all cached tiles */
uint i;
- debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
for (i = 0; i < NUM_ENTRIES; i++) {
tc->entries[i].addr.bits.invalid = 1;
}
@@ -291,7 +290,7 @@ lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc,
assert(0);
}
- util_format_read_4ub(tc->tex_trans->format,
+ util_format_read_4ub(tc->tex_trans->texture->format,
(uint8_t *)tile->color, sizeof tile->color[0],
tc->tex_trans_map, tc->tex_trans->stride,
x, y, w, h);
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 9b19cac9729..9e41bc40745 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -50,7 +50,6 @@
/* Simple, maximally packed layout.
*/
-
/* Conventional allocation path for non-display textures:
*/
static boolean
@@ -65,20 +64,15 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
unsigned buffer_size = 0;
- util_format_get_block(lpt->base.format, &lpt->base.block);
-
for (level = 0; level <= pt->last_level; level++) {
unsigned nblocksx, nblocksy;
- pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
- pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
-
/* Allocate storage for whole quads. This is particularly important
* for depth surfaces, which are currently stored in a swizzled format. */
- nblocksx = pf_get_nblocksx(&pt->block, align(width, 2));
- nblocksy = pf_get_nblocksy(&pt->block, align(height, 2));
+ nblocksx = pf_get_nblocksx(pt->format, align(width, 2));
+ nblocksy = pf_get_nblocksy(pt->format, align(height, 2));
- lpt->stride[level] = align(nblocksx*pt->block.size, 16);
+ lpt->stride[level] = align(nblocksx * pf_get_blocksize(pt->format), 16);
lpt->level_offset[level] = buffer_size;
@@ -102,10 +96,6 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
{
struct llvmpipe_winsys *winsys = screen->winsys;
- util_format_get_block(lpt->base.format, &lpt->base.block);
- lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width0);
- lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height0);
-
lpt->dt = winsys->displaytarget_create(winsys,
lpt->base.format,
lpt->base.width0,
@@ -182,8 +172,6 @@ llvmpipe_texture_blanket(struct pipe_screen * screen,
lpt->base = *base;
pipe_reference_init(&lpt->base.reference, 1);
lpt->base.screen = screen;
- lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width0);
- lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height0);
lpt->stride[0] = stride[0];
pipe_buffer_reference(&lpt->buffer, buffer);
@@ -257,11 +245,17 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->level = level;
ps->zslice = zslice;
+ /* XXX shouldn't that rather be
+ tex_height = align(ps->height, 2);
+ to account for alignment done in llvmpipe_texture_layout ?
+ */
if (pt->target == PIPE_TEXTURE_CUBE) {
- ps->offset += face * pt->nblocksy[level] * lpt->stride[level];
+ unsigned tex_height = ps->height;
+ ps->offset += face * pf_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
}
else if (pt->target == PIPE_TEXTURE_3D) {
- ps->offset += zslice * pt->nblocksy[level] * lpt->stride[level];
+ unsigned tex_height = ps->height;
+ ps->offset += zslice * pf_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
}
else {
assert(face == 0);
@@ -302,14 +296,10 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
if (lpt) {
struct pipe_transfer *pt = &lpt->base;
pipe_texture_reference(&pt->texture, texture);
- pt->format = texture->format;
- pt->block = texture->block;
pt->x = x;
pt->y = y;
pt->width = w;
pt->height = h;
- pt->nblocksx = texture->nblocksx[level];
- pt->nblocksy = texture->nblocksy[level];
pt->stride = lptex->stride[level];
pt->usage = usage;
pt->face = face;
@@ -318,11 +308,17 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
lpt->offset = lptex->level_offset[level];
+ /* XXX shouldn't that rather be
+ tex_height = align(u_minify(texture->height0, level), 2)
+ to account for alignment done in llvmpipe_texture_layout ?
+ */
if (texture->target == PIPE_TEXTURE_CUBE) {
- lpt->offset += face * pt->nblocksy * pt->stride;
+ unsigned tex_height = u_minify(texture->height0, level);
+ lpt->offset += face * pf_get_nblocksy(texture->format, tex_height) * pt->stride;
}
else if (texture->target == PIPE_TEXTURE_3D) {
- lpt->offset += zslice * pt->nblocksy * pt->stride;
+ unsigned tex_height = u_minify(texture->height0, level);
+ lpt->offset += zslice * pf_get_nblocksy(texture->format, tex_height) * pt->stride;
}
else {
assert(face == 0);
@@ -354,9 +350,11 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
ubyte *map, *xfer_map;
struct llvmpipe_texture *lpt;
+ enum pipe_format format;
assert(transfer->texture);
lpt = llvmpipe_texture(transfer->texture);
+ format = lpt->base.format;
if(lpt->dt) {
struct llvmpipe_winsys *winsys = screen->winsys;
@@ -381,8 +379,8 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
}
xfer_map = map + llvmpipe_transfer(transfer)->offset +
- transfer->y / transfer->block.height * transfer->stride +
- transfer->x / transfer->block.width * transfer->block.size;
+ transfer->y / pf_get_blockheight(format) * transfer->stride +
+ transfer->x / pf_get_blockwidth(format) * pf_get_blocksize(format);
/*printf("map = %p xfer map = %p\n", map, xfer_map);*/
return xfer_map;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
index ec3e002d628..7a1ecf5107b 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
@@ -252,13 +252,13 @@ lp_flush_tile_cache(struct llvmpipe_tile_cache *tc)
case LP_TILE_STATUS_CLEAR:
/* Actually clear the tiles which were flagged as being in a
* clear state. */
- util_fill_rect(tc->transfer_map, &pt->block, pt->stride,
+ util_fill_rect(tc->transfer_map, pt->texture->format, pt->stride,
x, y, w, h,
tc->clear_val);
break;
case LP_TILE_STATUS_DEFINED:
- lp_tile_write_4ub(pt->format,
+ lp_tile_write_4ub(pt->texture->format,
tile->color,
tc->transfer_map, pt->stride,
x, y, w, h);
@@ -291,6 +291,11 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
assert(tc->surface);
assert(tc->transfer);
+ if(!tc->transfer_map)
+ lp_tile_cache_map_transfers(tc);
+
+ assert(tc->transfer_map);
+
switch(tile->status) {
case LP_TILE_STATUS_CLEAR:
/* don't get tile from framebuffer, just clear it */
@@ -306,7 +311,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
y &= ~(TILE_SIZE - 1);
if (!pipe_clip_tile(x, y, &w, &h, tc->transfer))
- lp_tile_read_4ub(pt->format,
+ lp_tile_read_4ub(pt->texture->format,
tile->color,
tc->transfer_map, tc->transfer->stride,
x, y, w, h);