diff options
Diffstat (limited to 'src/gallium/drivers')
153 files changed, 2006 insertions, 1099 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 0a4da8ecc85..c674d0be633 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -59,7 +59,7 @@ cell_map_constant_buffers(struct cell_context *sp) } } - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0, sp->mapped_constants[PIPE_SHADER_VERTEX], sp->constants[PIPE_SHADER_VERTEX]->size); } diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c index 66d4b3b6a31..0dab34075da 100644 --- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c @@ -408,7 +408,7 @@ gen_blend(const struct pipe_blend_state *blend, int one_reg = -1; int constR_reg = -1, constG_reg = -1, constB_reg = -1, constA_reg = -1; - ASSERT(blend->blend_enable); + ASSERT(blend->rt[0].blend_enable); /* packed RGBA -> float colors */ unpack_colors(f, color_format, fbRGBA_reg, @@ -420,7 +420,7 @@ gen_blend(const struct pipe_blend_state *blend, * because in some cases (like PIPE_BLENDFACTOR_ONE and * PIPE_BLENDFACTOR_ZERO) we can avoid doing unnecessary math. */ - switch (blend->rgb_src_factor) { + switch (blend->rt[0].rgb_src_factor) { case PIPE_BLENDFACTOR_ONE: /* factors = (1,1,1), so term = (R,G,B) */ spe_move(f, term1R_reg, fragR_reg); @@ -574,7 +574,7 @@ gen_blend(const struct pipe_blend_state *blend, * the full term A*factor, not just the factor itself, because * in many cases we can avoid doing unnecessary multiplies. */ - switch (blend->alpha_src_factor) { + switch (blend->rt[0].alpha_src_factor) { case PIPE_BLENDFACTOR_ZERO: /* factor = 0, so term = 0 */ spe_load_float(f, term1A_reg, 0.0f); @@ -648,7 +648,7 @@ gen_blend(const struct pipe_blend_state *blend, * the full term (Rfb,Gfb,Bfb)*(factor), not just the factor itself, because * in many cases we can avoid doing unnecessary multiplies. */ - switch (blend->rgb_dst_factor) { + switch (blend->rt[0].rgb_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* factors = (1,1,1), so term = (Rfb,Gfb,Bfb) */ spe_move(f, term2R_reg, fbR_reg); @@ -786,7 +786,7 @@ gen_blend(const struct pipe_blend_state *blend, * the full term Afb*factor, not just the factor itself, because * in many cases we can avoid doing unnecessary multiplies. */ - switch (blend->alpha_dst_factor) { + switch (blend->rt[0].alpha_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* factor = 1, so term = Afb */ spe_move(f, term2A_reg, fbA_reg); @@ -858,7 +858,7 @@ gen_blend(const struct pipe_blend_state *blend, /* * Combine Src/Dest RGB terms as per the blend equation. */ - switch (blend->rgb_func) { + switch (blend->rt[0].rgb_func) { case PIPE_BLEND_ADD: spe_fa(f, fragR_reg, term1R_reg, term2R_reg); spe_fa(f, fragG_reg, term1G_reg, term2G_reg); @@ -891,7 +891,7 @@ gen_blend(const struct pipe_blend_state *blend, /* * Combine Src/Dest A term */ - switch (blend->alpha_func) { + switch (blend->rt[0].alpha_func) { case PIPE_BLEND_ADD: spe_fa(f, fragA_reg, term1A_reg, term2A_reg); break; @@ -2118,7 +2118,7 @@ cell_gen_fragment_function(struct cell_context *cell, spe_comment(f, 0, "Fetch quad colors from tile"); spe_lqx(f, fbRGBA_reg, color_tile_reg, quad_offset_reg); - if (blend->blend_enable) { + if (blend->rt[0].blend_enable) { spe_comment(f, 0, "Perform blending"); gen_blend(blend, blend_color, f, color_format, fragR_reg, fragG_reg, fragB_reg, fragA_reg, fbRGBA_reg); @@ -2143,9 +2143,9 @@ cell_gen_fragment_function(struct cell_context *cell, gen_logicop(blend, f, rgba_reg, fbRGBA_reg); } - if (blend->colormask != PIPE_MASK_RGBA) { + if (blend->rt[0].colormask != PIPE_MASK_RGBA) { spe_comment(f, 0, "Compute color mask"); - gen_colormask(f, blend->colormask, color_format, rgba_reg, fbRGBA_reg); + gen_colormask(f, blend->rt[0].colormask, color_format, rgba_reg, fbRGBA_reg); } /* Mix fragment colors with framebuffer colors using the quad/pixel mask: diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index d185c6b8497..37b04396b3e 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -86,6 +86,12 @@ cell_get_param(struct pipe_screen *screen, int param) return 0; /* XXX to do */ case PIPE_CAP_TGSI_CONT_SUPPORTED: return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: return 0; } diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index d97c22b2efe..21af7ed1c3f 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -999,23 +999,23 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) /* Does the selected blend mode make use of the source / destination * color (RGB) blend factors? */ - boolean need_color_factor = b->blend_enable - && (b->rgb_func != PIPE_BLEND_MIN) - && (b->rgb_func != PIPE_BLEND_MAX); + boolean need_color_factor = b->rt[0].blend_enable + && (b->rt[0].rgb_func != PIPE_BLEND_MIN) + && (b->rt[0].rgb_func != PIPE_BLEND_MAX); /* Does the selected blend mode make use of the source / destination * alpha blend factors? */ - boolean need_alpha_factor = b->blend_enable - && (b->alpha_func != PIPE_BLEND_MIN) - && (b->alpha_func != PIPE_BLEND_MAX); + boolean need_alpha_factor = b->rt[0].blend_enable + && (b->rt[0].alpha_func != PIPE_BLEND_MIN) + && (b->rt[0].alpha_func != PIPE_BLEND_MAX); - if (b->blend_enable) { - sF[0] = b->rgb_src_factor; + if (b->rt[0].blend_enable) { + sF[0] = b->rt[0].rgb_src_factor; sF[1] = sF[0]; sF[2] = sF[0]; - switch (b->alpha_src_factor & 0x0f) { + switch (b->rt[0].alpha_src_factor & 0x0f) { case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: sF[3] = PIPE_BLENDFACTOR_ONE; break; @@ -1023,30 +1023,30 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) case PIPE_BLENDFACTOR_DST_COLOR: case PIPE_BLENDFACTOR_CONST_COLOR: case PIPE_BLENDFACTOR_SRC1_COLOR: - sF[3] = b->alpha_src_factor + 1; + sF[3] = b->rt[0].alpha_src_factor + 1; break; default: - sF[3] = b->alpha_src_factor; + sF[3] = b->rt[0].alpha_src_factor; } - dF[0] = b->rgb_dst_factor; + dF[0] = b->rt[0].rgb_dst_factor; dF[1] = dF[0]; dF[2] = dF[0]; - switch (b->alpha_dst_factor & 0x0f) { + switch (b->rt[0].alpha_dst_factor & 0x0f) { case PIPE_BLENDFACTOR_SRC_COLOR: case PIPE_BLENDFACTOR_DST_COLOR: case PIPE_BLENDFACTOR_CONST_COLOR: case PIPE_BLENDFACTOR_SRC1_COLOR: - dF[3] = b->alpha_dst_factor + 1; + dF[3] = b->rt[0].alpha_dst_factor + 1; break; default: - dF[3] = b->alpha_dst_factor; + dF[3] = b->rt[0].alpha_dst_factor; } - func[0] = b->rgb_func; + func[0] = b->rt[0].rgb_func; func[1] = func[0]; func[2] = func[0]; - func[3] = b->alpha_func; + func[3] = b->rt[0].alpha_func; } else { sF[0] = PIPE_BLENDFACTOR_ONE; sF[1] = PIPE_BLENDFACTOR_ONE; @@ -1067,7 +1067,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) /* If alpha writing is enabled and the alpha blend mode requires use of * the alpha factor, calculate the alpha factor. */ - if (((b->colormask & 8) != 0) && need_alpha_factor) { + if (((b->rt[0].colormask & 8) != 0) && need_alpha_factor) { src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3], frag[3], pixel[3]); @@ -1091,8 +1091,8 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) src_factor[2] = dst_factor[3]; } else if (need_color_factor) { emit_color_factor_calculation(f, - b->rgb_src_factor, - b->colormask, + b->rt[0].rgb_src_factor, + b->rt[0].colormask, frag, pixel, const_color, src_factor); } @@ -1111,15 +1111,15 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) dst_factor[2] = src_factor[2]; } else if (need_color_factor) { emit_color_factor_calculation(f, - b->rgb_dst_factor, - b->colormask, + b->rt[0].rgb_dst_factor, + b->rt[0].colormask, frag, pixel, const_color, dst_factor); } for (i = 0; i < 4; ++i) { - if ((b->colormask & (1U << i)) != 0) { + if ((b->rt[0].colormask & (1U << i)) != 0) { emit_blend_calculation(f, func[i], sF[i], dF[i], frag[i], src_factor[i], @@ -1216,7 +1216,7 @@ cell_generate_logic_op(struct spe_function *f, /* Short-circuit the noop and invert cases. */ - if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->colormask == 0)) { + if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->rt[0].colormask == 0)) { spe_bi(f, 0, 0, 0); return; } else if (logic_op == PIPE_LOGICOP_INVERT) { diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index b18f4c22ef1..a9d72f84d56 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -100,8 +100,10 @@ struct spu_framebuffer void *depth_start; /**< addr of depth surface in main memory */ enum pipe_format color_format; enum pipe_format depth_format; - uint width, height; /**< size in pixels */ - uint width_tiles, height_tiles; /**< width and height in tiles */ + uint width; /**< width in pixels */ + uint height; /**< height in pixels */ + uint width_tiles; /**< width in tiles */ + uint height_tiles; /**< width in tiles */ uint color_clear_value; uint depth_clear_value; @@ -116,15 +118,23 @@ PIPE_ALIGN_TYPE(16, struct spu_texture_level { void *start; - ushort width, height, depth; + ushort width; + ushort height; + ushort depth; ushort tiles_per_row; uint bytes_per_image; /** texcoord scale factors */ - vector float scale_s, scale_t, scale_r; + vector float scale_s; + vector float scale_t; + vector float scale_r; /** texcoord masks (if REPEAT then size-1, else ~0) */ - vector signed int mask_s, mask_t, mask_r; + vector signed int mask_s; + vector signed int mask_t; + vector signed int mask_r; /** texcoord clamp limits */ - vector signed int max_s, max_t, max_r; + vector signed int max_s; + vector signed int max_t; + vector signed int max_r; }); @@ -166,7 +176,8 @@ struct spu_global boolean read_depth_stencil; /** Current tiles' status */ - ubyte cur_ctile_status, cur_ztile_status; + ubyte cur_ctile_status; + ubyte cur_ztile_status; /** Status of all tiles in framebuffer */ PIPE_ALIGN_VAR(16) ubyte ctile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE]; diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c index 90530f2826f..0d0859f8f33 100644 --- a/src/gallium/drivers/i915/i915_clear.c +++ b/src/gallium/drivers/i915/i915_clear.c @@ -32,7 +32,6 @@ #include "util/u_clear.h" #include "i915_context.h" -#include "i915_state.h" /** diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 89feeade756..a0c80d02286 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -29,12 +29,9 @@ #include "i915_state.h" #include "i915_screen.h" #include "i915_batch.h" -#include "i915_texture.h" -#include "i915_reg.h" #include "draw/draw_context.h" #include "pipe/p_defines.h" -#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "pipe/p_screen.h" @@ -84,7 +81,7 @@ i915_draw_range_elements(struct pipe_context *pipe, } - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915->current.constants[PIPE_SHADER_VERTEX], (i915->current.num_user_constants[PIPE_SHADER_VERTEX] * 4 * sizeof(float))); diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c index c6e6d6fd313..237654d26b2 100644 --- a/src/gallium/drivers/i915/i915_debug.c +++ b/src/gallium/drivers/i915/i915_debug.c @@ -29,7 +29,6 @@ #include "i915_context.h" #include "i915_debug.h" #include "i915_batch.h" -#include "pipe/internal/p_winsys_screen.h" #include "util/u_debug.h" diff --git a/src/gallium/drivers/i915/i915_debug_fp.c b/src/gallium/drivers/i915/i915_debug_fp.c index 9c5b117b6dd..f9c40d8a110 100644 --- a/src/gallium/drivers/i915/i915_debug_fp.c +++ b/src/gallium/drivers/i915/i915_debug_fp.c @@ -29,7 +29,6 @@ #include "i915_reg.h" #include "i915_debug.h" #include "pipe/internal/p_winsys_screen.h" -#include "util/u_memory.h" static void diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index d4ee8f5339b..7b8d66b8aa1 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -117,6 +117,12 @@ i915_get_param(struct pipe_screen *screen, int param) return 8; /* max 128x128x128 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 11; /* max 1024x1024 */ + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: return 0; } diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 0fab6e1bc36..23e4d6b9938 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -30,7 +30,6 @@ #include "draw/draw_context.h" -#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -38,7 +37,6 @@ #include "i915_context.h" #include "i915_reg.h" -#include "i915_state.h" #include "i915_state_inlines.h" #include "i915_fpc.h" @@ -105,13 +103,13 @@ i915_create_blend_state(struct pipe_context *pipe, struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state ); { - unsigned eqRGB = blend->rgb_func; - unsigned srcRGB = blend->rgb_src_factor; - unsigned dstRGB = blend->rgb_dst_factor; + unsigned eqRGB = blend->rt[0].rgb_func; + unsigned srcRGB = blend->rt[0].rgb_src_factor; + unsigned dstRGB = blend->rt[0].rgb_dst_factor; - unsigned eqA = blend->alpha_func; - unsigned srcA = blend->alpha_src_factor; - unsigned dstA = blend->alpha_dst_factor; + unsigned eqA = blend->rt[0].alpha_func; + unsigned srcA = blend->rt[0].alpha_src_factor; + unsigned dstA = blend->rt[0].alpha_dst_factor; /* Special handling for MIN/MAX filter modes handled at * state_tracker level. @@ -148,22 +146,22 @@ i915_create_blend_state(struct pipe_context *pipe, if (blend->dither) cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; - if ((blend->colormask & PIPE_MASK_R) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; - if ((blend->colormask & PIPE_MASK_G) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_G) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_GREEN; - if ((blend->colormask & PIPE_MASK_B) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_B) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_BLUE; - if ((blend->colormask & PIPE_MASK_A) == 0) + if ((blend->rt[0].colormask & PIPE_MASK_A) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA; - if (blend->blend_enable) { - unsigned funcRGB = blend->rgb_func; - unsigned srcRGB = blend->rgb_src_factor; - unsigned dstRGB = blend->rgb_dst_factor; + if (blend->rt[0].blend_enable) { + unsigned funcRGB = blend->rt[0].rgb_func; + unsigned srcRGB = blend->rt[0].rgb_src_factor; + unsigned dstRGB = blend->rt[0].rgb_dst_factor; cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE | SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index 03dd5091a61..f5b0e9f011e 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -33,7 +33,6 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" -#include "i915_fpc.h" diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index cbac4175c8f..e5c6d87215b 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -27,7 +27,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "util/u_memory.h" #include "i915_state_inlines.h" #include "i915_context.h" diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index c693eb30e87..1ff6b9f4c63 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -27,14 +27,8 @@ #include "i915_context.h" #include "i915_blit.h" -#include "i915_state.h" #include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" #include "util/u_format.h" -#include "util/u_tile.h" -#include "util/u_rect.h" /* Assumes all values are within bounds -- no checking at this level - diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c index 50a9e19094b..612e5c1cdd5 100644 --- a/src/gallium/drivers/i915/i915_texture.c +++ b/src/gallium/drivers/i915/i915_texture.c @@ -34,14 +34,12 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "i915_context.h" #include "i915_texture.h" -#include "i915_debug.h" #include "i915_screen.h" #include "intel_winsys.h" diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c index 22607dc6083..003b1fd5bf0 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.c +++ b/src/gallium/drivers/i965/brw_batchbuffer.c @@ -155,7 +155,7 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch, enum pipe_error brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, struct brw_winsys_buffer *buffer, - uint32_t usage, + enum brw_buffer_usage usage, uint32_t delta) { int ret; diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h index 7473f5bea4d..6ca9f617f5e 100644 --- a/src/gallium/drivers/i965/brw_batchbuffer.h +++ b/src/gallium/drivers/i965/brw_batchbuffer.h @@ -64,12 +64,12 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch); * Consider it a convenience function wrapping multple * intel_buffer_dword() calls. */ -int brw_batchbuffer_data(struct brw_batchbuffer *batch, +enum pipe_error brw_batchbuffer_data(struct brw_batchbuffer *batch, const void *data, GLuint bytes, enum cliprect_mode cliprect_mode); -int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, +enum pipe_error brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch, struct brw_winsys_buffer *buffer, enum brw_buffer_usage usage, uint32_t offset); diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index 3e070f5591a..4a543276f54 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -32,7 +32,6 @@ #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" static enum pipe_error prepare_cc_vp( struct brw_context *brw ) diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c index d67a1a62633..ccba205e8c7 100644 --- a/src/gallium/drivers/i965/brw_clip.c +++ b/src/gallium/drivers/i965/brw_clip.c @@ -38,7 +38,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_state.h" #include "brw_pipe_rast.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_line.c b/src/gallium/drivers/i965/brw_clip_line.c index 54282d975ed..66caadc4d53 100644 --- a/src/gallium/drivers/i965/brw_clip_line.c +++ b/src/gallium/drivers/i965/brw_clip_line.c @@ -33,7 +33,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_point.c b/src/gallium/drivers/i965/brw_clip_point.c index e0a5330556d..124156c1b50 100644 --- a/src/gallium/drivers/i965/brw_clip_point.c +++ b/src/gallium/drivers/i965/brw_clip_point.c @@ -31,7 +31,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_clip_tri.c b/src/gallium/drivers/i965/brw_clip_tri.c index 4cde7294ea0..069524bc14f 100644 --- a/src/gallium/drivers/i965/brw_clip_tri.c +++ b/src/gallium/drivers/i965/brw_clip_tri.c @@ -31,7 +31,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" static void release_tmps( struct brw_clip_compile *c ) diff --git a/src/gallium/drivers/i965/brw_clip_util.c b/src/gallium/drivers/i965/brw_clip_util.c index 97a57103105..23e51ee9bcd 100644 --- a/src/gallium/drivers/i965/brw_clip_util.c +++ b/src/gallium/drivers/i965/brw_clip_util.c @@ -32,7 +32,6 @@ #include "brw_defines.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_clip.h" diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c index e67551882dc..d60b7b99b6e 100644 --- a/src/gallium/drivers/i965/brw_context.c +++ b/src/gallium/drivers/i965/brw_context.c @@ -34,7 +34,6 @@ #include "util/u_simple_list.h" #include "brw_context.h" -#include "brw_defines.h" #include "brw_draw.h" #include "brw_state.h" #include "brw_batchbuffer.h" diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c index 3f031577d5a..4b215a001c4 100644 --- a/src/gallium/drivers/i965/brw_curbe.c +++ b/src/gallium/drivers/i965/brw_curbe.c @@ -36,9 +36,7 @@ #include "brw_context.h" #include "brw_defines.h" #include "brw_state.h" -#include "brw_util.h" #include "brw_debug.h" -#include "brw_screen.h" /** diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index ea8d39adaf0..1b5cd23995b 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -34,7 +34,6 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_debug.h" -#include "brw_screen.h" #include "brw_batchbuffer.h" diff --git a/src/gallium/drivers/i965/brw_gs.c b/src/gallium/drivers/i965/brw_gs.c index 921b201bae2..06826635a8a 100644 --- a/src/gallium/drivers/i965/brw_gs.c +++ b/src/gallium/drivers/i965/brw_gs.c @@ -34,7 +34,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_state.h" #include "brw_gs.h" diff --git a/src/gallium/drivers/i965/brw_gs_emit.c b/src/gallium/drivers/i965/brw_gs_emit.c index fd8e2accedd..9b58773b3bd 100644 --- a/src/gallium/drivers/i965/brw_gs_emit.c +++ b/src/gallium/drivers/i965/brw_gs_emit.c @@ -35,7 +35,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_gs.h" static void brw_gs_alloc_regs( struct brw_gs_compile *c, diff --git a/src/gallium/drivers/i965/brw_pipe_blend.c b/src/gallium/drivers/i965/brw_pipe_blend.c index b759a910b63..21f786f8715 100644 --- a/src/gallium/drivers/i965/brw_pipe_blend.c +++ b/src/gallium/drivers/i965/brw_pipe_blend.c @@ -118,14 +118,14 @@ static void *brw_create_blend_state( struct pipe_context *pipe, blend->cc2.logicop_enable = 1; blend->cc5.logicop_func = translate_logicop(templ->logicop_func); } - else if (templ->blend_enable) { - blend->cc6.dest_blend_factor = translate_blend_factor(templ->rgb_dst_factor); - blend->cc6.src_blend_factor = translate_blend_factor(templ->rgb_src_factor); - blend->cc6.blend_function = translate_blend_equation(templ->rgb_func); + else if (templ->rt[0].blend_enable) { + blend->cc6.dest_blend_factor = translate_blend_factor(templ->rt[0].rgb_dst_factor); + blend->cc6.src_blend_factor = translate_blend_factor(templ->rt[0].rgb_src_factor); + blend->cc6.blend_function = translate_blend_equation(templ->rt[0].rgb_func); - blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->alpha_dst_factor); - blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->alpha_src_factor); - blend->cc5.ia_blend_function = translate_blend_equation(templ->alpha_func); + blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->rt[0].alpha_dst_factor); + blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->rt[0].alpha_src_factor); + blend->cc5.ia_blend_function = translate_blend_equation(templ->rt[0].alpha_func); blend->cc3.blend_enable = 1; blend->cc3.ia_blend_enable = @@ -146,10 +146,10 @@ static void *brw_create_blend_state( struct pipe_context *pipe, /* Per-surface color mask -- just follow global state: */ - blend->ss0.writedisable_red = (templ->colormask & PIPE_MASK_R) ? 0 : 1; - blend->ss0.writedisable_green = (templ->colormask & PIPE_MASK_G) ? 0 : 1; - blend->ss0.writedisable_blue = (templ->colormask & PIPE_MASK_B) ? 0 : 1; - blend->ss0.writedisable_alpha = (templ->colormask & PIPE_MASK_A) ? 0 : 1; + blend->ss0.writedisable_red = (templ->rt[0].colormask & PIPE_MASK_R) ? 0 : 1; + blend->ss0.writedisable_green = (templ->rt[0].colormask & PIPE_MASK_G) ? 0 : 1; + blend->ss0.writedisable_blue = (templ->rt[0].colormask & PIPE_MASK_B) ? 0 : 1; + blend->ss0.writedisable_alpha = (templ->rt[0].colormask & PIPE_MASK_A) ? 0 : 1; return (void *)blend; } diff --git a/src/gallium/drivers/i965/brw_pipe_fb.c b/src/gallium/drivers/i965/brw_pipe_fb.c index 5d4e5025f97..c1f049272ac 100644 --- a/src/gallium/drivers/i965/brw_pipe_fb.c +++ b/src/gallium/drivers/i965/brw_pipe_fb.c @@ -3,7 +3,6 @@ #include "pipe/p_state.h" #include "brw_context.h" -#include "brw_debug.h" /** * called from intelDrawBuffer() diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index 81712798a5d..ef6c1bb3155 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -7,7 +7,6 @@ #include "brw_context.h" #include "brw_defines.h" -#include "brw_debug.h" diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index 0ecacac9a3a..a8f9892d71d 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -138,6 +138,9 @@ brw_get_name(struct pipe_screen *screen) case PCI_CHIP_ILM_G: chipset = "ILM_G"; break; + default: + chipset = "unknown"; + break; } util_snprintf(buffer, sizeof(buffer), "i965 (chipset: %s)", chipset); @@ -172,6 +175,12 @@ brw_get_param(struct pipe_screen *screen, int param) return 8; /* max 128x128x128 */ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: return 11; /* max 1024x1024 */ + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: return 0; } diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c index e1986a9dbbd..6e99eaa09d8 100644 --- a/src/gallium/drivers/i965/brw_sf.c +++ b/src/gallium/drivers/i965/brw_sf.c @@ -36,7 +36,6 @@ #include "brw_context.h" #include "brw_pipe_rast.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_sf.h" #include "brw_state.h" diff --git a/src/gallium/drivers/i965/brw_sf_emit.c b/src/gallium/drivers/i965/brw_sf_emit.c index 3b85725e368..497634ec9ed 100644 --- a/src/gallium/drivers/i965/brw_sf_emit.c +++ b/src/gallium/drivers/i965/brw_sf_emit.c @@ -35,7 +35,6 @@ #include "brw_defines.h" #include "brw_context.h" #include "brw_eu.h" -#include "brw_util.h" #include "brw_sf.h" diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c index 16b643ceb28..85c20076fb8 100644 --- a/src/gallium/drivers/i965/brw_state_cache.c +++ b/src/gallium/drivers/i965/brw_state_cache.c @@ -59,7 +59,6 @@ #include "brw_debug.h" #include "brw_state.h" -#include "brw_batchbuffer.h" /* XXX: Fixme - have to include these to get the sizes of the prog_key * structs: diff --git a/src/gallium/drivers/i965/brw_util.c b/src/gallium/drivers/i965/brw_util.c index 458058d668d..1fd2e297137 100644 --- a/src/gallium/drivers/i965/brw_util.c +++ b/src/gallium/drivers/i965/brw_util.c @@ -30,8 +30,6 @@ */ -#include "brw_util.h" -#include "brw_defines.h" diff --git a/src/gallium/drivers/i965/brw_vs.c b/src/gallium/drivers/i965/brw_vs.c index e3ea5a3a135..ca8ee79550d 100644 --- a/src/gallium/drivers/i965/brw_vs.c +++ b/src/gallium/drivers/i965/brw_vs.c @@ -33,9 +33,7 @@ #include "brw_context.h" #include "brw_vs.h" -#include "brw_util.h" #include "brw_state.h" -#include "brw_pipe_rast.h" diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c index 177a5170d23..004e3cb4e6f 100644 --- a/src/gallium/drivers/i965/brw_vs_surface_state.c +++ b/src/gallium/drivers/i965/brw_vs_surface_state.c @@ -31,7 +31,6 @@ #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" #include "brw_winsys.h" /* XXX: disabled true constant buffer functionality diff --git a/src/gallium/drivers/i965/brw_wm_fp.c b/src/gallium/drivers/i965/brw_wm_fp.c index 9c5b527f897..9c67759ad0b 100644 --- a/src/gallium/drivers/i965/brw_wm_fp.c +++ b/src/gallium/drivers/i965/brw_wm_fp.c @@ -41,7 +41,6 @@ #include "tgsi/tgsi_util.h" #include "brw_wm.h" -#include "brw_util.h" #include "brw_debug.h" diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index f92b8198ed3..b01a7f194b7 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -34,7 +34,6 @@ #include "brw_batchbuffer.h" #include "brw_context.h" #include "brw_state.h" -#include "brw_defines.h" #include "brw_screen.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c index 2b4bc5c819d..7245730350c 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c @@ -35,7 +35,6 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_arit.h" #include "lp_bld_logic.h" #include "lp_bld_flow.h" #include "lp_bld_debug.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c index ced7b9c11d7..ad1dbbc9b19 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c @@ -314,9 +314,10 @@ lp_build_blend_aos(LLVMBuilderRef builder, LLVMValueRef dst_term; /* FIXME */ - assert(blend->colormask == 0xf); + assert(blend->independent_blend_enable == 0); + assert(blend->rt[0].colormask == 0xf); - if(!blend->blend_enable) + if(!blend->rt[0].blend_enable) return src; /* It makes no sense to blend unless values are normalized */ @@ -333,14 +334,16 @@ lp_build_blend_aos(LLVMBuilderRef builder, * combinations it is possible to reorder the operations and therefore saving * some instructions. */ - src_term = lp_build_blend_factor(&bld, src, blend->rgb_src_factor, blend->alpha_src_factor, alpha_swizzle); - dst_term = lp_build_blend_factor(&bld, dst, blend->rgb_dst_factor, blend->alpha_dst_factor, alpha_swizzle); + src_term = lp_build_blend_factor(&bld, src, blend->rt[0].rgb_src_factor, + blend->rt[0].alpha_src_factor, alpha_swizzle); + dst_term = lp_build_blend_factor(&bld, dst, blend->rt[0].rgb_dst_factor, + blend->rt[0].alpha_dst_factor, alpha_swizzle); lp_build_name(src_term, "src_term"); lp_build_name(dst_term, "dst_term"); - if(blend->rgb_func == blend->alpha_func) { - return lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term); + if(blend->rt[0].rgb_func == blend->rt[0].alpha_func) { + return lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term); } else { /* Seperate RGB / A functions */ @@ -348,8 +351,8 @@ lp_build_blend_aos(LLVMBuilderRef builder, LLVMValueRef rgb; LLVMValueRef alpha; - rgb = lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term); - alpha = lp_build_blend_func(&bld.base, blend->alpha_func, src_term, dst_term); + rgb = lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term); + alpha = lp_build_blend_func(&bld.base, blend->rt[0].alpha_func, src_term, dst_term); return lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle); } diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c index 9511299d558..a73d1158e79 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c @@ -71,7 +71,6 @@ #include "pipe/p_state.h" #include "lp_bld_type.h" -#include "lp_bld_const.h" #include "lp_bld_arit.h" #include "lp_bld_blend.h" @@ -218,7 +217,7 @@ lp_build_blend_soa(LLVMBuilderRef builder, } for (i = 0; i < 4; ++i) { - if (blend->colormask & (1 << i)) { + if (blend->rt[0].colormask & (1 << i)) { if (blend->logicop_enable) { if(!type.floating) { res[i] = lp_build_logicop(builder, blend->logicop_func, src[i], dst[i]); @@ -226,10 +225,10 @@ lp_build_blend_soa(LLVMBuilderRef builder, else res[i] = dst[i]; } - else if (blend->blend_enable) { - unsigned src_factor = i < 3 ? blend->rgb_src_factor : blend->alpha_src_factor; - unsigned dst_factor = i < 3 ? blend->rgb_dst_factor : blend->alpha_dst_factor; - unsigned func = i < 3 ? blend->rgb_func : blend->alpha_func; + else if (blend->rt[0].blend_enable) { + unsigned src_factor = i < 3 ? blend->rt[0].rgb_src_factor : blend->rt[0].alpha_src_factor; + unsigned dst_factor = i < 3 ? blend->rt[0].rgb_dst_factor : blend->rt[0].alpha_dst_factor; + unsigned func = i < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func; boolean func_commutative = lp_build_blend_func_commutative(func); /* It makes no sense to blend unless values are normalized */ @@ -270,7 +269,7 @@ lp_build_blend_soa(LLVMBuilderRef builder, /* See if this function has been previously applied */ for(j = 0; j < i; ++j) { - unsigned prev_func = j < 3 ? blend->rgb_func : blend->alpha_func; + unsigned prev_func = j < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func; unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func); if((!func_reverse && diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.c b/src/gallium/drivers/llvmpipe/lp_bld_conv.c index 9fa88372022..f77cf787213 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.c @@ -63,11 +63,9 @@ #include "util/u_debug.h" #include "util/u_math.h" -#include "util/u_cpu_detect.h" #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_intr.h" #include "lp_bld_arit.h" #include "lp_bld_pack.h" #include "lp_bld_conv.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c index 10e82f120bb..dfa080b8533 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c @@ -38,7 +38,6 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_logic.h" #include "lp_bld_swizzle.h" #include "lp_bld_format.h" diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c index fb1eda4423b..85e3b1bdd42 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c @@ -47,13 +47,11 @@ #include "tgsi/tgsi_exec.h" #include "lp_bld_type.h" #include "lp_bld_const.h" -#include "lp_bld_intr.h" #include "lp_bld_arit.h" #include "lp_bld_logic.h" #include "lp_bld_swizzle.h" #include "lp_bld_flow.h" #include "lp_bld_tgsi.h" -#include "lp_bld_debug.h" #define LP_MAX_TEMPS 256 diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 3989cce7445..3dd68d5794e 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -33,8 +33,6 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "pipe/internal/p_winsys_screen.h" -#include "pipe/p_inlines.h" #include "util/u_prim.h" #include "lp_buffer.h" diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 07f32848c7f..edd480d7ed9 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -35,7 +35,6 @@ #include "lp_flush.h" #include "lp_context.h" #include "lp_surface.h" -#include "lp_winsys.h" #include "lp_setup.h" diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 9fad7033db5..310fc2b8479 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -40,7 +40,6 @@ #include "lp_debug.h" #include "lp_screen.h" #include "lp_bld_intr.h" -#include "lp_bld_misc.h" #include "lp_jit.h" diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index a3adc81e9f9..ca64c418276 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -115,6 +115,16 @@ llvmpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 0; default: return 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index a7514ee011d..0602e940d92 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -66,7 +66,6 @@ #include "util/u_format.h" #include "util/u_debug_dump.h" #include "util/u_time.h" -#include "pipe/internal/p_winsys_screen.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "tgsi/tgsi_dump.h" @@ -568,7 +567,7 @@ generate_blend(const struct pipe_blend_state *blend, lp_build_blend_soa(builder, blend, type, src, dst, con, res); for(chan = 0; chan < 4; ++chan) { - if(blend->colormask & (1 << chan)) { + if(blend->rt[0].colormask & (1 << chan)) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0); lp_build_name(res[chan], "res.%c", "rgba"[chan]); res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]); @@ -871,15 +870,15 @@ generate_variant(struct llvmpipe_context *lp, 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)); + else if(key->blend.rt[0].blend_enable) { + debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); + debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); + debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); + debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); + debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); + debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); } - debug_printf("blend.colormask = 0x%x\n", key->blend.colormask); + debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { if(key->sampler[i].format) { debug_printf("sampler[%u] = \n", i); @@ -1020,7 +1019,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, pipe_buffer_reference(&llvmpipe->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { - draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, data, size); } @@ -1078,7 +1077,7 @@ make_variant_key(struct llvmpipe_context *lp, enum util_format_swizzle swizzle = format_desc->swizzle[chan]; if(swizzle <= UTIL_FORMAT_SWIZZLE_W) - key->cbuf_blend[i].colormask |= (1 << chan); + key->blend.rt[0].colormask |= (1 << chan); } } @@ -1128,8 +1127,8 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) /* TODO: put this in the variant */ /* TODO: most of these can be relaxed, in particular the colormask */ opaque = !key.blend.logicop_enable && - !key.blend.blend_enable && - key.blend.colormask == 0xf && + !key.blend.rt[0].blend_enable && + key.blend.rt[0].colormask == 0xf && !key.alpha.enabled && !key.depth.enabled && !key.scissor && diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index 0e9f03b90b8..aa4241a80db 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -32,7 +32,6 @@ #include "util/u_surface.h" #include "lp_context.h" #include "lp_state.h" -#include "lp_surface.h" #include "lp_setup.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c index 1a17631a4c6..57ac25ea0cb 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c +++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c @@ -31,7 +31,6 @@ #include "lp_context.h" #include "lp_state.h" -#include "lp_surface.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index 6c29e8d8ace..ee72f6ce4fc 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -38,7 +38,6 @@ #include "lp_bld_type.h" -#include "lp_bld_arit.h" #include "lp_bld_blend.h" #include "lp_bld_debug.h" #include "lp_test.h" @@ -104,18 +103,18 @@ write_tsv_row(FILE *fp, fprintf(fp, "%s\t%s\t%s\t", - blend->rgb_func != blend->alpha_func ? "true" : "false", - blend->rgb_src_factor != blend->alpha_src_factor ? "true" : "false", - blend->rgb_dst_factor != blend->alpha_dst_factor ? "true" : "false"); + blend->rt[0].rgb_func != blend->rt[0].alpha_func ? "true" : "false", + blend->rt[0].rgb_src_factor != blend->rt[0].alpha_src_factor ? "true" : "false", + blend->rt[0].rgb_dst_factor != blend->rt[0].alpha_dst_factor ? "true" : "false"); fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%s\n", - debug_dump_blend_func(blend->rgb_func, TRUE), - debug_dump_blend_factor(blend->rgb_src_factor, TRUE), - debug_dump_blend_factor(blend->rgb_dst_factor, TRUE), - debug_dump_blend_func(blend->alpha_func, TRUE), - debug_dump_blend_factor(blend->alpha_src_factor, TRUE), - debug_dump_blend_factor(blend->alpha_dst_factor, TRUE)); + debug_dump_blend_func(blend->rt[0].rgb_func, TRUE), + debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), + debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), + debug_dump_blend_func(blend->rt[0].alpha_func, TRUE), + debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), + debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); fflush(fp); } @@ -137,12 +136,12 @@ dump_blend_type(FILE *fp, fprintf(fp, " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s", - "rgb_func", debug_dump_blend_func(blend->rgb_func, TRUE), - "rgb_src_factor", debug_dump_blend_factor(blend->rgb_src_factor, TRUE), - "rgb_dst_factor", debug_dump_blend_factor(blend->rgb_dst_factor, TRUE), - "alpha_func", debug_dump_blend_func(blend->alpha_func, TRUE), - "alpha_src_factor", debug_dump_blend_factor(blend->alpha_src_factor, TRUE), - "alpha_dst_factor", debug_dump_blend_factor(blend->alpha_dst_factor, TRUE)); + "rgb_func", debug_dump_blend_func(blend->rt[0].rgb_func, TRUE), + "rgb_src_factor", debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), + "rgb_dst_factor", debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), + "alpha_func", debug_dump_blend_func(blend->rt[0].alpha_func, TRUE), + "alpha_src_factor", debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), + "alpha_dst_factor", debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); fprintf(fp, " ...\n"); fflush(fp); @@ -401,13 +400,15 @@ compute_blend_ref(const struct pipe_blend_state *blend, double src_term[4]; double dst_term[4]; - compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, con, src_term); - compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, con, dst_term); + compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor, + src, src, dst, con, src_term); + compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor, + dst, src, dst, con, dst_term); /* * Combine RGB terms */ - switch (blend->rgb_func) { + switch (blend->rt[0].rgb_func) { case PIPE_BLEND_ADD: ADD_SAT(res[0], src_term[0], dst_term[0]); /* R */ ADD_SAT(res[1], src_term[1], dst_term[1]); /* G */ @@ -440,7 +441,7 @@ compute_blend_ref(const struct pipe_blend_state *blend, /* * Combine A terms */ - switch (blend->alpha_func) { + switch (blend->rt[0].alpha_func) { case PIPE_BLEND_ADD: ADD_SAT(res[3], src_term[3], dst_term[3]); /* A */ break; @@ -806,14 +807,14 @@ test_all(unsigned verbose, FILE *fp) continue; memset(&blend, 0, sizeof blend); - blend.blend_enable = 1; - blend.rgb_func = *rgb_func; - blend.rgb_src_factor = *rgb_src_factor; - blend.rgb_dst_factor = *rgb_dst_factor; - blend.alpha_func = *alpha_func; - blend.alpha_src_factor = *alpha_src_factor; - blend.alpha_dst_factor = *alpha_dst_factor; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = *rgb_func; + blend.rt[0].rgb_src_factor = *rgb_src_factor; + blend.rt[0].rgb_dst_factor = *rgb_dst_factor; + blend.rt[0].alpha_func = *alpha_func; + blend.rt[0].alpha_src_factor = *alpha_src_factor; + blend.rt[0].alpha_dst_factor = *alpha_dst_factor; + blend.rt[0].colormask = PIPE_MASK_RGBA; if(!test_one(verbose, fp, &blend, mode, *type)) success = FALSE; @@ -865,14 +866,14 @@ test_some(unsigned verbose, FILE *fp, unsigned long n) type = &blend_types[rand() % num_types]; memset(&blend, 0, sizeof blend); - blend.blend_enable = 1; - blend.rgb_func = *rgb_func; - blend.rgb_src_factor = *rgb_src_factor; - blend.rgb_dst_factor = *rgb_dst_factor; - blend.alpha_func = *alpha_func; - blend.alpha_src_factor = *alpha_src_factor; - blend.alpha_dst_factor = *alpha_dst_factor; - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = *rgb_func; + blend.rt[0].rgb_src_factor = *rgb_src_factor; + blend.rt[0].rgb_dst_factor = *rgb_dst_factor; + blend.rt[0].alpha_func = *alpha_func; + blend.rt[0].alpha_src_factor = *alpha_src_factor; + blend.rt[0].alpha_dst_factor = *alpha_dst_factor; + blend.rt[0].colormask = PIPE_MASK_RGBA; if(!test_one(verbose, fp, &blend, mode, *type)) success = FALSE; diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c index d59d7681398..7f55f1ae83f 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c @@ -44,7 +44,6 @@ #include "pipe/p_shader_tokens.h" #include "lp_bld_debug.h" #include "lp_bld_type.h" -#include "lp_bld_intr.h" #include "lp_bld_sample.h" #include "lp_bld_tgsi.h" #include "lp_jit.h" diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 36e2ebb41a3..c9b6eb180ff 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -33,7 +33,6 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/internal/p_winsys_screen.h" #include "util/u_format.h" #include "util/u_math.h" diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 7ebc94ed6c7..1ad539d2858 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -260,6 +260,8 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) void nouveau_screen_fini(struct nouveau_screen *screen) { + struct pipe_winsys *ws = screen->base.winsys; nouveau_channel_free(&screen->channel); + ws->destroy(ws); } diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c index 7c5b6e8229a..97538964af8 100644 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -45,6 +45,16 @@ nv04_screen_get_param(struct pipe_screen *screen, int param) case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c index b67f1e16b1c..1fdb764b532 100644 --- a/src/gallium/drivers/nv04/nv04_state.c +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -17,11 +17,11 @@ nv04_blend_state_create(struct pipe_context *pipe, cb = MALLOC(sizeof(struct nv04_blend_state)); - cb->b_enable = cso->blend_enable ? 1 : 0; - cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rgb_src_factor))); - cb->b_dst = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rgb_dst_factor))); + cb->b_enable = cso->rt[0].blend_enable ? 1 : 0; + cb->b_src = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rt[0].rgb_src_factor))); + cb->b_dst = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rt[0].rgb_dst_factor))); return (void *)cb; diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c index 34847718145..2db61d89412 100644 --- a/src/gallium/drivers/nv04/nv04_vbo.c +++ b/src/gallium/drivers/nv04/nv04_vbo.c @@ -45,7 +45,7 @@ void nv04_draw_elements( struct pipe_context *pipe, draw_set_mapped_element_buffer(draw, 0, NULL); } - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, nv04->constbuf[PIPE_SHADER_VERTEX], nv04->constbuf_nr[PIPE_SHADER_VERTEX]); diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 69a6dab866a..4e6bc129943 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -40,6 +40,16 @@ nv10_screen_get_param(struct pipe_screen *screen, int param) case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index ad7def53b12..9aafc604116 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -17,16 +17,16 @@ nv10_blend_state_create(struct pipe_context *pipe, cb = MALLOC(sizeof(struct nv10_blend_state)); - cb->b_enable = cso->blend_enable ? 1 : 0; - cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rgb_src_factor))); - cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rgb_dst_factor))); - - cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | - ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | - ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | - ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); + cb->b_enable = cso->rt[0].blend_enable ? 1 : 0; + cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rt[0].rgb_src_factor))); + cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rt[0].rgb_dst_factor))); + + cb->c_mask = (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); cb->d_enable = cso->dither ? 1 : 0; diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c index 9180c72c9b0..da5c93f0814 100644 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -46,6 +46,7 @@ void nv10_draw_elements( struct pipe_context *pipe, draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, + 0, nv10->constbuf[PIPE_SHADER_VERTEX], nv10->constbuf_nr[PIPE_SHADER_VERTEX]); diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c index d091335063b..df9401bcce0 100644 --- a/src/gallium/drivers/nv20/nv20_screen.c +++ b/src/gallium/drivers/nv20/nv20_screen.c @@ -40,6 +40,16 @@ nv20_screen_get_param(struct pipe_screen *screen, int param) case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c index 45697a60efd..83335c790a0 100644 --- a/src/gallium/drivers/nv20/nv20_state.c +++ b/src/gallium/drivers/nv20/nv20_state.c @@ -17,16 +17,16 @@ nv20_blend_state_create(struct pipe_context *pipe, cb = MALLOC(sizeof(struct nv20_blend_state)); - cb->b_enable = cso->blend_enable ? 1 : 0; - cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rgb_src_factor))); - cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rgb_dst_factor))); - - cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | - ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | - ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | - ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); + cb->b_enable = cso->rt[0].blend_enable ? 1 : 0; + cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rt[0].rgb_src_factor))); + cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rt[0].rgb_dst_factor))); + + cb->c_mask = (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); cb->d_enable = cso->dither ? 1 : 0; diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c index 52991a0d856..6dc95389013 100644 --- a/src/gallium/drivers/nv20/nv20_vbo.c +++ b/src/gallium/drivers/nv20/nv20_vbo.c @@ -45,7 +45,7 @@ void nv20_draw_elements( struct pipe_context *pipe, draw_set_mapped_element_buffer(draw, 0, NULL); } - draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, nv20->constbuf[PIPE_SHADER_VERTEX], nv20->constbuf_nr[PIPE_SHADER_VERTEX]); diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 9ed48178dc2..ee83ec56760 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -67,6 +67,16 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 1; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 065c927a10d..1f4c9642705 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -16,27 +16,27 @@ nv30_blend_state_create(struct pipe_context *pipe, struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(5, 8, 0); - if (cso->blend_enable) { + if (cso->rt[0].blend_enable) { so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3); so_data (so, 1); - so_data (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) | - nvgl_blend_func(cso->rgb_src_factor)); - so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 | - nvgl_blend_func(cso->rgb_dst_factor)); + so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) | + nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rt[0].rgb_dst_factor)); /* FIXME: Gallium assumes GL_EXT_blend_func_separate. It is not the case for NV30 */ so_method(so, rankine, NV34TCL_BLEND_EQUATION, 1); - so_data (so, nvgl_blend_eqn(cso->rgb_func)); + so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); } else { so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1); so_data (so, 0); } so_method(so, rankine, NV34TCL_COLOR_MASK, 1); - so_data (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | - ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | - ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | - ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); if (cso->logicop_enable) { so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2); diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index d826f8c2f5f..a2fd5f6c02f 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -271,7 +271,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe, map = pipe_buffer_map(pscreen, nv40->constbuf[PIPE_SHADER_VERTEX], PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX, + draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX, 0, map, nr); } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 9e55e5a089c..b1a7343b409 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -52,6 +52,16 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) if (screen->curie->grclass == NV40TCL) return 1; return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 0; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 7d990f7d567..7a63fba18c5 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -18,26 +18,26 @@ nv40_blend_state_create(struct pipe_context *pipe, struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(5, 8, 0); - if (cso->blend_enable) { + if (cso->rt[0].blend_enable) { so_method(so, curie, NV40TCL_BLEND_ENABLE, 3); so_data (so, 1); - so_data (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) | - nvgl_blend_func(cso->rgb_src_factor)); - so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 | - nvgl_blend_func(cso->rgb_dst_factor)); + so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) | + nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 | + nvgl_blend_func(cso->rt[0].rgb_dst_factor)); so_method(so, curie, NV40TCL_BLEND_EQUATION, 1); - so_data (so, nvgl_blend_eqn(cso->alpha_func) << 16 | - nvgl_blend_eqn(cso->rgb_func)); + so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func) << 16 | + nvgl_blend_eqn(cso->rt[0].rgb_func)); } else { so_method(so, curie, NV40TCL_BLEND_ENABLE, 1); so_data (so, 0); } so_method(so, curie, NV40TCL_COLOR_MASK, 1); - so_data (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | - ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | - ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | - ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); + so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) | + ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0))); if (cso->logicop_enable) { so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2); diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 22a8498c69b..5c705ccc8f1 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -34,6 +34,11 @@ nv50_flush(struct pipe_context *pipe, unsigned flags, struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_channel *chan = nv50->screen->base.channel; + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(chan, nv50->screen->tesla, 0x1338, 1); + OUT_RING (chan, 0x20); + } + if (flags & PIPE_FLUSH_FRAME) FIRE_RING(chan); } @@ -81,6 +86,10 @@ nv50_destroy(struct pipe_context *pipe) so_ref(NULL, &nv50->state.vtxattr); draw_destroy(nv50->draw); + + if (nv50->screen->cur_ctx == nv50) + nv50->screen->cur_ctx = NULL; + FREE(nv50); } @@ -104,7 +113,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) nv50->pipe.destroy = nv50_destroy; nv50->pipe.draw_arrays = nv50_draw_arrays; + nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced; nv50->pipe.draw_elements = nv50_draw_elements; + nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced; nv50->pipe.clear = nv50_clear; nv50->pipe.flush = nv50_flush; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index d024be6ea95..bebcd95054f 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -29,9 +29,7 @@ #define NV50_CB_PVP 1 #define NV50_CB_PFP 2 #define NV50_CB_PGP 3 -#define NV50_CB_TIC 4 -#define NV50_CB_TSC 5 -#define NV50_CB_PUPLOAD 6 +#define NV50_CB_AUX 4 #define NV50_NEW_BLEND (1 << 0) #define NV50_NEW_ZSA (1 << 1) @@ -137,6 +135,7 @@ struct nv50_state { struct nouveau_stateobj *vtxfmt; struct nouveau_stateobj *vtxbuf; struct nouveau_stateobj *vtxattr; + struct nouveau_stateobj *instbuf; unsigned vtxelt_nr; }; @@ -198,11 +197,22 @@ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); /* nv50_vbo.c */ extern void nv50_draw_arrays(struct pipe_context *, unsigned mode, unsigned start, unsigned count); +extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode, + unsigned start, unsigned count, + unsigned startInstance, + unsigned instanceCount); extern void nv50_draw_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); +extern void nv50_draw_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, + unsigned count, + unsigned startInstance, + unsigned instanceCount); extern void nv50_vbo_validate(struct nv50_context *nv50); /* nv50_clear.c */ diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index acd695b39bc..e74a526c626 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -95,6 +95,8 @@ struct nv50_reg { int vtx; /* vertex index, for GP inputs (TGSI Dimension.Index) */ int indirect[2]; /* index into pc->addr, or -1 */ + + ubyte buf_index; /* c{0 .. 15}[] or g{0 .. 15}[] */ }; #define NV50_MOD_NEG 1 @@ -188,6 +190,7 @@ ctor_reg(struct nv50_reg *reg, unsigned type, int index, int hw) reg->vtx = -1; reg->acc = 0; reg->indirect[0] = reg->indirect[1] = -1; + reg->buf_index = (type == P_CONST) ? 1 : 0; } static INLINE unsigned @@ -474,6 +477,12 @@ is_join(struct nv50_program_exec *e) return FALSE; } +static INLINE boolean +is_control_flow(struct nv50_program_exec *e) +{ + return (e->inst[0] & 2); +} + static INLINE void set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, struct nv50_program_exec *e) @@ -631,7 +640,7 @@ set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s, set_addr(e, pc->addr[src->indirect[0]]); } - e->inst[1] |= (((src->type == P_IMMD) ? 0 : 1) << 22); + e->inst[1] |= (src->buf_index << 22); } /* Never apply nv50_reg::mod in emit_mov, or carefully check the code !!! */ @@ -3163,7 +3172,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (!is_long(pc->p->exec_tail)) convert_to_long(pc, pc->p->exec_tail); else - if (is_immd(pc->p->exec_tail) || is_join(pc->p->exec_tail)) + if (is_immd(pc->p->exec_tail) || + is_join(pc->p->exec_tail) || + is_control_flow(pc->p->exec_tail)) emit_nop(pc); pc->p->exec_tail->inst[1] |= 1; /* set exit bit */ @@ -3272,7 +3283,7 @@ prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn) static unsigned nv50_revdep_reorder(unsigned m[4], unsigned rdep[4]) { - unsigned i, c, x, unsafe; + unsigned i, c, x, unsafe = 0; for (c = 0; c < 4; c++) m[c] = c; @@ -3483,6 +3494,19 @@ load_frontfacing(struct nv50_pc *pc, struct nv50_reg *sv) } static void +load_instance_id(struct nv50_pc *pc, unsigned index) +{ + struct nv50_reg reg, mem; + + ctor_reg(®, P_TEMP, -1, -1); + ctor_reg(&mem, P_CONST, -1, 24); /* startInstance */ + mem.buf_index = 2; + + emit_add_b32(pc, ®, &pc->sysval[index], &mem); + pc->sysval[index] = reg; +} + +static void copy_semantic_info(struct nv50_program *p) { unsigned i, id; @@ -3668,8 +3692,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) } if (p->cfg.regs[0] & (1 << 0)) pc->sysval[vertex_id].hw = rid++; - if (p->cfg.regs[0] & (1 << 4)) + if (p->cfg.regs[0] & (1 << 4)) { pc->sysval[instance_id].hw = rid++; + load_instance_id(pc, instance_id); + } } for (i = 0, rid = 0; i < pc->result_nr; ++i) { @@ -3702,13 +3728,21 @@ nv50_program_tx_prep(struct nv50_pc *pc) copy_semantic_info(p); } else if (p->type == PIPE_SHADER_FRAGMENT) { - int rid, aid, base; + int rid, aid; unsigned n = 0, m = pc->attr_nr - flat_nr; pc->allow32 = TRUE; - base = (TGSI_SEMANTIC_POSITION == - p->info.input_semantic_name[0]) ? 0 : 1; + /* do we read FragCoord ? */ + if (pc->attr_nr && + p->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + /* select FCRD components we want accessible */ + for (c = 0; c < 4; ++c) + if (pc->attr[c].acc) + p->cfg.regs[1] |= 1 << (24 + c); + aid = 0; + } else /* offset by 1 if FCRD.w is needed for pinterp */ + aid = popcnt4(p->cfg.regs[1] >> 24); /* non-flat interpolants have to be mapped to * the lower hardware IDs, so sort them: @@ -3724,12 +3758,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) } copy_semantic_info(p); - if (!base) /* set w-coordinate mask from perspective interp */ - p->cfg.in[0].mask |= p->cfg.regs[1] >> 24; - - aid = popcnt4( /* if fcrd isn't contained in cfg.io */ - base ? (p->cfg.regs[1] >> 24) : p->cfg.in[0].mask); - for (n = 0; n < pc->attr_nr; ++n) { p->cfg.in[n].hw = rid = aid; i = p->cfg.in[n].id; @@ -3751,9 +3779,6 @@ nv50_program_tx_prep(struct nv50_pc *pc) aid += popcnt4(p->cfg.in[n].mask); } - if (!base) - p->cfg.regs[1] |= p->cfg.in[0].mask << 24; - m = popcnt4(p->cfg.regs[1] >> 24); /* set count of non-position inputs and of non-flat @@ -4641,6 +4666,7 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) nouveau_bo_ref(NULL, &p->bo); + FREE(p->immd); nouveau_resource_free(&p->data[0]); p->translated = 0; diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 5a4ab3508b8..9eba4c96115 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -48,7 +48,7 @@ nv50_query_create(struct pipe_context *pipe, unsigned type) assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER); q->type = type; - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 256, + ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 256, 16, &q->bo); if (ret) { FREE(q); @@ -95,11 +95,13 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */ BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); - OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR); + OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR); OUT_RING (chan, 0x00000000); OUT_RING (chan, 0x0100f002); - FIRE_RING (chan); + + BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1); + OUT_RING (chan, 0); } static boolean @@ -123,6 +125,35 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, return q->ready; } +static void +nv50_render_condition(struct pipe_context *pipe, + struct pipe_query *pq, uint mode) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nv50_query *q; + + if (!pq) { + BEGIN_RING(chan, tesla, NV50TCL_COND_MODE, 1); + OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS); + return; + } + q = nv50_query(pq); + + if (mode == PIPE_RENDER_COND_WAIT || + mode == PIPE_RENDER_COND_BY_REGION_WAIT) { + /* XXX: big fence, FIFO semaphore might be better */ + BEGIN_RING(chan, tesla, 0x0110, 1); + OUT_RING (chan, 0); + } + + BEGIN_RING(chan, tesla, NV50TCL_COND_ADDRESS_HIGH, 3); + OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RING (chan, NV50TCL_COND_MODE_RES); +} + void nv50_init_query_functions(struct nv50_context *nv50) { @@ -131,4 +162,5 @@ nv50_init_query_functions(struct nv50_context *nv50) nv50->pipe.begin_query = nv50_query_begin; nv50->pipe.end_query = nv50_query_end; nv50->pipe.get_query_result = nv50_query_result; + nv50->pipe.render_condition = nv50_render_condition; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 73205652cc4..c4465a228ca 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -135,6 +135,16 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case NOUVEAU_CAP_HW_IDXBUF: return 0; + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 1; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; @@ -329,7 +339,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_ref(NULL, &so); /* Static tesla init */ - so = so_new(44, 90, 22); + so = so_new(47, 95, 24); so_method(so, screen->tesla, NV50TCL_COND_MODE, 1); so_data (so, NV50TCL_COND_MODE_ALWAYS); @@ -372,7 +382,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) } for (i = 0; i < 3; i++) { - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (128 * 4) * 4, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4, &screen->constbuf_parm[i]); if (ret) { nv50_screen_destroy(pscreen); @@ -411,6 +421,18 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000031 | (NV50_CB_PMISC << 12)); + /* bind auxiliary constbuf to immediate data bo */ + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); + so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4, + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + so_data (so, (NV50_CB_AUX << 16) | 0x00000200); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); + so_data (so, 0x00000201 | (NV50_CB_AUX << 12)); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); + so_data (so, 0x00000221 | (NV50_CB_AUX << 12)); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 7a155ca9c45..0d786b0f2e3 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -23,6 +23,8 @@ struct nv50_screen { struct nouveau_resource *immd_heap[1]; struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES]; + struct pipe_buffer *strm_vbuf[16]; + struct nouveau_bo *tic; struct nouveau_bo *tsc; diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 6ab33be663d..da8dc933b03 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -31,6 +31,23 @@ #include "nouveau/nouveau_stateobj.h" +static INLINE uint32_t +nv50_colormask(unsigned mask) +{ + uint32_t cmask = 0; + + if (mask & PIPE_MASK_R) + cmask |= 0x0001; + if (mask & PIPE_MASK_G) + cmask |= 0x0010; + if (mask & PIPE_MASK_B) + cmask |= 0x0100; + if (mask & PIPE_MASK_A) + cmask |= 0x1000; + + return cmask; +} + static void * nv50_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) @@ -38,28 +55,37 @@ nv50_blend_state_create(struct pipe_context *pipe, struct nouveau_stateobj *so = so_new(5, 24, 0); struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj); - unsigned cmask = 0, i; + unsigned i, blend_enabled = 0; /*XXX ignored: * - dither */ - if (cso->blend_enable == 0) { - so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + if (cso->independent_blend_enable) { + for (i = 0; i < 8; ++i) { + so_data(so, cso->rt[i].blend_enable); + if (cso->rt[i].blend_enable) + blend_enabled = 1; + } + } else + if (cso->rt[0].blend_enable) { + blend_enabled = 1; for (i = 0; i < 8; i++) - so_data(so, 0); + so_data(so, 1); } else { - so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); for (i = 0; i < 8; i++) - so_data(so, 1); + so_data(so, 0); + } + if (blend_enabled) { so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5); - so_data (so, nvgl_blend_eqn(cso->rgb_func)); - so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_src_factor)); - so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_dst_factor)); - so_data (so, nvgl_blend_eqn(cso->alpha_func)); - so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_src_factor)); + so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].rgb_src_factor)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].rgb_dst_factor)); + so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].alpha_src_factor)); so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); - so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_dst_factor)); + so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].alpha_dst_factor)); } if (cso->logicop_enable == 0 ) { @@ -71,17 +97,15 @@ nv50_blend_state_create(struct pipe_context *pipe, so_data (so, nvgl_logicop_func(cso->logicop_func)); } - if (cso->colormask & PIPE_MASK_R) - cmask |= (1 << 0); - if (cso->colormask & PIPE_MASK_G) - cmask |= (1 << 4); - if (cso->colormask & PIPE_MASK_B) - cmask |= (1 << 8); - if (cso->colormask & PIPE_MASK_A) - cmask |= (1 << 12); so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8); - for (i = 0; i < 8; i++) - so_data(so, cmask); + if (cso->independent_blend_enable) + for (i = 0; i < 8; ++i) + so_data(so, nv50_colormask(cso->rt[i].colormask)); + else { + uint32_t cmask = nv50_colormask(cso->rt[0].colormask); + for (i = 0; i < 8; i++) + so_data(so, cmask); + } bso->pipe = *cso; so_ref(so, &bso->so); diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index fcd07b59cd6..956da9b304c 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -274,6 +274,9 @@ nv50_state_flush_notify(struct nouveau_channel *chan) so_emit_reloc_markers(chan, nv50->state.fragprog); so_emit_reloc_markers(chan, nv50->state.vtxbuf); so_emit_reloc_markers(chan, nv50->screen->static_init); + + if (nv50->state.instbuf) + so_emit_reloc_markers(chan, nv50->state.instbuf); } boolean diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 871536dca9b..9f1a1713032 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -220,11 +220,8 @@ nv50_tex_validate(struct nv50_context *nv50) return; } - /* not sure if the following really do what I think: */ so_method(so, tesla, 0x1330, 1); /* flush TIC */ so_data (so, 0); - so_method(so, tesla, 0x1338, 1); /* flush texture caches */ - so_data (so, 0x20); so_ref(so, &nv50->state.tic_upload); so_ref(NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 89a94d2fe81..bfb1b34d27a 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -40,6 +40,8 @@ nv50_push_elements_u32(struct nv50_context *, uint32_t *, unsigned); static boolean nv50_push_arrays(struct nv50_context *, unsigned, unsigned); +#define NV50_USING_LOATHED_EDGEFLAG(ctx) ((ctx)->vertprog->cfg.edgeflag_in < 16) + static INLINE unsigned nv50_prim(unsigned mode) { @@ -160,6 +162,309 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve) return (hw_type | hw_size); } +/* For instanced drawing from user buffers, hitting the FIFO repeatedly + * with the same vertex data is probably worse than uploading all data. + */ +static boolean +nv50_upload_vtxbuf(struct nv50_context *nv50, unsigned i) +{ + struct nv50_screen *nscreen = nv50->screen; + struct pipe_screen *pscreen = &nscreen->base.base; + struct pipe_buffer *buf = nscreen->strm_vbuf[i]; + struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; + uint8_t *src; + unsigned size = align(vb->buffer->size, 4096); + + if (buf && buf->size < size) + pipe_buffer_reference(&nscreen->strm_vbuf[i], NULL); + + if (!nscreen->strm_vbuf[i]) { + nscreen->strm_vbuf[i] = pipe_buffer_create( + pscreen, 0, PIPE_BUFFER_USAGE_VERTEX, size); + buf = nscreen->strm_vbuf[i]; + } + + src = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ); + if (!src) + return FALSE; + src += vb->buffer_offset; + + size = (vb->max_index + 1) * vb->stride + 16; /* + 16 is for stride 0 */ + if (vb->buffer_offset + size > vb->buffer->size) + size = vb->buffer->size - vb->buffer_offset; + + pipe_buffer_write(pscreen, buf, vb->buffer_offset, size, src); + pipe_buffer_unmap(pscreen, vb->buffer); + + vb->buffer = buf; /* don't pipe_reference, this is a private copy */ + return TRUE; +} + +static void +nv50_upload_user_vbufs(struct nv50_context *nv50) +{ + unsigned i; + + if (nv50->vbo_fifo) + nv50->dirty |= NV50_NEW_ARRAYS; + if (!(nv50->dirty & NV50_NEW_ARRAYS)) + return; + + for (i = 0; i < nv50->vtxbuf_nr; ++i) { + if (nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX) + continue; + nv50_upload_vtxbuf(nv50, i); + } +} + +static void +nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + float v[4]; + + util_format_read_4f(nv50->vtxelt[i].src_format, + v, 0, data, 0, 0, 0, 1, 1); + + switch (nv50->vtxelt[i].nr_components) { + case 4: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_4F_X(i), 4); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + OUT_RINGf (chan, v[2]); + OUT_RINGf (chan, v[3]); + break; + case 3: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_3F_X(i), 3); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + OUT_RINGf (chan, v[2]); + break; + case 2: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_2F_X(i), 2); + OUT_RINGf (chan, v[0]); + OUT_RINGf (chan, v[1]); + break; + case 1: + BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_1F(i), 1); + OUT_RINGf (chan, v[0]); + break; + default: + assert(0); + break; + } +} + +static unsigned +init_per_instance_arrays_immd(struct nv50_context *nv50, + unsigned startInstance, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_bo *bo; + unsigned i, b, count = 0; + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + ++count; + b = nv50->vtxelt[i].vertex_buffer_index; + + pos[i] = nv50->vtxelt[i].src_offset + + nv50->vtxbuf[b].buffer_offset + + startInstance * nv50->vtxbuf[b].stride; + step[i] = startInstance % nv50->vtxelt[i].instance_divisor; + + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + if (!bo->map) + nouveau_bo_map(bo, NOUVEAU_BO_RD); + + nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]); + } + + return count; +} + +static unsigned +init_per_instance_arrays(struct nv50_context *nv50, + unsigned startInstance, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + struct nouveau_bo *bo; + struct nouveau_stateobj *so; + unsigned i, b, count = 0; + const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + if (nv50->vbo_fifo) + return init_per_instance_arrays_immd(nv50, startInstance, + pos, step); + + so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2); + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + ++count; + b = nv50->vtxelt[i].vertex_buffer_index; + + pos[i] = nv50->vtxelt[i].src_offset + + nv50->vtxbuf[b].buffer_offset + + startInstance * nv50->vtxbuf[b].stride; + + if (!startInstance) { + step[i] = 0; + continue; + } + step[i] = startInstance % nv50->vtxelt[i].instance_divisor; + + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + + so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0); + } + + if (count && startInstance) { + so_ref (so, &nv50->state.instbuf); /* for flush notify */ + so_emit(chan, nv50->state.instbuf); + } + so_ref (NULL, &so); + + return count; +} + +static void +step_per_instance_arrays_immd(struct nv50_context *nv50, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_bo *bo; + unsigned i, b; + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + if (++step[i] != nv50->vtxelt[i].instance_divisor) + continue; + b = nv50->vtxelt[i].vertex_buffer_index; + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + + step[i] = 0; + pos[i] += nv50->vtxbuf[b].stride; + + nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]); + } +} + +static void +step_per_instance_arrays(struct nv50_context *nv50, + unsigned pos[16], unsigned step[16]) +{ + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + struct nouveau_bo *bo; + struct nouveau_stateobj *so; + unsigned i, b; + const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; + + if (nv50->vbo_fifo) { + step_per_instance_arrays_immd(nv50, pos, step); + return; + } + + so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2); + + for (i = 0; i < nv50->vtxelt_nr; ++i) { + if (!nv50->vtxelt[i].instance_divisor) + continue; + b = nv50->vtxelt[i].vertex_buffer_index; + + if (++step[i] == nv50->vtxelt[i].instance_divisor) { + step[i] = 0; + pos[i] += nv50->vtxbuf[b].stride; + } + + bo = nouveau_bo(nv50->vtxbuf[b].buffer); + + so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0); + } + + so_ref (so, &nv50->state.instbuf); /* for flush notify */ + so_ref (NULL, &so); + + so_emit(chan, nv50->state.instbuf); +} + +static INLINE void +nv50_unmap_vbufs(struct nv50_context *nv50) +{ + unsigned i; + + for (i = 0; i < nv50->vtxbuf_nr; ++i) + if (nouveau_bo(nv50->vtxbuf[i].buffer)->map) + nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer)); +} + +void +nv50_draw_arrays_instanced(struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count, + unsigned startInstance, unsigned instanceCount) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->tesla->channel; + struct nouveau_grobj *tesla = nv50->screen->tesla; + unsigned i, nz_divisors; + unsigned step[16], pos[16]; + + if (!NV50_USING_LOATHED_EDGEFLAG(nv50)) + nv50_upload_user_vbufs(nv50); + + nv50_state_validate(nv50); + + nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); + OUT_RING (chan, NV50_CB_AUX | (24 << 8)); + OUT_RING (chan, startInstance); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode)); + + if (nv50->vbo_fifo) + nv50_push_arrays(nv50, start, count); + else { + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (chan, start); + OUT_RING (chan, count); + } + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + + for (i = 1; i < instanceCount; i++) { + if (nz_divisors) /* any non-zero array divisors ? */ + step_per_instance_arrays(nv50, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode) | (1 << 28)); + + if (nv50->vbo_fifo) + nv50_push_arrays(nv50, start, count); + else { + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2); + OUT_RING (chan, start); + OUT_RING (chan, count); + } + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + } + nv50_unmap_vbufs(nv50); + + so_ref(NULL, &nv50->state.instbuf); +} + void nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -190,6 +495,8 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); + nv50_unmap_vbufs(nv50); + /* XXX: not sure what to do if ret != TRUE: flush and retry? */ assert(ret); @@ -218,7 +525,7 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map, unsigned nr = count > 2046 ? 2046 : count; int i; - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1); + BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1); for (i = 0; i < nr; i += 2) OUT_RING (chan, (map[i + 1] << 16) | map[i]); @@ -251,7 +558,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, unsigned nr = count > 2046 ? 2046 : count; int i; - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1); + BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1); for (i = 0; i < nr; i += 2) OUT_RING (chan, (map[i + 1] << 16) | map[i]); @@ -276,7 +583,7 @@ nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map, while (count) { unsigned nr = count > 2047 ? 2047 : count; - BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x40000000, nr); + BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, nr); OUT_RINGp (chan, map, nr); count -= nr; @@ -285,6 +592,77 @@ nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map, return TRUE; } +static INLINE void +nv50_draw_elements_inline(struct nv50_context *nv50, + void *map, unsigned indexSize, + unsigned start, unsigned count) +{ + switch (indexSize) { + case 1: + nv50_draw_elements_inline_u08(nv50, map, start, count); + break; + case 2: + nv50_draw_elements_inline_u16(nv50, map, start, count); + break; + case 4: + nv50_draw_elements_inline_u32(nv50, map, start, count); + break; + } +} + +void +nv50_draw_elements_instanced(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count, + unsigned startInstance, unsigned instanceCount) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_channel *chan = tesla->channel; + struct pipe_screen *pscreen = pipe->screen; + void *map; + unsigned i, nz_divisors; + unsigned step[16], pos[16]; + + map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); + + if (!NV50_USING_LOATHED_EDGEFLAG(nv50)) + nv50_upload_user_vbufs(nv50); + + nv50_state_validate(nv50); + + nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2); + OUT_RING (chan, NV50_CB_AUX | (24 << 8)); + OUT_RING (chan, startInstance); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode)); + + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + + for (i = 1; i < instanceCount; ++i) { + if (nz_divisors) /* any non-zero array divisors ? */ + step_per_instance_arrays(nv50, pos, step); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); + OUT_RING (chan, nv50_prim(mode) | (1 << 28)); + + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); + OUT_RING (chan, 0); + } + nv50_unmap_vbufs(nv50); + + so_ref(NULL, &nv50->state.instbuf); +} + void nv50_draw_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, @@ -295,7 +673,6 @@ nv50_draw_elements(struct pipe_context *pipe, struct nouveau_grobj *tesla = nv50->screen->tesla; struct pipe_screen *pscreen = pipe->screen; void *map; - boolean ret; map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); @@ -308,29 +685,15 @@ nv50_draw_elements(struct pipe_context *pipe, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); OUT_RING (chan, nv50_prim(mode)); - switch (indexSize) { - case 1: - ret = nv50_draw_elements_inline_u08(nv50, map, start, count); - break; - case 2: - ret = nv50_draw_elements_inline_u16(nv50, map, start, count); - break; - case 4: - ret = nv50_draw_elements_inline_u32(nv50, map, start, count); - break; - default: - assert(0); - ret = FALSE; - break; - } + + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); + nv50_unmap_vbufs(nv50); + pipe_buffer_unmap(pscreen, indexBuffer); - - /* XXX: what to do if ret != TRUE? Flush and retry? - */ - assert(ret); } static INLINE boolean @@ -343,23 +706,16 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, struct nouveau_stateobj *so; struct nouveau_grobj *tesla = nv50->screen->tesla; struct nouveau_bo *bo = nouveau_bo(vb->buffer); - float *v; + float v[4]; int ret; - enum pipe_format pf = ve->src_format; - const struct util_format_description *desc; - - desc = util_format_description(pf); - assert(desc); - - if ((desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT) || - util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0) != 32) - return FALSE; ret = nouveau_bo_map(bo, NOUVEAU_BO_RD); if (ret) return FALSE; - v = (float *)(bo->map + (vb->buffer_offset + ve->src_offset)); + util_format_read_4f(ve->src_format, v, 0, (uint8_t *)bo->map + + (vb->buffer_offset + ve->src_offset), 0, + 0, 0, 1, 1); so = *pso; if (!so) *pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0); @@ -417,7 +773,7 @@ nv50_vbo_validate(struct nv50_context *nv50) !(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)) nv50->vbo_fifo = 0xffff; - if (nv50->vertprog->cfg.edgeflag_in < 16) + if (NV50_USING_LOATHED_EDGEFLAG(nv50)) nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */ n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr); @@ -445,17 +801,20 @@ nv50_vbo_validate(struct nv50_context *nv50) nv50->vbo_fifo &= ~(1 << i); continue; } - so_data(vtxfmt, hw | i); if (nv50->vbo_fifo) { + so_data (vtxfmt, hw | + (ve->instance_divisor ? (1 << 4) : i)); so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); so_data (vtxbuf, 0); continue; } + so_data(vtxfmt, hw | i); so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3); - so_data (vtxbuf, 0x20000000 | vb->stride); + so_data (vtxbuf, 0x20000000 | + (ve->instance_divisor ? 0 : vb->stride)); so_reloc (vtxbuf, bo, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); @@ -493,7 +852,7 @@ typedef void (*pfn_push)(struct nouveau_channel *, void *); struct nv50_vbo_emitctx { pfn_push push[16]; - void *map[16]; + uint8_t *map[16]; unsigned stride[16]; unsigned nr_ve; unsigned vtx_dwords; @@ -531,19 +890,18 @@ nv50_map_vbufs(struct nv50_context *nv50) for (i = 0; i < nv50->vtxbuf_nr; ++i) { struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; - unsigned size, delta; + unsigned size = vb->stride * (vb->max_index + 1) + 16; if (nouveau_bo(vb->buffer)->map) continue; - size = vb->stride * (vb->max_index + 1); - delta = vb->buffer_offset; - + size = vb->stride * (vb->max_index + 1) + 16; + size = MIN2(size, vb->buffer->size); if (!size) - size = vb->buffer->size - vb->buffer_offset; + size = vb->buffer->size; if (nouveau_bo_map_range(nouveau_bo(vb->buffer), - delta, size, NOUVEAU_BO_RD)) + 0, size, NOUVEAU_BO_RD)) break; } @@ -554,16 +912,6 @@ nv50_map_vbufs(struct nv50_context *nv50) return FALSE; } -static INLINE void -nv50_unmap_vbufs(struct nv50_context *nv50) -{ - unsigned i; - - for (i = 0; i < nv50->vtxbuf_nr; ++i) - if (nouveau_bo(nv50->vtxbuf[i].buffer)->map) - nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer)); -} - static void emit_b32_1(struct nouveau_channel *chan, void *data) { @@ -658,12 +1006,13 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit, ve = &nv50->vtxelt[i]; vb = &nv50->vtxbuf[ve->vertex_buffer_index]; - if (!(nv50->vbo_fifo & (1 << i))) + if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor) continue; n = emit->nr_ve++; emit->stride[n] = vb->stride; - emit->map[n] = nouveau_bo(vb->buffer)->map + + emit->map[n] = (uint8_t *)nouveau_bo(vb->buffer)->map + + vb->buffer_offset + (start * vb->stride + ve->src_offset); desc = util_format_description(ve->src_format); @@ -753,13 +1102,12 @@ nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count) set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */ - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx_next(chan, &emit); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } @@ -780,13 +1128,12 @@ nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count) set_edgeflag(chan, tesla, &emit, *map); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx(chan, &emit, *map++); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } @@ -807,13 +1154,12 @@ nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count) set_edgeflag(chan, tesla, &emit, *map); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx(chan, &emit, *map++); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } @@ -834,13 +1180,12 @@ nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count) set_edgeflag(chan, tesla, &emit, *map); - BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw); + BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw); for (i = 0; i < nr; ++i) emit_vtx(chan, &emit, *map++); count -= nr; } - nv50_unmap_vbufs(nv50); return TRUE; } diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index c14414fff6b..cdedb302209 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -23,8 +23,6 @@ #include "r300_blit.h" #include "r300_context.h" -#include "util/u_rect.h" - static void r300_blitter_save_states(struct r300_context* r300) { util_blitter_save_blend(r300->blitter, r300->blend_state.state); @@ -75,13 +73,15 @@ void r300_clear(struct pipe_context* pipe, */ struct r300_context* r300 = r300_context(pipe); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; r300_blitter_save_states(r300); util_blitter_clear(r300->blitter, - r300->framebuffer_state.width, - r300->framebuffer_state.height, - r300->framebuffer_state.nr_cbufs, + fb->width, + fb->height, + fb->nr_cbufs, buffers, rgba, depth, stencil); } @@ -99,7 +99,7 @@ void r300_surface_copy(struct pipe_context* pipe, * is really transparent. The states will be restored by the blitter once * copying is done. */ r300_blitter_save_states(r300); - util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state); + util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_save_fragment_sampler_states( r300->blitter, r300->sampler_count, (void**)r300->sampler_states); @@ -123,7 +123,7 @@ void r300_surface_fill(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); r300_blitter_save_states(r300); - util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state); + util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_fill(r300->blitter, dst, dstx, dsty, width, height, value); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 5e4f6552c36..9837530a7ac 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -22,9 +22,6 @@ #include "draw/draw_context.h" -#include "tgsi/tgsi_scan.h" - -#include "util/u_hash_table.h" #include "util/u_memory.h" #include "util/u_simple_list.h" @@ -35,30 +32,16 @@ #include "r300_query.h" #include "r300_render.h" #include "r300_screen.h" -#include "r300_state_derived.h" #include "r300_state_invariant.h" #include "r300_texture.h" #include "r300_winsys.h" -static enum pipe_error r300_clear_hash_table(void* key, void* value, - void* data) -{ - FREE(key); - FREE(value); - return PIPE_OK; -} - static void r300_destroy_context(struct pipe_context* context) { struct r300_context* r300 = r300_context(context); struct r300_query* query, * temp; util_blitter_destroy(r300->blitter); - - util_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table, - NULL); - util_hash_table_destroy(r300->shader_hash_table); - draw_destroy(r300->draw); /* Free the OQ BO. */ @@ -72,9 +55,9 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); - FREE(r300->rs_block); + FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); - FREE(r300->vertex_info); + FREE(r300->vertex_format_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); FREE(r300); @@ -87,7 +70,7 @@ r300_is_texture_referenced(struct pipe_context *pipe, { struct pipe_buffer* buf = 0; - r300_get_texture_buffer(texture, &buf, NULL); + r300_get_texture_buffer(pipe->screen, texture, &buf, NULL); return pipe->is_buffer_referenced(pipe, buf); } @@ -129,14 +112,18 @@ static void r300_setup_atoms(struct r300_context* r300) * an upper bound on each atom, to keep the emission machinery from * underallocating space. */ make_empty_list(&r300->atom_list); + R300_INIT_ATOM(invariant, 71); R300_INIT_ATOM(ztop, 2); R300_INIT_ATOM(blend, 8); R300_INIT_ATOM(blend_color, 3); R300_INIT_ATOM(clip, 29); R300_INIT_ATOM(dsa, 8); - R300_INIT_ATOM(rs, 22); + R300_INIT_ATOM(fb, 56); + R300_INIT_ATOM(rs, 25); R300_INIT_ATOM(scissor, 3); R300_INIT_ATOM(viewport, 9); + R300_INIT_ATOM(rs_block, 21); + R300_INIT_ATOM(vertex_format, 26); } struct pipe_context* r300_create_context(struct pipe_screen* screen, @@ -153,8 +140,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.winsys = (struct pipe_winsys*)radeon_winsys; r300->context.screen = screen; - r300_init_debug(r300); - r300->context.destroy = r300_destroy_context; r300->context.clear = r300_clear; @@ -184,16 +169,13 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.is_texture_referenced = r300_is_texture_referenced; r300->context.is_buffer_referenced = r300_is_buffer_referenced; - r300->shader_hash_table = util_hash_table_create(r300_shader_key_hash, - r300_shader_key_compare); - r300_setup_atoms(r300); r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state); - r300->rs_block = CALLOC_STRUCT(r300_rs_block); + r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); - r300->vertex_info = CALLOC_STRUCT(r300_vertex_info); + r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); @@ -210,7 +192,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300_init_state_functions(r300); - r300_emit_invariant_state(r300); + r300->invariant_state.dirty = TRUE; r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 682b9179c83..3f461640a03 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -30,6 +30,8 @@ #include "pipe/p_context.h" #include "pipe/p_inlines.h" +#include "r300_screen.h" + struct r300_context; struct r300_fragment_shader; @@ -82,13 +84,14 @@ struct r300_rs_state { struct pipe_rasterizer_state rs; uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ + uint32_t antialiasing_config; /* R300_GB_AA_CONFIG: 0x4020 */ uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */ uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ - uint32_t depth_scale_front; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ - uint32_t depth_offset_front;/* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ - uint32_t depth_scale_back; /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ - uint32_t depth_offset_back; /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ + float depth_scale; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ + /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ + float depth_offset; /* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ + /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */ uint32_t cull_mode; /* R300_SU_CULL_MODE: 0x42b8 */ uint32_t line_stipple_config; /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */ @@ -136,15 +139,12 @@ struct r300_ztop_state { uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */ }; -#define R300_NEW_FRAMEBUFFERS 0x00000010 #define R300_NEW_FRAGMENT_SHADER 0x00000020 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040 -#define R300_NEW_RS_BLOCK 0x00000100 #define R300_NEW_SAMPLER 0x00000200 #define R300_ANY_NEW_SAMPLERS 0x0001fe00 #define R300_NEW_TEXTURE 0x00040000 #define R300_ANY_NEW_TEXTURES 0x03fc0000 -#define R300_NEW_VERTEX_FORMAT 0x04000000 #define R300_NEW_VERTEX_SHADER 0x08000000 #define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000 #define R300_NEW_QUERY 0x40000000 @@ -269,11 +269,8 @@ struct r300_context { struct r300_query *query_current; struct r300_query query_list; - /* Shader hash table. Used to store vertex formatting information, which - * depends on the combination of both currently loaded shaders. */ - struct util_hash_table* shader_hash_table; /* Vertex formatting information. */ - struct r300_vertex_info* vertex_info; + struct r300_atom vertex_format_state; /* Various CSO state objects. */ /* Beginning of atom list. */ @@ -290,12 +287,12 @@ struct r300_context { struct r300_atom dsa_state; /* Fragment shader. */ struct r300_fragment_shader* fs; - /* Framebuffer state. We currently don't need our own version of this. */ - struct pipe_framebuffer_state framebuffer_state; + /* Framebuffer state. */ + struct r300_atom fb_state; /* Rasterizer state. */ struct r300_atom rs_state; /* RS block state. */ - struct r300_rs_block* rs_block; + struct r300_atom rs_block_state; /* Sampler states. */ struct r300_sampler_state* sampler_states[8]; int sampler_count; @@ -311,6 +308,9 @@ struct r300_context { /* ZTOP state. */ struct r300_atom ztop_state; + /* Invariant state. This must be emitted to get the engine started. */ + struct r300_atom invariant_state; + /* Vertex buffers for Gallium. */ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; @@ -324,9 +324,10 @@ struct r300_context { uint32_t dirty_hw; /* Whether the TCL engine should be in bypass mode. */ boolean tcl_bypass; - - /** Combination of DBG_xxx flags */ - unsigned debug; + /* Whether polygon offset is enabled. */ + boolean polygon_offset_enabled; + /* Z buffer bit depth. */ + uint32_t zbuffer_bpp; }; /* Convenience cast wrapper. */ @@ -340,35 +341,15 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_surface_functions(struct r300_context* r300); -/* Debug functionality. */ - -/** - * Debug flags to disable/enable certain groups of debugging outputs. - * - * \note These may be rather coarse, and the grouping may be impractical. - * If you find, while debugging the driver, that a different grouping - * of these flags would be beneficial, just feel free to change them - * but make sure to update the documentation in r300_debug.c to reflect - * those changes. - */ -/*@{*/ -#define DBG_HELP 0x0000001 -#define DBG_FP 0x0000002 -#define DBG_VP 0x0000004 -#define DBG_CS 0x0000008 -#define DBG_DRAW 0x0000010 -#define DBG_TEX 0x0000020 -#define DBG_FALL 0x0000040 -/*@}*/ - -static INLINE boolean DBG_ON(struct r300_context * ctx, unsigned flags) +static INLINE boolean CTX_DBG_ON(struct r300_context * ctx, unsigned flags) { - return (ctx->debug & flags) ? TRUE : FALSE; + return SCREEN_DBG_ON(r300_screen(ctx->context.screen), flags); } -static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * fmt, ...) +static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags, + const char * fmt, ...) { - if (DBG_ON(ctx, flags)) { + if (CTX_DBG_ON(ctx, flags)) { va_list va; va_start(va, fmt); debug_vprintf(fmt, va); @@ -376,6 +357,8 @@ static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * f } } -void r300_init_debug(struct r300_context * ctx); +#define DBG_ON CTX_DBG_ON +#define DBG CTX_DBG #endif /* R300_CONTEXT_H */ + diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 2a6ed54ac9b..b881730848a 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -22,8 +22,6 @@ #include "r300_context.h" -#include <ctype.h> - struct debug_option { const char * name; @@ -46,7 +44,7 @@ static struct debug_option debug_options[] = { { 0, 0, 0 } }; -void r300_init_debug(struct r300_context * ctx) +void r300_init_debug(struct r300_screen * screen) { const char * options = debug_get_option("RADEON_DEBUG", 0); boolean printhint = FALSE; @@ -64,7 +62,7 @@ void r300_init_debug(struct r300_context * ctx) for(opt = debug_options; opt->name; ++opt) { if (!strncmp(options, opt->name, length)) { - ctx->debug |= opt->flag; + screen->debug |= opt->flag; break; } } @@ -77,11 +75,11 @@ void r300_init_debug(struct r300_context * ctx) options += length; } - if (!ctx->debug) + if (!screen->debug) printhint = TRUE; } - if (printhint || ctx->debug & DBG_HELP) { + if (printhint || screen->debug & DBG_HELP) { debug_printf("You can enable debug output by setting the RADEON_DEBUG environment variable\n" "to a comma-separated list of debug options. Available options are:\n"); for(opt = debug_options; opt->name; ++opt) { diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 9f93327e598..a429457625a 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,20 +32,20 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" -#include "r300_state_derived.h" #include "r300_state_inlines.h" -#include "r300_texture.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, void* state) { struct r300_blend_state* blend = (struct r300_blend_state*)state; + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); BEGIN_CS(8); OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop); OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3); - if (r300->framebuffer_state.nr_cbufs) { + if (fb->nr_cbufs) { OUT_CS(blend->blend_control); OUT_CS(blend->alpha_blend_control); OUT_CS(blend->color_channel_mask); @@ -112,6 +112,8 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state) { struct r300_dsa_state* dsa = (struct r300_dsa_state*)state; struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6); @@ -124,7 +126,7 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state) OUT_CS_REG_SEQ(R300_ZB_CNTL, 3); - if (r300->framebuffer_state.zsbuf) { + if (fb->zsbuf) { OUT_CS(dsa->z_buffer_control); OUT_CS(dsa->z_stencil_control); } else { @@ -168,9 +170,8 @@ static const float * get_shader_constant( vec[1] = 1.0 / tex->height0; break; - /* Texture compare-fail value. */ - /* XXX Since Gallium doesn't support GL_ARB_shadow_ambient, - * this is always (0,0,0,0), right? */ + /* Texture compare-fail value. Shouldn't ever show up, but if + * it does, we'll be ready. */ case RC_STATE_SHADOW_AMBIENT: vec[3] = 0; break; @@ -384,17 +385,14 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300, END_CS; } -void r300_emit_fb_state(struct r300_context* r300, - struct pipe_framebuffer_state* fb) +void r300_emit_fb_state(struct r300_context* r300, void* state) { + struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_texture* tex; struct pipe_surface* surf; int i; CS_LOCALS(r300); - /* Shouldn't fail unless there is a bug in the state tracker. */ - assert(fb->nr_cbufs <= 4); - BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + (fb->zsbuf ? 10 : 0) + 6); @@ -407,7 +405,14 @@ void r300_emit_fb_state(struct r300_context* r300, R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); /* Set the number of colorbuffers. */ - OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs)); + if (fb->nr_cbufs > 1) { + OUT_CS_REG(R300_RB3D_CCTL, + R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) | + R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE | + R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE); + } else { + OUT_CS_REG(R300_RB3D_CCTL, 0x0); + } /* Set up colorbuffers. */ for (i = 0; i < fb->nr_cbufs; i++) { @@ -584,19 +589,40 @@ void r300_emit_query_end(struct r300_context* r300) void r300_emit_rs_state(struct r300_context* r300, void* state) { struct r300_rs_state* rs = (struct r300_rs_state*)state; + float scale, offset; CS_LOCALS(r300); - BEGIN_CS(22); + BEGIN_CS(20 + (rs->polygon_offset_enable ? 5 : 0)); OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); + + OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config); + OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size); OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2); OUT_CS(rs->point_minmax); OUT_CS(rs->line_control); - OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6); - OUT_CS(rs->depth_scale_front); - OUT_CS(rs->depth_offset_front); - OUT_CS(rs->depth_scale_back); - OUT_CS(rs->depth_offset_back); + + if (rs->polygon_offset_enable) { + scale = rs->depth_scale * 12; + offset = rs->depth_offset; + + switch (r300->zbuffer_bpp) { + case 16: + offset *= 4; + break; + case 24: + offset *= 2; + break; + } + + OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); + OUT_CS_32F(scale); + OUT_CS_32F(offset); + OUT_CS_32F(scale); + OUT_CS_32F(offset); + } + + OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2); OUT_CS(rs->polygon_offset_enable); OUT_CS(rs->cull_mode); OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config); @@ -606,10 +632,10 @@ void r300_emit_rs_state(struct r300_context* r300, void* state) END_CS; } -void r300_emit_rs_block_state(struct r300_context* r300, - struct r300_rs_block* rs) +void r300_emit_rs_block_state(struct r300_context* r300, void* state) { - int i; + struct r300_rs_block* rs = (struct r300_rs_block*)state; + unsigned i; struct r300_screen* r300screen = r300_screen(r300->context.screen); CS_LOCALS(r300); @@ -652,11 +678,13 @@ void r300_emit_scissor_state(struct r300_context* r300, void* state) uint32_t top_left, bottom_right; struct r300_screen* r300screen = r300_screen(r300->context.screen); struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state; + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); minx = miny = 0; - maxx = r300->framebuffer_state.width; - maxy = r300->framebuffer_state.height; + maxx = fb->width; + maxy = fb->height; if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) { minx = MAX2(minx, scissor->minx); @@ -665,6 +693,22 @@ void r300_emit_scissor_state(struct r300_context* r300, void* state) maxy = MIN2(maxy, scissor->maxy); } + /* Special case for zero-area scissor. + * + * We can't allow the variables maxx and maxy to be zero because they are + * subtracted from later in the code, which would cause emitting ~0 and + * making the kernel checker angry. + * + * Let's consider we change maxx and maxy to 1, which is effectively + * a one-pixel area. We must then change minx and miny to a number which is + * greater than 1 to get the zero area back. */ + if (!maxx || !maxy) { + minx = 2; + miny = 2; + maxx = 1; + maxy = 1; + } + if (r300screen->caps->is_r500) { top_left = (minx << R300_SCISSORS_X_SHIFT) | @@ -705,12 +749,18 @@ void r300_emit_texture(struct r300_context* r300, filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); } - /* determine min/max levels */ - /* the MAX_MIP level is the largest (finest) one */ - max_level = MIN2(sampler->max_lod, tex->tex.last_level); - min_level = MIN2(sampler->min_lod, max_level); - format0 |= R300_TX_NUM_LEVELS(max_level); - filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); + if (tex->is_npot) { + /* NPOT textures don't support mip filter, unfortunately. + * This prevents incorrect rendering. */ + filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK; + } else { + /* determine min/max levels */ + /* the MAX_MIP level is the largest (finest) one */ + max_level = MIN2(sampler->max_lod, tex->tex.last_level); + min_level = MIN2(sampler->min_lod, max_level); + format0 |= R300_TX_NUM_LEVELS(max_level); + filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); + } BEGIN_CS(16); OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 | @@ -729,22 +779,6 @@ void r300_emit_texture(struct r300_context* r300, END_CS; } -static boolean r300_validate_aos(struct r300_context *r300) -{ - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; - int i; - - /* Check if formats and strides are aligned to the size of DWORD. */ - for (i = 0; i < r300->vertex_element_count; i++) { - if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || - util_format_get_blocksize(velem[i].src_format) % 4 != 0) { - return FALSE; - } - } - return TRUE; -} - void r300_emit_aos(struct r300_context* r300, unsigned offset) { struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; @@ -754,12 +788,6 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) unsigned packet_size = (aos_count * 3 + 1) / 2; CS_LOCALS(r300); - /* XXX Move this checking to a more approriate place. */ - if (!r300_validate_aos(r300)) { - /* XXX We should fallback using Draw. */ - assert(0); - } - BEGIN_CS(2 + packet_size + aos_count * 2); OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); OUT_CS(aos_count); @@ -791,38 +819,39 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) END_CS; } -void r300_emit_vertex_format_state(struct r300_context* r300) +void r300_emit_vertex_format_state(struct r300_context* r300, void* state) { - int i; + struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state; + unsigned i; CS_LOCALS(r300); DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n"); BEGIN_CS(26); - OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info->vinfo.size); + OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size); OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); - OUT_CS(r300->vertex_info->vinfo.hwfmt[0]); - OUT_CS(r300->vertex_info->vinfo.hwfmt[1]); + OUT_CS(vertex_info->vinfo.hwfmt[0]); + OUT_CS(vertex_info->vinfo.hwfmt[1]); OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); - OUT_CS(r300->vertex_info->vinfo.hwfmt[2]); - OUT_CS(r300->vertex_info->vinfo.hwfmt[3]); + OUT_CS(vertex_info->vinfo.hwfmt[2]); + OUT_CS(vertex_info->vinfo.hwfmt[3]); for (i = 0; i < 4; i++) { DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i, - r300->vertex_info->vinfo.hwfmt[i]); + vertex_info->vinfo.hwfmt[i]); } OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8); for (i = 0; i < 8; i++) { - OUT_CS(r300->vertex_info->vap_prog_stream_cntl[i]); + OUT_CS(vertex_info->vap_prog_stream_cntl[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i, - r300->vertex_info->vap_prog_stream_cntl[i]); + vertex_info->vap_prog_stream_cntl[i]); } OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8); for (i = 0; i < 8; i++) { - OUT_CS(r300->vertex_info->vap_prog_stream_cntl_ext[i]); + OUT_CS(vertex_info->vap_prog_stream_cntl_ext[i]); DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i, - r300->vertex_info->vap_prog_stream_cntl_ext[i]); + vertex_info->vap_prog_stream_cntl_ext[i]); } END_CS; } @@ -987,39 +1016,21 @@ static void r300_flush_pvs(struct r300_context* r300) END_CS; } -/* Emit all dirty state. */ -void r300_emit_dirty_state(struct r300_context* r300) +void r300_emit_buffer_validate(struct r300_context *r300) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; struct r300_texture* tex; - struct r300_atom* atom; - unsigned i, dwords = 1024; - int dirty_tex = 0; + unsigned i; boolean invalid = FALSE; - /* Check the required number of dwords against the space remaining in the - * current CS object. If we need more, then flush. */ - - foreach(atom, &r300->atom_list) { - if (atom->dirty || atom->always_dirty) { - dwords += atom->size; - } - } - - /* Make sure we have at least 2*1024 spare dwords. */ - /* XXX It would be nice to know the number of dwords we really need to - * XXX emit. */ - if (!r300->winsys->check_cs(r300->winsys, dwords)) { - r300->context.flush(&r300->context, 0, NULL); - } - /* Clean out BOs. */ r300->winsys->reset_bos(r300->winsys); validate: /* Color buffers... */ - for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) { - tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture; + for (i = 0; i < fb->nr_cbufs; i++) { + tex = (struct r300_texture*)fb->cbufs[i]->texture; assert(tex && tex->buffer && "cbuf is marked, but NULL!"); if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, 0, RADEON_GEM_DOMAIN_VRAM)) { @@ -1028,8 +1039,8 @@ validate: } } /* ...depth buffer... */ - if (r300->framebuffer_state.zsbuf) { - tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture; + if (fb->zsbuf) { + tex = (struct r300_texture*)fb->zsbuf->texture; assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, 0, RADEON_GEM_DOMAIN_VRAM)) { @@ -1076,6 +1087,31 @@ validate: invalid = TRUE; goto validate; } +} + +/* Emit all dirty state. */ +void r300_emit_dirty_state(struct r300_context* r300) +{ + struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_atom* atom; + unsigned i, dwords = 1024; + int dirty_tex = 0; + + /* Check the required number of dwords against the space remaining in the + * current CS object. If we need more, then flush. */ + + foreach(atom, &r300->atom_list) { + if (atom->dirty || atom->always_dirty) { + dwords += atom->size; + } + } + + /* Make sure we have at least 2*1024 spare dwords. */ + /* XXX It would be nice to know the number of dwords we really need to + * XXX emit. */ + while (!r300->winsys->check_cs(r300->winsys, dwords)) { + r300->context.flush(&r300->context, 0, NULL); + } if (r300->dirty_state & R300_NEW_QUERY) { r300_emit_query_start(r300); @@ -1110,16 +1146,6 @@ validate: r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS; } - if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) { - r300_emit_fb_state(r300, &r300->framebuffer_state); - r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS; - } - - if (r300->dirty_state & R300_NEW_RS_BLOCK) { - r300_emit_rs_block_state(r300, r300->rs_block); - r300->dirty_state &= ~R300_NEW_RS_BLOCK; - } - /* Samplers and textures are tracked separately but emitted together. */ if (r300->dirty_state & (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) { @@ -1145,11 +1171,6 @@ validate: r300_flush_textures(r300); } - if (r300->dirty_state & R300_NEW_VERTEX_FORMAT) { - r300_emit_vertex_format_state(r300); - r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT; - } - if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) { r300_flush_pvs(r300); } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 05a6bfeae86..6b96d9b57c0 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -51,8 +51,7 @@ void r500_emit_fragment_program_code(struct r300_context* r300, void r500_emit_fs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants); -void r300_emit_fb_state(struct r300_context* r300, - struct pipe_framebuffer_state* fb); +void r300_emit_fb_state(struct r300_context* r300, void* state); void r300_emit_query_begin(struct r300_context* r300, struct r300_query* query); @@ -61,8 +60,7 @@ void r300_emit_query_end(struct r300_context* r300); void r300_emit_rs_state(struct r300_context* r300, void* state); -void r300_emit_rs_block_state(struct r300_context* r300, - struct r300_rs_block* rs); +void r300_emit_rs_block_state(struct r300_context* r300, void* state); void r300_emit_scissor_state(struct r300_context* r300, void* state); @@ -73,7 +71,7 @@ void r300_emit_texture(struct r300_context* r300, void r300_emit_vertex_buffer(struct r300_context* r300); -void r300_emit_vertex_format_state(struct r300_context* r300); +void r300_emit_vertex_format_state(struct r300_context* r300, void* state); void r300_emit_vertex_program_code(struct r300_context* r300, struct r300_vertex_program_code* code); @@ -95,4 +93,6 @@ void r300_flush_textures(struct r300_context* r300); /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); +void r300_emit_buffer_validate(struct r300_context *r300); + #endif /* R300_EMIT_H */ diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 59819cb1061..e37d3092703 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -29,7 +29,6 @@ #include "r300_cs.h" #include "r300_emit.h" #include "r300_flush.h" -#include "r300_state_invariant.h" static void r300_flush(struct pipe_context* pipe, unsigned flags, @@ -53,7 +52,6 @@ static void r300_flush(struct pipe_context* pipe, if (r300->dirty_hw) { FLUSH_CS; - r300_emit_invariant_state(r300); r300->dirty_state = R300_NEW_KITCHEN_SINK; r300->dirty_hw = 0; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 710d850163f..95b7cb5fa49 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -26,10 +26,9 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" -#include "indices/u_indices.h" - #include "pipe/p_inlines.h" +#include "util/u_format.h" #include "util/u_memory.h" #include "util/u_prim.h" @@ -116,20 +115,60 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, return color_control; } -static void r300_emit_draw_immediate(struct r300_context *r300, - unsigned mode, - unsigned start, - unsigned count) +static boolean immd_is_good_idea(struct r300_context *r300, + unsigned count) { - struct pipe_buffer* vbo = r300->vertex_buffer[0].buffer; - unsigned vertex_size = r300->vertex_buffer[0].stride / sizeof(float); - unsigned i; - uint32_t* map; + return count <= 4; +} + +static void r300_emit_draw_arrays_immediate(struct r300_context *r300, + unsigned mode, + unsigned start, + unsigned count) +{ + struct pipe_vertex_element* velem; + struct pipe_vertex_buffer* vbuf; + unsigned vertex_element_count = r300->vertex_element_count; + unsigned i, v, vbi, dw, elem_offset; + + /* Size of the vertex, in dwords. */ + unsigned vertex_size = 0; + + /* Offsets of the attribute, in dwords, from the start of the vertex. */ + unsigned offset[PIPE_MAX_ATTRIBS]; + + /* Size of the vertex element, in dwords. */ + unsigned size[PIPE_MAX_ATTRIBS]; + + /* Stride to the same attrib in the next vertex in the vertex buffer, + * in dwords. */ + unsigned stride[PIPE_MAX_ATTRIBS]; + + /* Mapped vertex buffers. */ + uint32_t* map[PIPE_MAX_ATTRIBS] = {0}; + CS_LOCALS(r300); - map = (uint32_t*)pipe_buffer_map_range(r300->context.screen, vbo, - start * vertex_size, count * vertex_size, - PIPE_BUFFER_USAGE_CPU_READ); + /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ + for (i = 0; i < vertex_element_count; i++) { + velem = &r300->vertex_element[i]; + offset[i] = velem->src_offset / 4; + size[i] = util_format_get_blocksize(velem->src_format) / 4; + vertex_size += size[i]; + vbi = velem->vertex_buffer_index; + + /* Map the buffer. */ + if (!map[vbi]) { + vbuf = &r300->vertex_buffer[vbi]; + map[vbi] = (uint32_t*)pipe_buffer_map(r300->context.screen, + vbuf->buffer, + PIPE_BUFFER_USAGE_CPU_READ); + map[vbi] += vbuf->buffer_offset / 4; + stride[vbi] = vbuf->stride / 4; + } + } + + r300_emit_dirty_state(r300); BEGIN_CS(10 + count * vertex_size); OUT_CS_REG(R300_GA_COLOR_CONTROL, @@ -140,18 +179,31 @@ static void r300_emit_draw_immediate(struct r300_context *r300, OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | r300_translate_primitive(mode)); - //debug_printf("r300: Immd %d verts, %d attrs\n", count, vertex_size); - for (i = 0; i < count * vertex_size; i++) { - if (i % vertex_size == 0) { - //debug_printf("r300: -- vert --\n"); + + /* Emit vertices. */ + for (v = 0; v < count; v++) { + for (i = 0; i < vertex_element_count; i++) { + velem = &r300->vertex_element[i]; + vbi = velem->vertex_buffer_index; + elem_offset = offset[i] + stride[vbi] * (v + start); + + for (dw = 0; dw < size[i]; dw++) { + OUT_CS(map[vbi][elem_offset + dw]); + } } - //debug_printf("r300: 0x%08x\n", *map); - OUT_CS(*map); - map++; } END_CS; - pipe_buffer_unmap(r300->context.screen, vbo); + /* Unmap buffers. */ + for (i = 0; i < vertex_element_count; i++) { + vbi = r300->vertex_element[i].vertex_buffer_index; + + if (map[vbi]) { + vbuf = &r300->vertex_buffer[vbi]; + pipe_buffer_unmap(r300->context.screen, vbuf->buffer); + map[vbi] = NULL; + } + } } static void r300_emit_draw_arrays(struct r300_context *r300, @@ -223,17 +275,18 @@ static void r300_emit_draw_elements(struct r300_context *r300, END_CS; } - static boolean r300_setup_vertex_buffers(struct r300_context *r300) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_buffer *pbuf; validate: for (int i = 0; i < r300->vertex_element_count; i++) { - if (!r300->winsys->add_buffer(r300->winsys, - vbuf[velem[i].vertex_buffer_index].buffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + pbuf = vbuf[velem[i].vertex_buffer_index].buffer; + + if (!r300->winsys->add_buffer(r300->winsys, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -247,40 +300,35 @@ validate: return TRUE; } -static struct pipe_buffer* r300_translate_elts(struct r300_context* r300, - struct pipe_buffer* elts, - unsigned* size, - unsigned* mode, - unsigned* count) +static void r300_shorten_ubyte_elts(struct r300_context* r300, + struct pipe_buffer** elts, + unsigned count) { struct pipe_screen* screen = r300->context.screen; struct pipe_buffer* new_elts; - void *in_map, *out_map; - unsigned out_prim, out_index_size, out_nr; - u_translate_func out_translate; - - (void)u_index_translator(~0, *mode, *size, *count, PV_LAST, PV_LAST, - &out_prim, &out_index_size, &out_nr, &out_translate); + unsigned char *in_map; + unsigned short *out_map; + unsigned i; new_elts = screen->buffer_create(screen, 32, PIPE_BUFFER_USAGE_INDEX | PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_READ, - out_index_size * out_nr); + 2 * count); - in_map = pipe_buffer_map(screen, elts, PIPE_BUFFER_USAGE_CPU_READ); + in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ); out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE); - out_translate(in_map, *count, out_map); + for (i = 0; i < count; i++) { + *out_map = (unsigned short)*in_map; + in_map++; + out_map++; + } - pipe_buffer_unmap(screen, elts); + pipe_buffer_unmap(screen, *elts); pipe_buffer_unmap(screen, new_elts); - *size = out_index_size; - *mode = out_prim; - *count = out_nr; - - return new_elts; + *elts = new_elts; } /* This is the fast-path drawing & emission for HW TCL. */ @@ -309,13 +357,15 @@ void r300_draw_range_elements(struct pipe_context* pipe, r300_update_derived_state(r300); + r300_emit_buffer_validate(r300); + if (!r300_setup_vertex_buffers(r300)) { return; } if (indexSize == 1) { - indexBuffer = r300_translate_elts(r300, indexBuffer, - &indexSize, &mode, &count); + r300_shorten_ubyte_elts(r300, &indexBuffer, count); + indexSize = 2; } if (!r300->winsys->add_buffer(r300->winsys, indexBuffer, @@ -368,15 +418,16 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, r300_update_derived_state(r300); - if (!r300_setup_vertex_buffers(r300)) { - return; - } - - r300_emit_dirty_state(r300); + r300_emit_buffer_validate(r300); - if (FALSE && count <= 4 && r300->vertex_buffer_count == 1) { - r300_emit_draw_immediate(r300, mode, start, count); + if (immd_is_good_idea(r300, count)) { + r300_emit_draw_arrays_immediate(r300, mode, start, count); } else { + if (!r300_setup_vertex_buffers(r300)) { + return; + } + + r300_emit_dirty_state(r300); r300_emit_aos(r300, start); r300_emit_draw_arrays(r300, mode, count); } @@ -411,6 +462,7 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe, draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, + 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants, r300->shader_constants[PIPE_SHADER_VERTEX].count * (sizeof(float) * 4)); @@ -455,6 +507,7 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe, draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX, + 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants, r300->shader_constants[PIPE_SHADER_VERTEX].count * (sizeof(float) * 4)); @@ -506,7 +559,7 @@ r300_render_get_vertex_info(struct vbuf_render* render) r300_update_derived_state(r300); - return &r300->vertex_info->vinfo; + return (struct vertex_info*)r300->vertex_format_state.state; } static boolean r300_render_allocate_vertices(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 287664b1d20..fa8ed581dae 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -113,6 +113,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) * ~ C. */ return 1; + case PIPE_CAP_DUAL_SOURCE_BLEND: + return 0; case PIPE_CAP_ANISOTROPIC_FILTER: return 1; case PIPE_CAP_POINT_SPRITE: @@ -149,6 +151,20 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) } else { return 0; } + case PIPE_CAP_INDEP_BLEND_ENABLE: + if (r300screen->caps->is_r500) { + return 1; + } else { + return 0; + } + case PIPE_CAP_INDEP_BLEND_FUNC: + return 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; default: debug_printf("r300: Implementation error: Bad param %d\n", param); @@ -183,10 +199,20 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param) } } -static boolean check_tex_format(enum pipe_format format, uint32_t usage, - boolean is_r500) +static boolean r300_is_format_supported(struct pipe_screen* screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned usage, + unsigned geom_flags) { uint32_t retval = 0; + boolean is_r500 = r300_screen(screen)->caps->is_r500; + + if (target >= PIPE_MAX_TEXTURE_TYPES) { + debug_printf("r300: Implementation error: Received bogus texture " + "target %d in %s\n", target, __FUNCTION__); + return FALSE; + } switch (format) { /* Supported formats. */ @@ -194,6 +220,8 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_L8_UNORM: retval = usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | @@ -208,7 +236,6 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: case PIPE_FORMAT_YCBCR: - case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_A8L8_UNORM: retval = usage & PIPE_TEXTURE_USAGE_SAMPLER; break; @@ -247,28 +274,13 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, case PIPE_FORMAT_Z32_UNORM: case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: - debug_printf("r300: Note: Got unsupported format: %s in %s\n", - pf_name(format), __FUNCTION__); + SCREEN_DBG(r300_screen(screen), DBG_TEX, + "r300: Note: Got unsupported format: %s in %s\n", + pf_name(format), __FUNCTION__); return FALSE; - /* XXX These don't even exist - case PIPE_FORMAT_A32R32G32B32: - case PIPE_FORMAT_A16R16G16B16: */ - /* XXX What the deuce is UV88? (r3xx accel page 14) - debug_printf("r300: Warning: Got unimplemented format: %s in %s\n", - pf_name(format), __FUNCTION__); - return FALSE; */ - - /* XXX Supported yet unimplemented r5xx formats: */ - /* XXX Again, what is UV1010 this time? (r5xx accel page 148) */ - /* XXX Even more that don't exist - case PIPE_FORMAT_A10R10G10B10_UNORM: - case PIPE_FORMAT_A2R10G10B10_UNORM: - case PIPE_FORMAT_I10_UNORM: - debug_printf( - "r300: Warning: Got unimplemented r500 format: %s in %s\n", - pf_name(format), __FUNCTION__); - return FALSE; */ + /* XXX Add all remaining gallium-supported formats, + * see util/u_format.csv. */ default: /* Unknown format... */ @@ -286,30 +298,6 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage, return (retval >= usage); } -static boolean r300_is_format_supported(struct pipe_screen* pscreen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, - unsigned geom_flags) -{ - switch (target) { - case PIPE_TEXTURE_1D: /* handle 1D textures as 2D ones */ - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_3D: - case PIPE_TEXTURE_CUBE: - return check_tex_format(format, tex_usage, - r300_screen(pscreen)->caps->is_r500); - - default: - debug_printf("r300: Fatal: This is not a format target: %d\n", - target); - assert(0); - break; - } - - return FALSE; -} - static struct pipe_transfer* r300_get_tex_transfer(struct pipe_screen *screen, struct pipe_texture *texture, @@ -319,6 +307,7 @@ r300_get_tex_transfer(struct pipe_screen *screen, { struct r300_texture *tex = (struct r300_texture *)texture; struct r300_transfer *trans; + struct r300_screen *rscreen = r300_screen(screen); unsigned offset; offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */ @@ -330,11 +319,8 @@ r300_get_tex_transfer(struct pipe_screen *screen, trans->transfer.y = y; trans->transfer.width = w; trans->transfer.height = h; - trans->transfer.stride = r300_texture_get_stride(tex, level); + trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level); trans->transfer.usage = usage; - - /* XXX not sure whether it's required to set these two, - the driver doesn't use them */ trans->transfer.zslice = zslice; trans->transfer.face = face; @@ -396,6 +382,7 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys) caps->num_frag_pipes = radeon_winsys->gb_pipes; caps->num_z_pipes = radeon_winsys->z_pipes; + r300_init_debug(r300screen); r300_parse_chipset(caps); r300screen->caps = caps; diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 2217988addd..580fda3984e 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -35,6 +35,9 @@ struct r300_screen { /* Chipset capabilities */ struct r300_capabilities* caps; + + /** Combination of DBG_xxx flags */ + unsigned debug; }; struct r300_transfer { @@ -60,4 +63,44 @@ r300_transfer(struct pipe_transfer* transfer) /* Creates a new r300 screen. */ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); +/* Debug functionality. */ + +/** + * Debug flags to disable/enable certain groups of debugging outputs. + * + * \note These may be rather coarse, and the grouping may be impractical. + * If you find, while debugging the driver, that a different grouping + * of these flags would be beneficial, just feel free to change them + * but make sure to update the documentation in r300_debug.c to reflect + * those changes. + */ +/*@{*/ +#define DBG_HELP 0x0000001 +#define DBG_FP 0x0000002 +#define DBG_VP 0x0000004 +#define DBG_CS 0x0000008 +#define DBG_DRAW 0x0000010 +#define DBG_TEX 0x0000020 +#define DBG_FALL 0x0000040 +/*@}*/ + +static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags) +{ + return (screen->debug & flags) ? TRUE : FALSE; +} + +static INLINE void SCREEN_DBG(struct r300_screen * screen, unsigned flags, + const char * fmt, ...) +{ + if (SCREEN_DBG_ON(screen, flags)) { + va_list va; + va_start(va, fmt); + debug_vprintf(fmt, va); + va_end(va); + } +} + +void r300_init_debug(struct r300_screen* ctx); + #endif /* R300_SCREEN_H */ + diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 60ad763cf48..a5c0869066c 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -30,7 +30,6 @@ #include "tgsi/tgsi_parse.h" #include "pipe/p_config.h" -#include "pipe/internal/p_winsys_screen.h" #include "r300_context.h" #include "r300_reg.h" @@ -162,17 +161,18 @@ static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA static void* r300_create_blend_state(struct pipe_context* pipe, const struct pipe_blend_state* state) { + struct r300_screen* r300screen = r300_screen(pipe->screen); struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); - if (state->blend_enable) + if (state->rt[0].blend_enable) { - unsigned eqRGB = state->rgb_func; - unsigned srcRGB = state->rgb_src_factor; - unsigned dstRGB = state->rgb_dst_factor; + unsigned eqRGB = state->rt[0].rgb_func; + unsigned srcRGB = state->rt[0].rgb_src_factor; + unsigned dstRGB = state->rt[0].rgb_dst_factor; - unsigned eqA = state->alpha_func; - unsigned srcA = state->alpha_src_factor; - unsigned dstA = state->alpha_dst_factor; + unsigned eqA = state->rt[0].alpha_func; + unsigned srcA = state->rt[0].alpha_src_factor; + unsigned dstA = state->rt[0].alpha_dst_factor; /* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha, * this is just the crappy D3D naming */ @@ -289,18 +289,18 @@ static void* r300_create_blend_state(struct pipe_context* pipe, (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; } - /* Color Channel Mask */ - if (state->colormask & PIPE_MASK_R) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_RED_MASK0; - } - if (state->colormask & PIPE_MASK_G) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0; - } - if (state->colormask & PIPE_MASK_B) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0; - } - if (state->colormask & PIPE_MASK_A) { - blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0; + /* Color channel masks for all MRTs. */ + blend->color_channel_mask = state->rt[0].colormask; + if (r300screen->caps->is_r500 && state->independent_blend_enable) { + if (state->rt[1].blend_enable) { + blend->color_channel_mask |= (state->rt[1].colormask << 4); + } + if (state->rt[2].blend_enable) { + blend->color_channel_mask |= (state->rt[2].colormask << 8); + } + if (state->rt[3].blend_enable) { + blend->color_channel_mask |= (state->rt[3].colormask << 12); + } } if (state->dither) { @@ -486,19 +486,47 @@ static void const struct pipe_framebuffer_state* state) { struct r300_context* r300 = r300_context(pipe); + uint32_t zbuffer_bpp = 0; + + r300->fb_state.size = (10 * state->nr_cbufs) + + (2 * (4 - state->nr_cbufs)) + + (state->zsbuf ? 10 : 0) + 6; + + if (state->nr_cbufs > 4) { + debug_printf("r300: Implementation error: Too many MRTs in %s, " + "refusing to bind framebuffer state!\n", __FUNCTION__); + return; + } if (r300->draw) { draw_flush(r300->draw); } - r300->framebuffer_state = *state; + r300->fb_state.state = state; /* Don't rely on the order of states being set for the first time. */ - r300->dirty_state |= R300_NEW_FRAMEBUFFERS; - + /* XXX wait what */ r300->blend_state.dirty = TRUE; r300->dsa_state.dirty = TRUE; + r300->fb_state.dirty = TRUE; r300->scissor_state.dirty = TRUE; + + /* Polygon offset depends on the zbuffer bit depth. */ + if (state->zsbuf && r300->polygon_offset_enabled) { + switch (util_format_get_blocksize(state->zsbuf->texture->format)) { + case 2: + zbuffer_bpp = 16; + break; + case 4: + zbuffer_bpp = 24; + break; + } + + if (r300->zbuffer_bpp != zbuffer_bpp) { + r300->zbuffer_bpp = zbuffer_bpp; + r300->rs_state.dirty = TRUE; + } + } } /* Create fragment shader state. */ @@ -534,7 +562,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300_pick_fragment_shader(r300); if (r300->vs && r300_vertex_shader_setup_wpos(r300)) { - r300->dirty_state |= R300_NEW_VERTEX_FORMAT; + r300->vertex_format_state.dirty = TRUE; } r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -602,9 +630,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->line_control = pack_float_16_6x(state->line_width) | R300_GA_LINE_CNTL_END_TYPE_COMP; - /* XXX I think there is something wrong with the polygon mode, - * XXX re-test when r300g is in a better shape */ - /* Enable polygon mode */ if (state->fill_cw != PIPE_POLYGON_MODE_FILL || state->fill_ccw != PIPE_POLYGON_MODE_FILL) { @@ -657,10 +682,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe, } if (rs->polygon_offset_enable) { - rs->depth_offset_front = rs->depth_offset_back = - fui(state->offset_units); - rs->depth_scale_front = rs->depth_scale_back = - fui(state->offset_scale); + rs->depth_offset = state->offset_units; + rs->depth_scale = state->offset_scale; } if (state->line_stipple_enable) { @@ -694,8 +717,10 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) if (rs) { r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport; + r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; } else { r300->tcl_bypass = FALSE; + r300->polygon_offset_enabled = FALSE; } r300->rs_state.state = rs; @@ -705,7 +730,6 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) r300->viewport_state.dirty = TRUE; /* XXX Clean these up when we move to atom emits */ - r300->dirty_state |= R300_NEW_RS_BLOCK; if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) { r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; } @@ -906,7 +930,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, draw_set_vertex_buffers(r300->draw, count, buffers); } - r300->dirty_state |= R300_NEW_VERTEX_FORMAT; + r300->vertex_format_state.dirty = TRUE; +} + +static boolean r300_validate_aos(struct r300_context *r300) +{ + struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; + struct pipe_vertex_element *velem = r300->vertex_element; + int i; + + /* Check if formats and strides are aligned to the size of DWORD. */ + for (i = 0; i < r300->vertex_element_count; i++) { + if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 || + util_format_get_blocksize(velem[i].src_format) % 4 != 0) { + return FALSE; + } + } + return TRUE; } static void r300_set_vertex_elements(struct pipe_context* pipe, @@ -924,6 +964,12 @@ static void r300_set_vertex_elements(struct pipe_context* pipe, draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, count, elements); } + + if (!r300_validate_aos(r300)) { + /* XXX We should fallback using draw. */ + assert(0); + abort(); + } } static void* r300_create_vs_state(struct pipe_context* pipe, @@ -964,9 +1010,10 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300_vertex_shader_setup_wpos(r300); } + r300->vertex_format_state.dirty = TRUE; + r300->dirty_state |= - R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS | - R300_NEW_VERTEX_FORMAT; + R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 192846411ba..bad9e76067c 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -37,32 +37,6 @@ /* r300_state_derived: Various bits of state which are dependent upon * currently bound CSO data. */ -struct r300_shader_key { - struct r300_vertex_shader* vs; - struct r300_fragment_shader* fs; -}; - -struct r300_shader_derived_value { - struct r300_vertex_format* vformat; - struct r300_rs_block* rs_block; -}; - -unsigned r300_shader_key_hash(void* key) { - struct r300_shader_key* shader_key = (struct r300_shader_key*)key; - unsigned vs = (intptr_t)shader_key->vs; - unsigned fs = (intptr_t)shader_key->fs; - - return (vs << 16) | (fs & 0xffff); -} - -int r300_shader_key_compare(void* key1, void* key2) { - struct r300_shader_key* shader_key1 = (struct r300_shader_key*)key1; - struct r300_shader_key* shader_key2 = (struct r300_shader_key*)key2; - - return (shader_key1->vs == shader_key2->vs) && - (shader_key1->fs == shader_key2->fs); -} - static void r300_draw_emit_attrib(struct r300_context* r300, enum attrib_emit emit, enum interp_mode interp, @@ -74,7 +48,9 @@ static void r300_draw_emit_attrib(struct r300_context* r300, output = draw_find_shader_output(r300->draw, info->output_semantic_name[index], info->output_semantic_index[index]); - draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output); + draw_emit_vertex_attr( + (struct vertex_info*)r300->vertex_format_state.state, + emit, interp, output); } static void r300_draw_emit_all_attribs(struct r300_context* r300) @@ -130,7 +106,8 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) /* Update the PSC tables. */ static void r300_vertex_psc(struct r300_context* r300) { - struct r300_vertex_info *vformat = r300->vertex_info; + struct r300_vertex_info *vformat = + (struct r300_vertex_info*)r300->vertex_format_state.state; uint16_t type, swizzle; enum pipe_format format; unsigned i; @@ -182,7 +159,8 @@ static void r300_vertex_psc(struct r300_context* r300) /* Update the PSC tables for SW TCL, using Draw. */ static void r300_swtcl_vertex_psc(struct r300_context* r300) { - struct r300_vertex_info *vformat = r300->vertex_info; + struct r300_vertex_info *vformat = + (struct r300_vertex_info*)r300->vertex_format_state.state; struct vertex_info* vinfo = &vformat->vinfo; uint16_t type, swizzle; enum pipe_format format; @@ -327,7 +305,7 @@ static void r300_update_rs_block(struct r300_context* r300, struct r300_shader_semantics* vs_outputs, struct r300_shader_semantics* fs_inputs) { - struct r300_rs_block* rs = r300->rs_block; + struct r300_rs_block rs = { { 0 } }; int i, col_count = 0, tex_count = 0, fp_offset = 0; void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean); void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); @@ -350,14 +328,15 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) { + if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || + vs_outputs->color[1] != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_col(rs, col_count, i, FALSE); + rX00_rs_col(&rs, col_count, i, FALSE); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->color[i] != ATTR_UNUSED) { - rX00_rs_col_write(rs, col_count, fp_offset); + rX00_rs_col_write(&rs, col_count, fp_offset); fp_offset++; } col_count++; @@ -375,11 +354,11 @@ static void r300_update_rs_block(struct r300_context* r300, if (vs_outputs->generic[i] != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_tex(rs, tex_count, tex_count, FALSE); + rX00_rs_tex(&rs, tex_count, tex_count, FALSE); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->generic[i] != ATTR_UNUSED) { - rX00_rs_tex_write(rs, tex_count, fp_offset); + rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; } tex_count++; @@ -396,11 +375,11 @@ static void r300_update_rs_block(struct r300_context* r300, if (vs_outputs->fog != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_tex(rs, tex_count, tex_count, TRUE); + rX00_rs_tex(&rs, tex_count, tex_count, TRUE); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->fog != ATTR_UNUSED) { - rX00_rs_tex_write(rs, tex_count, fp_offset); + rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; } tex_count++; @@ -415,8 +394,8 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize WPOS. */ /* If the FS doesn't need it, it's not written by the VS. */ if (fs_inputs->wpos != ATTR_UNUSED) { - rX00_rs_tex(rs, tex_count, tex_count, FALSE); - rX00_rs_tex_write(rs, tex_count, fp_offset); + rX00_rs_tex(&rs, tex_count, tex_count, FALSE); + rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; tex_count++; @@ -424,51 +403,33 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize at least one color, or bad things happen. */ if (col_count == 0 && tex_count == 0) { - rX00_rs_col(rs, 0, 0, TRUE); + rX00_rs_col(&rs, 0, 0, TRUE); col_count++; } - rs->count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | + rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; - rs->inst_count = MAX3(col_count - 1, tex_count - 1, 0); + rs.inst_count = MAX3(col_count - 1, tex_count - 1, 0); + + /* Now, after all that, see if we actually need to update the state. */ + if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { + memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); + r300->rs_block_state.dirty = TRUE; + } } -/* Update the vertex format. */ +/* Update the shader-dependant states. */ static void r300_update_derived_shader_state(struct r300_context* r300) { struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_vertex_info *vformat = + (struct r300_vertex_info*)r300->vertex_format_state.state; + struct vertex_info* vinfo = &vformat->vinfo; - /* - struct r300_shader_key* key; - struct r300_shader_derived_value* value; - key = CALLOC_STRUCT(r300_shader_key); - key->vs = r300->vs; - key->fs = r300->fs; - - value = (struct r300_shader_derived_value*) - util_hash_table_get(r300->shader_hash_table, (void*)key); - if (value) { - //vformat = value->vformat; - rs_block = value->rs_block; - - FREE(key); - } else { - rs_block = CALLOC_STRUCT(r300_rs_block); - value = CALLOC_STRUCT(r300_shader_derived_value); - - r300_update_rs_block(r300, rs_block); - - //value->vformat = vformat; - value->rs_block = rs_block; - util_hash_table_set(r300->shader_hash_table, - (void*)key, (void*)value); - } */ - - /* Reset structures */ - memset(r300->rs_block, 0, sizeof(struct r300_rs_block)); - memset(r300->vertex_info, 0, sizeof(struct r300_vertex_info)); - memcpy(r300->vertex_info->vinfo.hwfmt, r300->vs->hwfmt, sizeof(uint)*4); + /* Mmm, delicious hax */ + memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info)); + memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4); r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs); @@ -476,11 +437,10 @@ static void r300_update_derived_shader_state(struct r300_context* r300) r300_vertex_psc(r300); } else { r300_draw_emit_all_attribs(r300); - draw_compute_vertex_size(&r300->vertex_info->vinfo); + draw_compute_vertex_size( + (struct vertex_info*)r300->vertex_format_state.state); r300_swtcl_vertex_psc(r300); } - - r300->dirty_state |= R300_NEW_RS_BLOCK; } static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa) @@ -558,8 +518,8 @@ void r300_update_derived_state(struct r300_context* r300) { /* XXX */ if (r300->dirty_state & - (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER | - R300_NEW_VERTEX_FORMAT) || r300->rs_state.dirty) { + (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER) || + r300->vertex_format_state.dirty || r300->rs_state.dirty) { r300_update_derived_shader_state(r300); } diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 35be00e1b01..5df6815221f 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -81,9 +81,6 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact) return R300_BLEND_GL_CONST_COLOR; case PIPE_BLENDFACTOR_CONST_ALPHA: return R300_BLEND_GL_CONST_ALPHA; - /* XXX WTF are these? - case PIPE_BLENDFACTOR_SRC1_COLOR: - case PIPE_BLENDFACTOR_SRC1_ALPHA: */ case PIPE_BLENDFACTOR_ZERO: return R300_BLEND_GL_ZERO; case PIPE_BLENDFACTOR_INV_SRC_COLOR: @@ -98,9 +95,16 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact) return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; - /* XXX see above + + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + debug_printf("r300: Implementation error: " + "Bad blend factor %d not supported!\n", blend_fact); + assert(0); + break; + default: debug_printf("r300: Unknown blend factor %d\n", blend_fact); assert(0); @@ -331,7 +335,10 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) { switch (format) { /* 8-bit buffers */ + case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + /* case PIPE_FORMAT_S8_UNORM: ??? */ return R300_COLOR_FORMAT_I8; /* 16-bit buffers */ case PIPE_FORMAT_R5G6B5_UNORM: @@ -408,6 +415,16 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) return R300_US_OUT_FMT_C4_8 | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; + + /* 8-bit outputs */ + case PIPE_FORMAT_A8_UNORM: + return R300_US_OUT_FMT_C4_8 | + R300_C0_SEL_A; + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + return R300_US_OUT_FMT_C4_8 | + R300_C0_SEL_R; + /* R300_OUT_SIGN(x) */ default: debug_printf("r300: Implementation error: " "Got unsupported output format %s in %s\n", @@ -537,6 +554,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { static INLINE uint16_t r300_translate_vertex_data_swizzle(enum pipe_format format) { const struct util_format_description *desc = util_format_description(format); + unsigned swizzle[4], i; assert(format); @@ -547,11 +565,26 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) { return 0; } - return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | - (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | - (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | - (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) | - (0xf << R300_WRITE_ENA_SHIFT)); + /* Swizzles for 8bits formats are in the reversed order, not sure why. */ + if (desc->channel[0].size == 8) { + for (i = 0; i < 4; i++) { + if (desc->swizzle[i] <= 3) { + swizzle[i] = 3 - desc->swizzle[i]; + } else { + swizzle[i] = desc->swizzle[i]; + } + } + } else { + for (i = 0; i < 4; i++) { + swizzle[i] = desc->swizzle[i]; + } + } + + return ((swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | + (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | + (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | + (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) | + (0xf << R300_WRITE_ENA_SHIFT)); } #endif /* R300_STATE_INLINES_H */ diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index b0f309695c9..97927acf1b4 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -38,12 +38,12 @@ struct pipe_viewport_state r300_viewport_identity = { * * Note that eventually this should be empty, but it's useful for development * and general unduplication of code. */ -void r300_emit_invariant_state(struct r300_context* r300) +void r300_emit_invariant_state(struct r300_context* r300, void* state) { struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; CS_LOCALS(r300); - BEGIN_CS(16 + (caps->has_tcl ? 2: 0)); + BEGIN_CS(14 + (caps->has_tcl ? 2: 0)); /*** Graphics Backend (GB) ***/ /* Various GB enables */ @@ -58,8 +58,6 @@ void r300_emit_invariant_state(struct r300_context* r300) */ /* Source of fog depth */ OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W); - /* AA enable */ - OUT_CS_REG(R300_GB_AA_CONFIG, 0x0); /*** Fog (FG) ***/ OUT_CS_REG(R300_FG_FOG_BLEND, 0x0); @@ -79,7 +77,8 @@ void r300_emit_invariant_state(struct r300_context* r300) END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + (caps->is_r500 ? 4 : 0)); + BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + + (caps->family >= CHIP_FAMILY_RV350 ? 4 : 0)); if (caps->has_tcl) { /*Flushing PVS is required before the VAP_GB registers can be changed*/ diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h index 05cff0d6dfe..5d1a9636545 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.h +++ b/src/gallium/drivers/r300/r300_state_invariant.h @@ -25,6 +25,6 @@ struct r300_context; -void r300_emit_invariant_state(struct r300_context* r300); +void r300_emit_invariant_state(struct r300_context* r300, void* state); #endif /* R300_STATE_INVARIANT_H */ diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index a9bbdd56d84..67bf8ce13fd 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -30,6 +30,8 @@ #include "r300_texture.h" #include "r300_screen.h" +#include "radeon_winsys.h" + #define TILE_WIDTH 0 #define TILE_HEIGHT 1 @@ -42,10 +44,11 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; -static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) +static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex) { struct r300_texture_state* state = &tex->state; struct pipe_texture *pt = &tex->tex; + boolean is_r500 = screen->caps->is_r500; state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) | R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff); @@ -79,8 +82,8 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) } assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048)); - debug_printf("r300: Set texture state (%dx%d, %d levels)\n", - pt->width0, pt->height0, pt->last_level); + SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n", + pt->width0, pt->height0, pt->last_level); } unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, @@ -123,7 +126,8 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex, int dim) * Return the stride, in bytes, of the texture images of the given texture * at the given level. */ -unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) +unsigned r300_texture_get_stride(struct r300_screen* screen, + struct r300_texture* tex, unsigned level) { unsigned tile_width, width; @@ -132,16 +136,20 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) /* Check the level. */ if (level > tex->tex.last_level) { - debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, - level, tex->tex.last_level); + SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n", + __FUNCTION__, level, tex->tex.last_level); return 0; } - tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH); - width = align(u_minify(tex->tex.width0, level), tile_width); + width = u_minify(tex->tex.width0, level); - /* Should already be aligned except for S3TC. */ - return align(util_format_get_stride(tex->tex.format, width), 32); + if (!util_format_is_compressed(tex->tex.format)) { + tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH); + width = align(width, tile_width); + return util_format_get_stride(tex->tex.format, width); + } else { + return align(util_format_get_stride(tex->tex.format, width), 32); + } } static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, @@ -149,21 +157,27 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, { unsigned height, tile_height; - tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT); - height = align(u_minify(tex->tex.height0, level), tile_height); + height = u_minify(tex->tex.height0, level); + + if (!util_format_is_compressed(tex->tex.format)) { + tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT); + height = align(height, tile_height); + } return util_format_get_nblocksy(tex->tex.format, height); } -static void r300_setup_miptree(struct r300_texture* tex) +static void r300_setup_miptree(struct r300_screen* screen, + struct r300_texture* tex) { struct pipe_texture* base = &tex->tex; unsigned stride, size, layer_size, nblocksy, i; - debug_printf("r300: Making miptree for texture, format %s\n", pf_name(base->format)); + SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n", + pf_name(base->format)); for (i = 0; i <= base->last_level; i++) { - stride = r300_texture_get_stride(tex, i); + stride = r300_texture_get_stride(screen, tex, i); nblocksy = r300_texture_get_nblocksy(tex, i); layer_size = stride * nblocksy; @@ -177,7 +191,7 @@ static void r300_setup_miptree(struct r300_texture* tex) tex->layer_size[i] = layer_size; tex->pitch[i] = stride / util_format_get_blocksize(base->format); - debug_printf("r300: Texture miptree: Level %d " + SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d " "(%dx%dx%d px, pitch %d bytes) %d bytes total\n", i, u_minify(base->width0, i), u_minify(base->height0, i), u_minify(base->depth0, i), stride, tex->size); @@ -196,6 +210,8 @@ static struct pipe_texture* const struct pipe_texture* template) { struct r300_texture* tex = CALLOC_STRUCT(r300_texture); + struct r300_screen* rscreen = r300_screen(screen); + struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys; if (!tex) { return NULL; @@ -206,12 +222,16 @@ static struct pipe_texture* tex->tex.screen = screen; r300_setup_flags(tex); - r300_setup_miptree(tex); - r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); + r300_setup_miptree(rscreen, tex); + r300_setup_texture_state(rscreen, tex); tex->buffer = screen->buffer_create(screen, 2048, PIPE_BUFFER_USAGE_PIXEL, tex->size); + winsys->buffer_set_tiling(winsys, tex->buffer, + tex->pitch[0], + tex->microtile != R300_BUFFER_LINEAR, + tex->macrotile != R300_BUFFER_LINEAR); if (!tex->buffer) { FREE(tex); @@ -273,6 +293,7 @@ static struct pipe_texture* struct pipe_buffer* buffer) { struct r300_texture* tex; + struct r300_screen* rscreen = r300_screen(screen); /* Support only 2D textures without mipmaps */ if (base->target != PIPE_TEXTURE_2D || @@ -294,7 +315,7 @@ static struct pipe_texture* tex->pitch[0] = *stride / util_format_get_blocksize(base->format); r300_setup_flags(tex); - r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); + r300_setup_texture_state(rscreen, tex); pipe_buffer_reference(&tex->buffer, buffer); @@ -361,7 +382,8 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen) screen->video_surface_destroy= r300_video_surface_destroy; } -boolean r300_get_texture_buffer(struct pipe_texture* texture, +boolean r300_get_texture_buffer(struct pipe_screen* screen, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride) { @@ -373,7 +395,7 @@ boolean r300_get_texture_buffer(struct pipe_texture* texture, pipe_buffer_reference(buffer, tex->buffer); if (stride) { - *stride = r300_texture_get_stride(tex, 0); + *stride = r300_texture_get_stride(r300_screen(screen), tex, 0); } return TRUE; diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 55ceb1a5136..453fb1accc2 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -31,7 +31,8 @@ struct r300_texture; void r300_init_screen_texture_functions(struct pipe_screen* screen); -unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level); +unsigned r300_texture_get_stride(struct r300_screen* screen, + struct r300_texture* tex, unsigned level); unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, unsigned zslice, unsigned face); @@ -41,6 +42,7 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) { switch (format) { /* X8 */ + case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X8); case PIPE_FORMAT_L8_UNORM: @@ -115,7 +117,8 @@ r300_video_surface(struct pipe_video_surface *pvs) #ifndef R300_WINSYS_H -boolean r300_get_texture_buffer(struct pipe_texture* texture, +boolean r300_get_texture_buffer(struct pipe_screen* screen, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index 68aef70872e..9fbb830047f 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -124,7 +124,8 @@ static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs) /* Colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) { + if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || + vs_outputs->color[1] != ATTR_UNUSED) { hwfmt[1] |= R300_INPUT_CNTL_COLOR; hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; } @@ -182,7 +183,8 @@ static void r300_stream_locations_notcl( /* Colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) { + if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || + vs_outputs->color[1] != ATTR_UNUSED) { stream_loc[tabi++] = 2 + i; } } @@ -259,7 +261,8 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (outputs->color[i] != ATTR_UNUSED) { c->code->outputs[outputs->color[i]] = reg++; - } else if (any_bcolor_used) { + } else if (any_bcolor_used || + outputs->color[1] != ATTR_UNUSED) { reg++; } } diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 1ae6de70fee..bdb8b54bab6 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -40,7 +40,8 @@ extern "C" { struct pipe_context* r300_create_context(struct pipe_screen* screen, struct radeon_winsys* radeon_winsys); -boolean r300_get_texture_buffer(struct pipe_texture* texture, +boolean r300_get_texture_buffer(struct pipe_screen* screen, + struct pipe_texture* texture, struct pipe_buffer** buffer, unsigned* stride); diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index bcb887a0b26..e4ac49fa85f 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -32,6 +32,7 @@ C_SOURCES = \ sp_tex_tile_cache.c \ sp_tile_cache.c \ sp_surface.c \ - sp_video_context.c + sp_video_context.c \ + sp_winsys.c include ../../Makefile.template diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index aac9edf44e6..3042e556c64 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -34,6 +34,7 @@ softpipe = env.ConvenienceLibrary( 'sp_texture.c', 'sp_tile_cache.c', 'sp_video_context.c', + 'sp_winsys.c' ]) Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 8e017939402..53133d28888 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -43,7 +43,6 @@ #include "sp_surface.h" #include "sp_tile_cache.h" #include "sp_tex_tile_cache.h" -#include "sp_texture.h" #include "sp_winsys.h" #include "sp_query.h" @@ -112,9 +111,13 @@ softpipe_destroy( struct pipe_context *pipe ) pipe_texture_reference(&softpipe->vertex_textures[i], NULL); } - for (i = 0; i < Elements(softpipe->constants); i++) { - if (softpipe->constants[i]) { - pipe_buffer_reference(&softpipe->constants[i], NULL); + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + uint j; + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + if (softpipe->constants[i][j]) { + pipe_buffer_reference(&softpipe->constants[i][j], NULL); + } } } diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index da673c57ada..be4613b6228 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -63,7 +63,7 @@ struct softpipe_context { /** Other rendering state */ struct pipe_blend_color blend_color; struct pipe_clip_state clip; - struct pipe_buffer *constants[PIPE_SHADER_TYPES]; + struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; @@ -92,7 +92,7 @@ struct softpipe_context { ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; /** Mapped constant buffers */ - void *mapped_constants[PIPE_SHADER_TYPES]; + void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; /** Vertex format */ struct vertex_info vertex_info; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 03b58d2fb72..2b82427d546 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -49,30 +49,36 @@ static void softpipe_map_constant_buffers(struct softpipe_context *sp) { struct pipe_winsys *ws = sp->pipe.winsys; - uint i, vssize, gssize; + uint i; for (i = 0; i < PIPE_SHADER_TYPES; i++) { - if (sp->constants[i] && sp->constants[i]->size) - sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i], - PIPE_BUFFER_USAGE_CPU_READ); + uint j; + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + if (sp->constants[i][j] && sp->constants[i][j]->size) { + sp->mapped_constants[i][j] = ws->buffer_map(ws, + sp->constants[i][j], + PIPE_BUFFER_USAGE_CPU_READ); + } + } } - if (sp->constants[PIPE_SHADER_VERTEX]) - vssize = sp->constants[PIPE_SHADER_VERTEX]->size; - else - vssize = 0; - - if (sp->constants[PIPE_SHADER_GEOMETRY]) - gssize = sp->constants[PIPE_SHADER_GEOMETRY]->size; - else - gssize = 0; - - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, - sp->mapped_constants[PIPE_SHADER_VERTEX], - vssize); - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, - sp->mapped_constants[PIPE_SHADER_GEOMETRY], - gssize); + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + if (sp->constants[PIPE_SHADER_VERTEX][i]) { + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_VERTEX, + i, + sp->mapped_constants[PIPE_SHADER_VERTEX][i], + sp->constants[PIPE_SHADER_VERTEX][i]->size); + } + if (sp->constants[PIPE_SHADER_GEOMETRY][i]) { + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_GEOMETRY, + i, + sp->mapped_constants[PIPE_SHADER_GEOMETRY][i], + sp->constants[PIPE_SHADER_GEOMETRY][i]->size); + } + } } @@ -87,13 +93,28 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) */ draw_flush(sp->draw); - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, NULL, 0); - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0); + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_VERTEX, + i, + NULL, + 0); + draw_set_mapped_constant_buffer(sp->draw, + PIPE_SHADER_GEOMETRY, + i, + NULL, + 0); + } for (i = 0; i < PIPE_SHADER_TYPES; i++) { - if (sp->constants[i] && sp->constants[i]->size) - ws->buffer_unmap(ws, sp->constants[i]); - sp->mapped_constants[i] = NULL; + uint j; + + for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { + if (sp->constants[i][j] && sp->constants[i][j]->size) { + ws->buffer_unmap(ws, sp->constants[i][j]); + } + sp->mapped_constants[i][j] = NULL; + } } } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 75dac810a12..e8952bf4fb8 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -34,11 +34,9 @@ #include "draw/draw_context.h" #include "sp_flush.h" #include "sp_context.h" -#include "sp_surface.h" #include "sp_state.h" #include "sp_tile_cache.h" #include "sp_tex_tile_cache.h" -#include "sp_winsys.h" void diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index f9129506585..acee2136706 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -135,7 +135,7 @@ fs_sse_run( const struct sp_fragment_shader *base, tgsi_set_exec_mask(machine, 1, 1, 1, 1); shader->func( machine, - machine->Consts, + (const float (*)[4])machine->Consts[0], (const float (*)[4])shader->immediates, machine->InterpCoefs /*, &machine->QuadPos*/ diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 7f573aef3c3..98c08eaffaf 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -526,6 +526,8 @@ static void sp_vbuf_destroy(struct vbuf_render *vbr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + if(cvbr->vertex_buffer) + align_free(cvbr->vertex_buffer); sp_setup_destroy_context(cvbr->setup); FREE(cvbr); } @@ -541,7 +543,6 @@ sp_create_vbuf_backend(struct softpipe_context *sp) assert(sp->draw); - cvbr->base.max_indices = SP_MAX_VBUF_INDEXES; cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index d9babe81dad..d65307b7f60 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -35,7 +35,6 @@ #include "util/u_memory.h" #include "sp_context.h" #include "sp_quad.h" -#include "sp_surface.h" #include "sp_tile_cache.h" #include "sp_quad_pipe.h" @@ -224,7 +223,8 @@ logicop_quad(struct quad_stage *qs, static void blend_quad(struct quad_stage *qs, float (*quadColor)[4], - float (*dest)[4]) + float (*dest)[4], + unsigned cbuf) { static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; @@ -234,7 +234,7 @@ blend_quad(struct quad_stage *qs, /* * Compute src/first term RGB */ - switch (softpipe->blend->rgb_src_factor) { + switch (softpipe->blend->rt[cbuf].rgb_src_factor) { case PIPE_BLENDFACTOR_ONE: VEC4_COPY(source[0], quadColor[0]); /* R */ VEC4_COPY(source[1], quadColor[1]); /* G */ @@ -384,7 +384,7 @@ blend_quad(struct quad_stage *qs, /* * Compute src/first term A */ - switch (softpipe->blend->alpha_src_factor) { + switch (softpipe->blend->rt[cbuf].alpha_src_factor) { case PIPE_BLENDFACTOR_ONE: VEC4_COPY(source[3], quadColor[3]); /* A */ break; @@ -453,7 +453,7 @@ blend_quad(struct quad_stage *qs, /* * Compute dest/second term RGB */ - switch (softpipe->blend->rgb_dst_factor) { + switch (softpipe->blend->rt[cbuf].rgb_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* dest = dest * 1 NO-OP, leave dest as-is */ break; @@ -593,7 +593,7 @@ blend_quad(struct quad_stage *qs, /* * Compute dest/second term A */ - switch (softpipe->blend->alpha_dst_factor) { + switch (softpipe->blend->rt[cbuf].alpha_dst_factor) { case PIPE_BLENDFACTOR_ONE: /* dest = dest * 1 NO-OP, leave dest as-is */ break; @@ -656,7 +656,7 @@ blend_quad(struct quad_stage *qs, /* * Combine RGB terms */ - switch (softpipe->blend->rgb_func) { + switch (softpipe->blend->rt[cbuf].rgb_func) { case PIPE_BLEND_ADD: VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ @@ -689,7 +689,7 @@ blend_quad(struct quad_stage *qs, /* * Combine A terms */ - switch (softpipe->blend->alpha_func) { + switch (softpipe->blend->rt[cbuf].alpha_func) { case PIPE_BLEND_ADD: VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ break; @@ -711,26 +711,24 @@ blend_quad(struct quad_stage *qs, } static void -colormask_quad(struct quad_stage *qs, +colormask_quad(unsigned colormask, float (*quadColor)[4], float (*dest)[4]) { - struct softpipe_context *softpipe = qs->softpipe; - /* R */ - if (!(softpipe->blend->colormask & PIPE_MASK_R)) + if (!(colormask & PIPE_MASK_R)) COPY_4V(quadColor[0], dest[0]); /* G */ - if (!(softpipe->blend->colormask & PIPE_MASK_G)) + if (!(colormask & PIPE_MASK_G)) COPY_4V(quadColor[1], dest[1]); /* B */ - if (!(softpipe->blend->colormask & PIPE_MASK_B)) + if (!(colormask & PIPE_MASK_B)) COPY_4V(quadColor[2], dest[2]); /* A */ - if (!(softpipe->blend->colormask & PIPE_MASK_A)) + if (!(colormask & PIPE_MASK_A)) COPY_4V(quadColor[3], dest[3]); } @@ -773,12 +771,12 @@ blend_fallback(struct quad_stage *qs, if (blend->logicop_enable) { logicop_quad( qs, quadColor, dest ); } - else if (blend->blend_enable) { - blend_quad( qs, quadColor, dest ); + else if (blend->rt[cbuf].blend_enable) { + blend_quad( qs, quadColor, dest, cbuf ); } - if (blend->colormask != 0xf) - colormask_quad( qs, quadColor, dest ); + if (blend->rt[cbuf].colormask != 0xf) + colormask_quad( blend->rt[cbuf].colormask, quadColor, dest); /* Output color values */ @@ -954,23 +952,23 @@ choose_blend_quad(struct quad_stage *qs, qs->run = blend_noop; } else if (!softpipe->blend->logicop_enable && - softpipe->blend->colormask == 0xf && + softpipe->blend->rt[0].colormask == 0xf && softpipe->framebuffer.nr_cbufs == 1) { - if (!blend->blend_enable) { + if (!blend->rt[0].blend_enable) { qs->run = single_output_color; } - else if (blend->rgb_src_factor == blend->alpha_src_factor && - blend->rgb_dst_factor == blend->alpha_dst_factor && - blend->rgb_func == blend->alpha_func) + else if (blend->rt[0].rgb_src_factor == blend->rt[0].alpha_src_factor && + blend->rt[0].rgb_dst_factor == blend->rt[0].alpha_dst_factor && + blend->rt[0].rgb_func == blend->rt[0].alpha_func) { - if (blend->alpha_func == PIPE_BLEND_ADD) { - if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE && - blend->rgb_dst_factor == PIPE_BLENDFACTOR_ONE) { + if (blend->rt[0].alpha_func == PIPE_BLEND_ADD) { + if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_ONE && + blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_ONE) { qs->run = blend_single_add_one_one; } - else if (blend->rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA && - blend->rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA) + else if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA && + blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA) qs->run = blend_single_add_src_alpha_inv_src_alpha; } diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 0ca86c4e1cb..a981775cbd3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -30,11 +30,11 @@ */ #include "pipe/p_defines.h" +#include "util/u_format.h" #include "util/u_memory.h" #include "tgsi/tgsi_scan.h" #include "sp_context.h" #include "sp_quad.h" -#include "sp_surface.h" #include "sp_quad_pipe.h" #include "sp_tile_cache.h" #include "sp_state.h" /* for sp_fragment_shader */ @@ -651,6 +651,20 @@ static unsigned mask_count[16] = +/** helper to get number of Z buffer bits */ +static unsigned +get_depth_bits(struct quad_stage *qs) +{ + struct pipe_surface *zsurf = qs->softpipe->framebuffer.zsbuf; + if (zsurf) + return util_format_get_component_bits(zsurf->format, + UTIL_FORMAT_COLORSPACE_ZS, 0); + else + return 0; +} + + + static void depth_test_quads_fallback(struct quad_stage *qs, struct quad_header *quads[], @@ -666,7 +680,7 @@ depth_test_quads_fallback(struct quad_stage *qs, nr = alpha_test_quads(qs, quads, nr); } - if (qs->softpipe->framebuffer.zsbuf && + if (get_depth_bits(qs) > 0 && (qs->softpipe->depth_stencil->depth.enabled || qs->softpipe->depth_stencil->stencil[0].enabled)) { @@ -884,7 +898,7 @@ choose_depth_test(struct quad_stage *qs, boolean alpha = qs->softpipe->depth_stencil->alpha.enabled; - boolean depth = (qs->softpipe->framebuffer.zsbuf && + boolean depth = (get_depth_bits(qs) > 0 && qs->softpipe->depth_stencil->depth.enabled); unsigned depthfunc = qs->softpipe->depth_stencil->depth.func; @@ -895,7 +909,6 @@ choose_depth_test(struct quad_stage *qs, boolean occlusion = qs->softpipe->active_query_count; - if (!alpha && !depth && !stencil) { diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 1e7533d0f9e..ad04dc2afc3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -45,8 +45,6 @@ #include "sp_state.h" #include "sp_quad.h" #include "sp_quad_pipe.h" -#include "sp_texture.h" -#include "sp_tex_sample.h" struct quad_shade_stage @@ -109,10 +107,11 @@ shade_quads(struct quad_stage *qs, struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = qss->machine; - unsigned i, pass = 0; - - machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { + machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i]; + } machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index bd3532de4f4..714a1cf5343 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -91,6 +91,19 @@ softpipe_get_param(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_BLEND_EQUATION_SEPARATE: return 1; + case PIPE_CAP_MAX_CONST_BUFFERS: + return PIPE_MAX_CONSTANT_BUFFERS; + case PIPE_CAP_MAX_CONST_BUFFER_SIZE: + return 4096 * 4 * sizeof(float); + case PIPE_CAP_INDEP_BLEND_ENABLE: + return 1; + case PIPE_CAP_INDEP_BLEND_FUNC: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 1; default: return 0; } diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 3da75364c5d..bb1bff581cf 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -38,10 +38,8 @@ #include "sp_setup.h" #include "sp_state.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "pipe/p_shader_tokens.h" -#include "pipe/p_thread.h" #include "util/u_math.h" #include "util/u_memory.h" @@ -506,21 +504,24 @@ static void tri_persp_coeff( struct setup_context *setup, /** * Special coefficient setup for gl_FragCoord. - * X and Y are trivial, though Y has to be inverted for OpenGL. + * X and Y are trivial, though Y may have to be inverted for OpenGL. * Z and W are copied from posCoef which should have already been computed. * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. */ static void setup_fragcoord_coeff(struct setup_context *setup, uint slot) { + struct sp_fragment_shader* spfs = setup->softpipe->fs; /*X*/ - setup->coef[slot].a0[0] = 0; + setup->coef[slot].a0[0] = spfs->pixel_center_integer ? 0.0 : 0.5; setup->coef[slot].dadx[0] = 1.0; setup->coef[slot].dady[0] = 0.0; /*Y*/ - setup->coef[slot].a0[1] = 0.0; + setup->coef[slot].a0[1] = + (spfs->origin_lower_left ? setup->softpipe->framebuffer.height : 0) + + (spfs->pixel_center_integer ? 0.0 : 0.5); setup->coef[slot].dadx[1] = 0.0; - setup->coef[slot].dady[1] = 1.0; + setup->coef[slot].dady[1] = spfs->origin_lower_left ? -1.0 : 1.0; /*Z*/ setup->coef[slot].a0[2] = setup->posCoef.a0[2]; setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 7f244c4fd49..a83cae73617 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -68,6 +68,9 @@ struct sp_fragment_shader { struct tgsi_shader_info info; + boolean origin_lower_left; /**< fragment shader uses lower left position origin? */ + boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */ + void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct tgsi_sampler **samplers); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index b7ed4441b43..de3edde9760 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -44,6 +44,7 @@ softpipe_create_fs_state(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state; + unsigned i; /* debug */ if (softpipe->dump_fs) @@ -60,6 +61,13 @@ softpipe_create_fs_state(struct pipe_context *pipe, /* get/save the summary info for this shader */ tgsi_scan_shader(templ->tokens, &state->info); + for (i = 0; i < state->info.num_properties; ++i) { + if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN) + state->origin_lower_left = state->info.properties[i].data[0]; + else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER) + state->pixel_center_integer = state->info.properties[i].data[0]; + } + return state; } @@ -164,12 +172,12 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); + assert(index < PIPE_MAX_CONSTANT_BUFFERS); draw_flush(softpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&softpipe->constants[shader], buf); + pipe_buffer_reference(&softpipe->constants[shader][index], buf); softpipe->dirty |= SP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index f6154109ea8..39466782195 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -30,7 +30,6 @@ #include "sp_context.h" #include "sp_state.h" -#include "sp_surface.h" #include "sp_tile_cache.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 46b6991195d..b491d92ed15 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -31,7 +31,6 @@ #include "sp_context.h" #include "sp_state.h" -#include "sp_surface.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 1ae8fecacf7..473ec3e150a 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -517,7 +517,6 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, const float p[QUAD_SIZE]) { const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float rho = MAX2(dsdx, dsdy) * texture->width0; @@ -533,7 +532,6 @@ compute_lambda_2d(const struct sp_sampler_varient *samp, const float p[QUAD_SIZE]) { const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); @@ -553,7 +551,6 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, const float p[QUAD_SIZE]) { const struct pipe_texture *texture = samp->texture; - const struct pipe_sampler_state *sampler = samp->sampler; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index e50a76a73bc..50242d5bd69 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -37,7 +37,6 @@ #include "util/u_tile.h" #include "util/u_math.h" #include "sp_context.h" -#include "sp_surface.h" #include "sp_texture.h" #include "sp_tex_tile_cache.h" diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index a9436a33942..a5fff915077 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -38,7 +38,6 @@ #include "util/u_memory.h" #include "sp_context.h" -#include "sp_state.h" #include "sp_texture.h" #include "sp_screen.h" #include "sp_winsys.h" @@ -57,13 +56,8 @@ softpipe_texture_layout(struct pipe_screen *screen, unsigned width = pt->width0; unsigned height = pt->height0; unsigned depth = pt->depth0; - unsigned buffer_size = 0; - pt->width0 = width; - pt->height0 = height; - pt->depth0 = depth; - for (level = 0; level <= pt->last_level; level++) { spt->stride[level] = util_format_get_stride(pt->format, width); @@ -296,6 +290,10 @@ softpipe_get_tex_transfer(struct pipe_screen *screen, assert(texture); assert(level <= texture->last_level); + /* make sure the requested region is in the image bounds */ + assert(x + w <= u_minify(texture->width0, level)); + assert(y + h <= u_minify(texture->height0, level)); + spt = CALLOC_STRUCT(softpipe_transfer); if (spt) { struct pipe_transfer *pt = &spt->base; diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index cae2d3efc58..d0723ebe9e0 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -185,17 +185,18 @@ init_pipe_state(struct sp_mpeg12_context *ctx) ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast); ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast); - blend.blend_enable = 0; - blend.rgb_func = PIPE_BLEND_ADD; - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_func = PIPE_BLEND_ADD; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.independent_blend_enable = 0; + blend.rt[0].blend_enable = 0; + blend.rt[0].rgb_func = PIPE_BLEND_ADD; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_func = PIPE_BLEND_ADD; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; blend.logicop_enable = 0; blend.logicop_func = PIPE_LOGICOP_CLEAR; /* Needed to allow color writes to FB, even if blending disabled */ - blend.colormask = PIPE_MASK_RGBA; + blend.rt[0].colormask = PIPE_MASK_RGBA; blend.dither = 0; ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend); ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend); diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c new file mode 100644 index 00000000000..38bcd64c6a5 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_winsys.c @@ -0,0 +1,244 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Malloc softpipe winsys. Uses malloc for all memory allocations. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "pipe/internal/p_winsys_screen.h"/* port to just p_screen */ +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "util/u_format.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "softpipe/sp_winsys.h" + + +struct st_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = st_softpipe_buf->data; + return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct st_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(st_softpipe_buffer); + if(!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +static struct pipe_buffer * +st_softpipe_surface_buffer_create(struct pipe_winsys *winsys, + unsigned width, unsigned height, + enum pipe_format format, + unsigned usage, + unsigned tex_usage, + unsigned *stride) +{ + const unsigned alignment = 64; + unsigned nblocksy; + + nblocksy = util_format_get_nblocksy(format, height); + *stride = align(util_format_get_stride(format, width), alignment); + + return winsys->buffer_create(winsys, alignment, + usage, + *stride * nblocksy); +} + + +static void +st_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +st_softpipe_destroy(struct pipe_winsys *winsys) +{ + FREE(winsys); +} + + +struct pipe_screen * +softpipe_create_screen_malloc(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->destroy = st_softpipe_destroy; + + winsys->buffer_create = st_softpipe_buffer_create; + winsys->user_buffer_create = st_softpipe_user_buffer_create; + winsys->buffer_map = st_softpipe_buffer_map; + winsys->buffer_unmap = st_softpipe_buffer_unmap; + winsys->buffer_destroy = st_softpipe_buffer_destroy; + + winsys->surface_buffer_create = st_softpipe_surface_buffer_create; + + winsys->fence_reference = st_softpipe_fence_reference; + winsys->fence_signalled = st_softpipe_fence_signalled; + winsys->fence_finish = st_softpipe_fence_finish; + + winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; + winsys->get_name = st_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + st_softpipe_destroy(winsys); + + return screen; +} diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index f203ded29ee..3042e01a05c 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -49,10 +49,17 @@ struct pipe_buffer; struct pipe_context *softpipe_create( struct pipe_screen * ); +/** + * Create a softpipe screen that uses the + * given winsys for allocating buffers. + */ +struct pipe_screen *softpipe_create_screen( struct pipe_winsys * ); -struct pipe_screen * -softpipe_create_screen(struct pipe_winsys *); - +/** + * Create a softpipe screen that uses + * regular malloc to create all its buffers. + */ +struct pipe_screen *softpipe_create_screen_malloc(void); boolean softpipe_get_texture_buffer( struct pipe_texture *texture, diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c index 75492dffca2..6b6ebc9b585 100644 --- a/src/gallium/drivers/svga/svga_draw_arrays.c +++ b/src/gallium/drivers/svga/svga_draw_arrays.c @@ -26,7 +26,6 @@ #include "svga_cmd.h" #include "pipe/p_inlines.h" -#include "util/u_prim.h" #include "indices/u_indices.h" #include "svga_hw_reg.h" diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index 167d8178315..022b444eb91 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -24,7 +24,6 @@ **********************************************************/ #include "pipe/p_inlines.h" -#include "util/u_prim.h" #include "util/u_upload_mgr.h" #include "indices/u_indices.h" diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c index 855d228755f..9df5485f462 100644 --- a/src/gallium/drivers/svga/svga_pipe_blend.c +++ b/src/gallium/drivers/svga/svga_pipe_blend.c @@ -29,7 +29,6 @@ #include "util/u_memory.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_hw_reg.h" @@ -182,15 +181,15 @@ svga_create_blend_state(struct pipe_context *pipe, } } else { - blend->rt[i].blend_enable = templ->blend_enable; + blend->rt[i].blend_enable = templ->rt[0].blend_enable; - if (templ->blend_enable) { - blend->rt[i].srcblend = svga_translate_blend_factor(templ->rgb_src_factor); - blend->rt[i].dstblend = svga_translate_blend_factor(templ->rgb_dst_factor); - blend->rt[i].blendeq = svga_translate_blend_func(templ->rgb_func); - blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->alpha_src_factor); - blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->alpha_dst_factor); - blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->alpha_func); + if (templ->rt[0].blend_enable) { + blend->rt[i].srcblend = svga_translate_blend_factor(templ->rt[0].rgb_src_factor); + blend->rt[i].dstblend = svga_translate_blend_factor(templ->rt[0].rgb_dst_factor); + blend->rt[i].blendeq = svga_translate_blend_func(templ->rt[0].rgb_func); + blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_src_factor); + blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_dst_factor); + blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->rt[0].alpha_func); if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend || blend->rt[i].dstblend_alpha != blend->rt[i].dstblend || @@ -201,7 +200,7 @@ svga_create_blend_state(struct pipe_context *pipe, } } - blend->rt[i].writemask = templ->colormask; + blend->rt[i].writemask = templ->rt[0].colormask; } return blend; diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c index ca2c7c49d72..9022f7c4394 100644 --- a/src/gallium/drivers/svga/svga_pipe_constants.c +++ b/src/gallium/drivers/svga/svga_pipe_constants.c @@ -26,13 +26,9 @@ #include "pipe/p_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" -#include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "svga_context.h" -#include "svga_state.h" -#include "svga_hw_reg.h" -#include "svga_cmd.h" /*********************************************************************** * Constant buffers diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c index df636c08a05..34e60cb341a 100644 --- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c +++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c @@ -29,7 +29,6 @@ #include "util/u_memory.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_hw_reg.h" diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 0f24ef4ee8d..4e0c499dc3e 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -33,7 +33,6 @@ #include "svga_hw_reg.h" #include "svga_context.h" #include "svga_screen.h" -#include "svga_winsys.h" #include "svga_draw.h" #include "svga_state.h" #include "svga_swtnl.h" diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c index 0becb0765ac..3eb10336c4e 100644 --- a/src/gallium/drivers/svga/svga_pipe_flush.c +++ b/src/gallium/drivers/svga/svga_pipe_flush.c @@ -28,13 +28,8 @@ #include "svga_screen_texture.h" #include "svga_context.h" #include "svga_winsys.h" -#include "svga_draw.h" #include "svga_debug.h" -#include "svga_hw_reg.h" - - - static void svga_flush( struct pipe_context *pipe, unsigned flags, diff --git a/src/gallium/drivers/svga/svga_pipe_fs.c b/src/gallium/drivers/svga/svga_pipe_fs.c index 5f1213e46a3..32f07fb2616 100644 --- a/src/gallium/drivers/svga/svga_pipe_fs.c +++ b/src/gallium/drivers/svga/svga_pipe_fs.c @@ -32,11 +32,9 @@ #include "svga_screen.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_tgsi.h" #include "svga_hw_reg.h" #include "svga_cmd.h" -#include "svga_draw.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c index 58cb1e6e230..8cf1f2e083a 100644 --- a/src/gallium/drivers/svga/svga_pipe_misc.c +++ b/src/gallium/drivers/svga/svga_pipe_misc.c @@ -27,12 +27,6 @@ #include "svga_context.h" #include "svga_screen_texture.h" -#include "svga_state.h" -#include "svga_winsys.h" - -#include "svga_hw_reg.h" - - static void svga_set_scissor_state( struct pipe_context *pipe, diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 01336b0a2c3..08283e37317 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -32,7 +32,6 @@ #include "svga_screen.h" #include "svga_screen_buffer.h" #include "svga_winsys.h" -#include "svga_draw.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c index b03f8eb9cf3..9ea11aad9a9 100644 --- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c +++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c @@ -30,7 +30,6 @@ #include "util/u_memory.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_hw_reg.h" diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 460a101f8c0..161c66dd4ff 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -32,9 +32,6 @@ #include "svga_context.h" #include "svga_screen_texture.h" -#include "svga_state.h" - -#include "svga_hw_reg.h" #include "svga_debug.h" diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 42f290d162a..724166a3352 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -26,16 +26,11 @@ #include "pipe/p_inlines.h" #include "pipe/p_defines.h" #include "util/u_math.h" -#include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "svga_screen.h" #include "svga_screen_buffer.h" #include "svga_context.h" -#include "svga_state.h" -#include "svga_winsys.h" - -#include "svga_hw_reg.h" static void svga_set_vertex_buffers(struct pipe_context *pipe, diff --git a/src/gallium/drivers/svga/svga_pipe_vs.c b/src/gallium/drivers/svga/svga_pipe_vs.c index 7e6ab576add..c4ac5304ac6 100644 --- a/src/gallium/drivers/svga/svga_pipe_vs.c +++ b/src/gallium/drivers/svga/svga_pipe_vs.c @@ -33,7 +33,6 @@ #include "svga_screen.h" #include "svga_context.h" -#include "svga_state.h" #include "svga_tgsi.h" #include "svga_hw_reg.h" #include "svga_cmd.h" diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index fc1b3c980ef..c9db9ac8747 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -33,10 +33,8 @@ #include "svga_screen.h" #include "svga_screen_texture.h" #include "svga_screen_buffer.h" -#include "svga_cmd.h" #include "svga_debug.h" -#include "svga_hw_reg.h" #include "svga3d_shaderdefs.h" @@ -146,6 +144,13 @@ svga_get_paramf(struct pipe_screen *screen, int param) case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; + default: return 0; } @@ -393,8 +398,6 @@ svga_screen_create(struct svga_winsys_screen *sws) pipe_mutex_init(svgascreen->tex_mutex); pipe_mutex_init(svgascreen->swc_mutex); - LIST_INITHEAD(&svgascreen->cached_buffers); - svga_screen_cache_init(svgascreen); return screen; diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h index b94ca7fc1ca..a009b607200 100644 --- a/src/gallium/drivers/svga/svga_screen.h +++ b/src/gallium/drivers/svga/svga_screen.h @@ -68,12 +68,6 @@ struct svga_screen pipe_mutex tex_mutex; pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */ - /** - * List of buffers with cached GMR. Ordered from the most recently used to - * the least recently used - */ - struct list_head cached_buffers; - struct svga_host_surface_cache cache; }; diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c index 58a1aba464b..430a6970fde 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.c +++ b/src/gallium/drivers/svga/svga_screen_buffer.c @@ -113,68 +113,9 @@ svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf) if(sbuf->hw.buf) { sws->buffer_destroy(sws, sbuf->hw.buf); sbuf->hw.buf = NULL; - assert(sbuf->head.prev && sbuf->head.next); - LIST_DEL(&sbuf->head); -#ifdef DEBUG - sbuf->head.next = sbuf->head.prev = NULL; -#endif } } -static INLINE enum pipe_error -svga_buffer_backup(struct svga_screen *ss, struct svga_buffer *sbuf) -{ - if (sbuf->hw.buf && sbuf->hw.num_ranges) { - void *src; - - if (!sbuf->swbuf) - sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment); - if (!sbuf->swbuf) - return PIPE_ERROR_OUT_OF_MEMORY; - - src = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, - PIPE_BUFFER_USAGE_CPU_READ); - if (!src) - return PIPE_ERROR; - - memcpy(sbuf->swbuf, src, sbuf->base.size); - ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf); - } - - return PIPE_OK; -} - -/** - * Try to make GMR space available by freeing the hardware storage of - * unmapped - */ -boolean -svga_buffer_free_cached_hw_storage(struct svga_screen *ss) -{ - struct list_head *curr; - struct svga_buffer *sbuf; - enum pipe_error ret = PIPE_OK; - - curr = ss->cached_buffers.prev; - - /* free the least recently used buffer's hw storage which is not mapped */ - do { - if(curr == &ss->cached_buffers) - return FALSE; - - sbuf = LIST_ENTRY(struct svga_buffer, curr, head); - - curr = curr->prev; - if (sbuf->map.count == 0) - ret = svga_buffer_backup(ss, sbuf); - - } while(sbuf->map.count != 0 || ret != PIPE_OK); - - svga_buffer_destroy_hw_storage(ss, sbuf); - - return TRUE; -} - struct svga_winsys_buffer * svga_winsys_buffer_create( struct svga_screen *ss, unsigned alignment, @@ -195,12 +136,6 @@ svga_winsys_buffer_create( struct svga_screen *ss, svga_screen_flush(ss, NULL); buf = sws->buffer_create(sws, alignment, usage, size); - SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "evicting buffers to find %d bytes GMR\n", - size); - - /* Try evicing all buffer storage */ - while(!buf && svga_buffer_free_cached_hw_storage(ss)) - buf = sws->buffer_create(sws, alignment, usage, size); } return buf; @@ -226,8 +161,6 @@ svga_buffer_create_hw_storage(struct svga_screen *ss, return PIPE_ERROR_OUT_OF_MEMORY; assert(!sbuf->needs_flush); - assert(!sbuf->head.prev && !sbuf->head.next); - LIST_ADD(&sbuf->head, &ss->cached_buffers); } return PIPE_OK; @@ -311,7 +244,6 @@ static void svga_buffer_upload_flush(struct svga_context *svga, struct svga_buffer *sbuf) { - struct svga_screen *ss = svga_screen(svga->pipe.screen); SVGA3dCopyBox *boxes; unsigned i; @@ -348,13 +280,16 @@ svga_buffer_upload_flush(struct svga_context *svga, assert(sbuf->head.prev && sbuf->head.next); LIST_DEL(&sbuf->head); +#ifdef DEBUG + sbuf->head.next = sbuf->head.prev = NULL; +#endif sbuf->needs_flush = FALSE; - /* XXX: do we care about cached_buffers any more ?*/ - LIST_ADD(&sbuf->head, &ss->cached_buffers); sbuf->hw.svga = NULL; sbuf->hw.boxes = NULL; + sbuf->host_written = TRUE; + /* Decrement reference count */ pipe_reference(&(sbuf->base.reference), NULL); sbuf = NULL; @@ -437,17 +372,17 @@ svga_buffer_map_range( struct pipe_screen *screen, } else { if(!sbuf->hw.buf) { - struct svga_winsys_surface *handle = sbuf->handle; - if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) return NULL; /* Populate the hardware storage if the host surface pre-existed */ - if((usage & PIPE_BUFFER_USAGE_CPU_READ) && handle) { + if(sbuf->host_written) { SVGA3dSurfaceDMAFlags flags; enum pipe_error ret; struct pipe_fence_handle *fence = NULL; + assert(sbuf->handle); + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n", sbuf->handle, 0, sbuf->base.size); @@ -478,17 +413,6 @@ svga_buffer_map_range( struct pipe_screen *screen, sws->fence_reference(sws, &fence, NULL); } } - else { - if((usage & PIPE_BUFFER_USAGE_CPU_READ) && !sbuf->needs_flush) { - /* We already had the hardware storage but we would have to issue - * a download if we hadn't, so move the buffer to the begginning - * of the LRU list. - */ - assert(sbuf->head.prev && sbuf->head.next); - LIST_DEL(&sbuf->head); - LIST_ADD(&sbuf->head, &ss->cached_buffers); - } - } map = sws->buffer_map(sws, sbuf->hw.buf, usage); } @@ -572,10 +496,8 @@ svga_buffer_destroy( struct pipe_buffer *buf ) assert(!sbuf->needs_flush); - if(sbuf->handle) { - SVGA_DBG(DEBUG_DMA, "release sid %p sz %d\n", sbuf->handle, sbuf->base.size); - svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle); - } + if(sbuf->handle) + svga_buffer_destroy_host_surface(ss, sbuf); if(sbuf->hw.buf) svga_buffer_destroy_hw_storage(ss, sbuf); @@ -595,6 +517,9 @@ svga_buffer_create(struct pipe_screen *screen, struct svga_screen *ss = svga_screen(screen); struct svga_buffer *sbuf; + assert(size); + assert(alignment); + sbuf = CALLOC_STRUCT(svga_buffer); if(!sbuf) goto error1; @@ -755,8 +680,7 @@ svga_buffer_handle(struct svga_context *svga, assert(sbuf->hw.svga == svga); sbuf->needs_flush = TRUE; - assert(sbuf->head.prev && sbuf->head.next); - LIST_DEL(&sbuf->head); + assert(!sbuf->head.prev && !sbuf->head.next); LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers); } diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_screen_buffer.h index 5d7af5a7c50..448ac107c7f 100644 --- a/src/gallium/drivers/svga/svga_screen_buffer.h +++ b/src/gallium/drivers/svga/svga_screen_buffer.h @@ -135,6 +135,11 @@ struct svga_buffer */ struct svga_winsys_surface *handle; + /** + * Whether the host has been ever written. + */ + boolean host_written; + struct { unsigned count; boolean writing; @@ -178,9 +183,6 @@ svga_buffer_handle(struct svga_context *svga, void svga_context_flush_buffers(struct svga_context *svga); -boolean -svga_buffer_free_cached_hw_storage(struct svga_screen *ss); - struct svga_winsys_buffer * svga_winsys_buffer_create(struct svga_screen *ss, unsigned alignment, diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c index 2224c2d3945..0d69007fd87 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.c +++ b/src/gallium/drivers/svga/svga_screen_texture.c @@ -306,11 +306,19 @@ svga_texture_create(struct pipe_screen *screen, tex->key.numFaces = 1; } + tex->key.cachable = 1; + if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE; - if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) + if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + tex->key.cachable = 0; + } + + if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) { tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT; + tex->key.cachable = 0; + } /* * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot @@ -333,8 +341,6 @@ svga_texture_create(struct pipe_screen *screen, if(tex->key.format == SVGA3D_FORMAT_INVALID) goto error2; - tex->key.cachable = 1; - SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle); tex->handle = svga_screen_surface_create(svgascreen, &tex->key); if (tex->handle) @@ -416,6 +422,62 @@ svga_texture_blanket(struct pipe_screen * screen, } +struct pipe_texture * +svga_screen_texture_wrap_surface(struct pipe_screen *screen, + struct pipe_texture *base, + enum SVGA3dSurfaceFormat format, + struct svga_winsys_surface *srf) +{ + struct svga_texture *tex; + assert(screen); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth0 != 1) { + return NULL; + } + + if (!srf) + return NULL; + + if (svga_translate_format(base->format) != format) { + unsigned f1 = svga_translate_format(base->format); + unsigned f2 = format; + + /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */ + if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) || + (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) || + (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) { + debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2); + return NULL; + } + } + + tex = CALLOC_STRUCT(svga_texture); + if (!tex) + return NULL; + + tex->base = *base; + + + if (format == 1) + tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM; + else if (format == 2) + tex->base.format = PIPE_FORMAT_A8R8G8B8_UNORM; + + pipe_reference_init(&tex->base.reference, 1); + tex->base.screen = screen; + + SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf); + + tex->key.cachable = 0; + tex->handle = srf; + + return &tex->base; +} + + static void svga_texture_destroy(struct pipe_texture *pt) { diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index cfdcae4ee4a..eda1aefd67a 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -32,8 +32,6 @@ #include "svga_cmd.h" #include "svga_debug.h" -#include "svga_hw_reg.h" - /*********************************************************************** * Hardware state update diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index 8b6803a285a..2f9adaeb561 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -31,9 +31,6 @@ #include "svga_state.h" #include "svga_cmd.h" -#include "svga_hw_reg.h" - - struct rs_queue { unsigned rs_count; diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index b3137945202..b3c9687b1a4 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -33,8 +33,6 @@ #include "svga_state.h" #include "svga_cmd.h" -#include "svga_hw_reg.h" - void svga_cleanup_tss_binding(struct svga_context *svga) { diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index b4f757a47a9..aafb3e26b0b 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -31,7 +31,6 @@ #include "pipe/p_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "util/u_simple_shaders.h" #include "svga_context.h" #include "svga_state.h" @@ -87,13 +86,13 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render, if (!svga_render->vbuf) { svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size); svga_render->vbuf = pipe_buffer_create(screen, - 0, + 16, PIPE_BUFFER_USAGE_VERTEX, svga_render->vbuf_size); if(!svga_render->vbuf) { svga_context_flush(svga, NULL); svga_render->vbuf = pipe_buffer_create(screen, - 0, + 16, PIPE_BUFFER_USAGE_VERTEX, svga_render->vbuf_size); assert(svga_render->vbuf); @@ -123,7 +122,9 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render ) char *ptr = (char*)pipe_buffer_map(screen, svga_render->vbuf, PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_FLUSH_EXPLICIT); + PIPE_BUFFER_USAGE_FLUSH_EXPLICIT | + PIPE_BUFFER_USAGE_DISCARD | + PIPE_BUFFER_USAGE_UNSYNCHRONIZED); return ptr + svga_render->vbuf_offset; } @@ -259,14 +260,14 @@ svga_vbuf_render_draw( struct vbuf_render *render, if (!svga_render->ibuf) { svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size); svga_render->ibuf = pipe_buffer_create(screen, - 0, + 2, PIPE_BUFFER_USAGE_VERTEX, svga_render->ibuf_size); svga_render->ibuf_offset = 0; } - pipe_buffer_write(screen, svga_render->ibuf, - svga_render->ibuf_offset, 2 * nr_indices, indices); + pipe_buffer_write_nooverlap(screen, svga_render->ibuf, + svga_render->ibuf_offset, 2 * nr_indices, indices); /* off to hardware */ diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index 7655121bec1..5e6e30c7dfb 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -27,7 +27,6 @@ #include "draw/draw_vbuf.h" #include "pipe/p_inlines.h" #include "pipe/p_state.h" -#include "util/u_memory.h" #include "svga_context.h" #include "svga_swtnl.h" @@ -90,7 +89,7 @@ svga_swtnl_draw_range_elements(struct svga_context *svga, PIPE_BUFFER_USAGE_CPU_READ); assert(map); draw_set_mapped_constant_buffer( - draw, PIPE_SHADER_VERTEX, + draw, PIPE_SHADER_VERTEX, 0, map, svga->curr.cb[PIPE_SHADER_VERTEX]->size); } diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c index 94b6ccc62dd..fe03e207fff 100644 --- a/src/gallium/drivers/svga/svga_swtnl_state.c +++ b/src/gallium/drivers/svga/svga_swtnl_state.c @@ -27,7 +27,6 @@ #include "draw/draw_vbuf.h" #include "pipe/p_inlines.h" #include "pipe/p_state.h" -#include "util/u_memory.h" #include "svga_context.h" #include "svga_swtnl.h" diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c index 23b3ace7f30..1ae99067610 100644 --- a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c +++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c @@ -29,9 +29,6 @@ #include "util/u_memory.h" #include "svga_tgsi_emit.h" -#include "svga_context.h" - - static boolean ps20_input( struct svga_shader_emitter *emit, diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c index d1c7336dec4..43fc0d32359 100644 --- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c +++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c @@ -29,7 +29,6 @@ #include "util/u_memory.h" #include "svga_tgsi_emit.h" -#include "svga_context.h" static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic, unsigned *usage, diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index 59f299c1858..27b99fe4c10 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -296,4 +296,10 @@ svga_screen_buffer_from_texture(struct pipe_texture *texture, struct pipe_buffer **buffer, unsigned *stride); +struct pipe_texture * +svga_screen_texture_wrap_surface(struct pipe_screen *screen, + struct pipe_texture *base, + enum SVGA3dSurfaceFormat format, + struct svga_winsys_surface *srf); + #endif /* SVGA_WINSYS_H_ */ diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c index 48d1c4051cc..e7ca3a86ead 100644 --- a/src/gallium/drivers/trace/tr_drm.c +++ b/src/gallium/drivers/trace/tr_drm.c @@ -173,6 +173,7 @@ trace_drm_create(struct drm_api *api) if (!tr_api) goto error; + tr_api->base.driver_name = api->driver_name; tr_api->base.create_screen = trace_drm_create_screen; tr_api->base.create_context = trace_drm_create_context; tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 32f61f8c944..dbca5de0a52 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -323,9 +323,23 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ trace_dump_struct_end(); } +static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state) +{ + trace_dump_member(uint, state, rgb_func); + trace_dump_member(uint, state, rgb_src_factor); + trace_dump_member(uint, state, rgb_dst_factor); + + trace_dump_member(uint, state, alpha_func); + trace_dump_member(uint, state, alpha_src_factor); + trace_dump_member(uint, state, alpha_dst_factor); + + trace_dump_member(uint, state, colormask); + +} void trace_dump_blend_state(const struct pipe_blend_state *state) { + unsigned valid_entries = 1; if (!trace_dumping_enabled_locked()) return; @@ -336,21 +350,17 @@ void trace_dump_blend_state(const struct pipe_blend_state *state) trace_dump_struct_begin("pipe_blend_state"); - trace_dump_member(bool, state, blend_enable); - - trace_dump_member(uint, state, rgb_func); - trace_dump_member(uint, state, rgb_src_factor); - trace_dump_member(uint, state, rgb_dst_factor); - - trace_dump_member(uint, state, alpha_func); - trace_dump_member(uint, state, alpha_src_factor); - trace_dump_member(uint, state, alpha_dst_factor); + trace_dump_member(bool, state, dither); trace_dump_member(bool, state, logicop_enable); trace_dump_member(uint, state, logicop_func); - trace_dump_member(uint, state, colormask); - trace_dump_member(bool, state, dither); + trace_dump_member(bool, state, independent_blend_enable); + + if (state->independent_blend_enable) + valid_entries = PIPE_MAX_COLOR_BUFS; + + trace_dump_struct_array(rt_blend_state, state->rt, valid_entries); trace_dump_struct_end(); } |