diff options
author | Roland Scheidegger <[email protected]> | 2010-05-04 15:58:29 +0200 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2010-05-04 15:58:29 +0200 |
commit | 0ae2f59c0287f4baec6c7de5f2f0fdf736fba26d (patch) | |
tree | ee14bf3e8bba80649541c4e13fc07c60baf6c248 /src/gallium/drivers | |
parent | 7662e3519bef3802024da3050b886068281e02b1 (diff) | |
parent | 1c920c61764b17fd9fb4a89d2db7355fbe1d7565 (diff) |
Merge commit 'origin/master' into gallium-msaa
Diffstat (limited to 'src/gallium/drivers')
50 files changed, 604 insertions, 611 deletions
diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index ffb8595d828..6696a4591c1 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "util/u_rect.h" +#include "util/u_surface.h" #include "cell_context.h" #include "cell_surface.h" diff --git a/src/gallium/drivers/i965/brw_wm_debug.c b/src/gallium/drivers/i965/brw_wm_debug.c index 3d11fa074cc..e2767264e7e 100644 --- a/src/gallium/drivers/i965/brw_wm_debug.c +++ b/src/gallium/drivers/i965/brw_wm_debug.c @@ -202,7 +202,8 @@ static const char *file_strings[TGSI_FILE_COUNT+1] = { "SAMPLER", "ADDR", "IMM", - "LOOP", + "PRED", + "SV", "PAYLOAD" }; diff --git a/src/gallium/drivers/i965/intel_decode.c b/src/gallium/drivers/i965/intel_decode.c index 6c47415cac5..bd8b9174a89 100644 --- a/src/gallium/drivers/i965/intel_decode.c +++ b/src/gallium/drivers/i965/intel_decode.c @@ -40,6 +40,7 @@ #include <stdint.h> #include <string.h> +#include "util/u_string.h" #include "intel_decode.h" /*#include "intel_chipset.h"*/ @@ -478,7 +479,7 @@ i915_get_instruction_src0(const uint32_t *data, int i, char *srcname) char swizzle[100]; i915_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname); - sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); + util_snprintf(swizzle, sizeof(swizzle), ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); if (strcmp(swizzle, ".xyzw") != 0) strcat(srcname, swizzle); } @@ -496,7 +497,7 @@ i915_get_instruction_src1(const uint32_t *data, int i, char *srcname) char swizzle[100]; i915_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname); - sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); + util_snprintf(swizzle, sizeof(swizzle), ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); if (strcmp(swizzle, ".xyzw") != 0) strcat(srcname, swizzle); } @@ -513,7 +514,7 @@ i915_get_instruction_src2(const uint32_t *data, int i, char *srcname) char swizzle[100]; i915_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname); - sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); + util_snprintf(swizzle, sizeof(swizzle), ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w); if (strcmp(swizzle, ".xyzw") != 0) strcat(srcname, swizzle); } @@ -642,7 +643,7 @@ i915_decode_dcl(const uint32_t *data, uint32_t hw_offset, int i, char *instr_pre switch ((d0 >> 19) & 0x3) { case 1: - sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w); + util_snprintf(dcl_mask, sizeof(dcl_mask), ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w); if (strcmp(dcl_mask, ".") == 0) fprintf(out, "bad (empty) dcl mask\n"); @@ -976,7 +977,7 @@ decode_3d_1d(const uint32_t *data, int count, uint32_t hw_offset, int *failures, if (i + 3 >= count) BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_PROGRAM"); - sprintf(instr_prefix, "PS%03d", instr); + util_snprintf(instr_prefix, sizeof(instr_prefix), "PS%03d", instr); i915_decode_instruction(data, hw_offset, i, instr_prefix); i += 3; } diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 0bc8bf21966..7e62213597c 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -684,79 +684,67 @@ identity_flush(struct pipe_context *_pipe, static unsigned int identity_is_resource_referenced(struct pipe_context *_pipe, - struct pipe_resource *_resource, - unsigned face, - unsigned level) + struct pipe_resource *_resource, + unsigned face, + unsigned level) { struct identity_context *id_pipe = identity_context(_pipe); struct identity_resource *id_resource = identity_resource(_resource); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_resource *texture = id_resource->resource; + struct pipe_resource *resource = id_resource->resource; return pipe->is_resource_referenced(pipe, - texture, - face, - level); + resource, + face, + level); } static struct pipe_sampler_view * -identity_create_sampler_view(struct pipe_context *pipe, - struct pipe_resource *texture, - const struct pipe_sampler_view *templ) +identity_context_create_sampler_view(struct pipe_context *_pipe, + struct pipe_resource *_resource, + const struct pipe_sampler_view *templ) { - struct identity_context *id_pipe = identity_context(pipe); - struct identity_resource *id_resource = identity_resource(texture); - struct pipe_context *pipe_unwrapped = id_pipe->pipe; - struct pipe_resource *texture_unwrapped = id_resource->resource; - struct identity_sampler_view *view = MALLOC(sizeof(struct identity_sampler_view)); - - view->sampler_view = pipe_unwrapped->create_sampler_view(pipe_unwrapped, - texture_unwrapped, - templ); + struct identity_context *id_context = identity_context(_pipe); + struct identity_resource *id_resource = identity_resource(_resource); + struct pipe_context *pipe = id_context->pipe; + struct pipe_resource *resource = id_resource->resource; + struct pipe_sampler_view *result; - view->base = *templ; - view->base.reference.count = 1; - view->base.texture = NULL; - pipe_resource_reference(&view->base.texture, texture); - view->base.context = pipe; + result = pipe->create_sampler_view(pipe, + resource, + templ); - return &view->base; + if (result) + return identity_sampler_view_create(id_context, id_resource, result); + return NULL; } static void -identity_sampler_view_destroy(struct pipe_context *pipe, - struct pipe_sampler_view *view) +identity_context_sampler_view_destroy(struct pipe_context *_pipe, + struct pipe_sampler_view *_view) { - struct identity_context *id_pipe = identity_context(pipe); - struct identity_sampler_view *id_view = identity_sampler_view(view); - struct pipe_context *pipe_unwrapped = id_pipe->pipe; - struct pipe_sampler_view *view_unwrapped = id_view->sampler_view; - - pipe_unwrapped->sampler_view_destroy(pipe_unwrapped, - view_unwrapped); - - pipe_resource_reference(&view->texture, NULL); - FREE(view); + identity_sampler_view_destroy(identity_context(_pipe), + identity_sampler_view(_view)); } static struct pipe_transfer * identity_context_get_transfer(struct pipe_context *_context, - struct pipe_resource *_resource, - struct pipe_subresource sr, - unsigned usage, - const struct pipe_box *box) + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { struct identity_context *id_context = identity_context(_context); struct identity_resource *id_resource = identity_resource(_resource); struct pipe_context *context = id_context->pipe; - struct pipe_resource *texture = id_resource->resource; + struct pipe_resource *resource = id_resource->resource; struct pipe_transfer *result; result = context->get_transfer(context, - texture, - sr, - usage, - box); + resource, + sr, + usage, + box); if (result) return identity_transfer_create(id_context, id_resource, result); @@ -765,7 +753,7 @@ identity_context_get_transfer(struct pipe_context *_context, static void identity_context_transfer_destroy(struct pipe_context *_pipe, - struct pipe_transfer *_transfer) + struct pipe_transfer *_transfer) { identity_transfer_destroy(identity_context(_pipe), identity_transfer(_transfer)); @@ -773,7 +761,7 @@ identity_context_transfer_destroy(struct pipe_context *_pipe, static void * identity_context_transfer_map(struct pipe_context *_context, - struct pipe_transfer *_transfer) + struct pipe_transfer *_transfer) { struct identity_context *id_context = identity_context(_context); struct identity_transfer *id_transfer = identity_transfer(_transfer); @@ -781,15 +769,15 @@ identity_context_transfer_map(struct pipe_context *_context, struct pipe_transfer *transfer = id_transfer->transfer; return context->transfer_map(context, - transfer); + transfer); } static void -identity_context_transfer_flush_region( struct pipe_context *_context, - struct pipe_transfer *_transfer, - const struct pipe_box *box) +identity_context_transfer_flush_region(struct pipe_context *_context, + struct pipe_transfer *_transfer, + const struct pipe_box *box) { struct identity_context *id_context = identity_context(_context); struct identity_transfer *id_transfer = identity_transfer(_transfer); @@ -797,14 +785,14 @@ identity_context_transfer_flush_region( struct pipe_context *_context, struct pipe_transfer *transfer = id_transfer->transfer; context->transfer_flush_region(context, - transfer, - box); + transfer, + box); } static void identity_context_transfer_unmap(struct pipe_context *_context, - struct pipe_transfer *_transfer) + struct pipe_transfer *_transfer) { struct identity_context *id_context = identity_context(_context); struct identity_transfer *id_transfer = identity_transfer(_transfer); @@ -812,33 +800,33 @@ identity_context_transfer_unmap(struct pipe_context *_context, struct pipe_transfer *transfer = id_transfer->transfer; context->transfer_unmap(context, - transfer); + transfer); } static void -identity_context_transfer_inline_write( struct pipe_context *_context, - struct pipe_resource *_resource, - struct pipe_subresource sr, - unsigned usage, - const struct pipe_box *box, - const void *data, - unsigned stride, - unsigned slice_stride) +identity_context_transfer_inline_write(struct pipe_context *_context, + struct pipe_resource *_resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned slice_stride) { struct identity_context *id_context = identity_context(_context); struct identity_resource *id_resource = identity_resource(_resource); struct pipe_context *context = id_context->pipe; - struct pipe_resource *texture = id_resource->resource; + struct pipe_resource *resource = id_resource->resource; context->transfer_inline_write(context, - texture, - sr, - usage, - box, - data, - stride, - slice_stride); + resource, + sr, + usage, + box, + data, + stride, + slice_stride); } @@ -905,8 +893,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.clear = identity_clear; id_pipe->base.flush = identity_flush; id_pipe->base.is_resource_referenced = identity_is_resource_referenced; - id_pipe->base.create_sampler_view = identity_create_sampler_view; - id_pipe->base.sampler_view_destroy = identity_sampler_view_destroy; + id_pipe->base.create_sampler_view = identity_context_create_sampler_view; + id_pipe->base.sampler_view_destroy = identity_context_sampler_view_destroy; id_pipe->base.get_transfer = identity_context_get_transfer; id_pipe->base.transfer_destroy = identity_context_transfer_destroy; id_pipe->base.transfer_map = identity_context_transfer_map; diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c index d50914e7d5d..ca4743f9ef7 100644 --- a/src/gallium/drivers/identity/id_objects.c +++ b/src/gallium/drivers/identity/id_objects.c @@ -108,9 +108,45 @@ identity_surface_destroy(struct identity_surface *id_surface) } +struct pipe_sampler_view * +identity_sampler_view_create(struct identity_context *id_context, + struct identity_resource *id_resource, + struct pipe_sampler_view *view) +{ + struct identity_sampler_view *id_view; + + if (!view) + goto error; + + assert(view->texture == id_resource->resource); + + id_view = MALLOC(sizeof(struct identity_sampler_view)); + + id_view->base = *view; + id_view->base.reference.count = 1; + id_view->base.texture = NULL; + pipe_resource_reference(&id_view->base.texture, id_resource->resource); + id_view->base.context = id_context->pipe; + + return &id_view->base; +error: + return NULL; +} + +void +identity_sampler_view_destroy(struct identity_context *id_context, + struct identity_sampler_view *id_view) +{ + pipe_resource_reference(&id_view->base.texture, NULL); + id_context->pipe->sampler_view_destroy(id_context->pipe, + id_view->sampler_view); + FREE(id_view); +} + + struct pipe_transfer * identity_transfer_create(struct identity_context *id_context, - struct identity_resource *id_resource, + struct identity_resource *id_resource, struct pipe_transfer *transfer) { struct identity_transfer *id_transfer; @@ -144,8 +180,8 @@ identity_transfer_destroy(struct identity_context *id_context, struct identity_transfer *id_transfer) { pipe_resource_reference(&id_transfer->base.resource, NULL); - id_context->pipe->transfer_destroy(id_context->pipe, - id_transfer->transfer); + id_transfer->pipe->transfer_destroy(id_context->pipe, + id_transfer->transfer); FREE(id_transfer); } diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h index 058cf3009df..5eea10b0b5a 100644 --- a/src/gallium/drivers/identity/id_objects.h +++ b/src/gallium/drivers/identity/id_objects.h @@ -142,7 +142,7 @@ identity_transfer_unwrap(struct pipe_transfer *_transfer) struct pipe_resource * identity_resource_create(struct identity_screen *id_screen, - struct pipe_resource *resource); + struct pipe_resource *resource); void identity_resource_destroy(struct identity_resource *id_resource); @@ -154,9 +154,18 @@ identity_surface_create(struct identity_resource *id_resource, void identity_surface_destroy(struct identity_surface *id_surface); +struct pipe_sampler_view * +identity_sampler_view_create(struct identity_context *id_context, + struct identity_resource *id_resource, + struct pipe_sampler_view *view); + +void +identity_sampler_view_destroy(struct identity_context *id_context, + struct identity_sampler_view *id_sampler_view); + struct pipe_transfer * identity_transfer_create(struct identity_context *id_context, - struct identity_resource *id_resource, + struct identity_resource *id_resource, struct pipe_transfer *transfer); void diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 52573b211fb..7671bded981 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -120,14 +120,14 @@ identity_screen_context_create(struct pipe_screen *_screen, static struct pipe_resource * identity_screen_resource_create(struct pipe_screen *_screen, - const struct pipe_resource *templat) + const struct pipe_resource *templat) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; struct pipe_resource *result; result = screen->resource_create(screen, - templat); + templat); if (result) return identity_resource_create(id_screen, result); @@ -136,8 +136,8 @@ identity_screen_resource_create(struct pipe_screen *_screen, static struct pipe_resource * identity_screen_resource_from_handle(struct pipe_screen *_screen, - const struct pipe_resource *templ, - struct winsys_handle *handle) + const struct pipe_resource *templ, + struct winsys_handle *handle) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; @@ -154,44 +154,44 @@ identity_screen_resource_from_handle(struct pipe_screen *_screen, static boolean identity_screen_resource_get_handle(struct pipe_screen *_screen, - struct pipe_resource *_texture, - struct winsys_handle *handle) + struct pipe_resource *_resource, + struct winsys_handle *handle) { struct identity_screen *id_screen = identity_screen(_screen); - struct identity_resource *id_resource = identity_resource(_texture); + struct identity_resource *id_resource = identity_resource(_resource); struct pipe_screen *screen = id_screen->screen; - struct pipe_resource *texture = id_resource->resource; + struct pipe_resource *resource = id_resource->resource; /* TODO trace call */ - return screen->resource_get_handle(screen, texture, handle); + return screen->resource_get_handle(screen, resource, handle); } static void identity_screen_resource_destroy(struct pipe_screen *screen, - struct pipe_resource *_texture) + struct pipe_resource *_resource) { - identity_resource_destroy(identity_resource(_texture)); + identity_resource_destroy(identity_resource(_resource)); } static struct pipe_surface * identity_screen_get_tex_surface(struct pipe_screen *_screen, - struct pipe_resource *_texture, + struct pipe_resource *_resource, unsigned face, unsigned level, unsigned zslice, unsigned usage) { struct identity_screen *id_screen = identity_screen(_screen); - struct identity_resource *id_resource = identity_resource(_texture); + struct identity_resource *id_resource = identity_resource(_resource); struct pipe_screen *screen = id_screen->screen; - struct pipe_resource *texture = id_resource->resource; + struct pipe_resource *resource = id_resource->resource; struct pipe_surface *result; result = screen->get_tex_surface(screen, - texture, + resource, face, level, zslice, @@ -214,7 +214,7 @@ static struct pipe_resource * identity_screen_user_buffer_create(struct pipe_screen *_screen, void *ptr, unsigned bytes, - unsigned usage) + unsigned usage) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; @@ -223,7 +223,7 @@ identity_screen_user_buffer_create(struct pipe_screen *_screen, result = screen->user_buffer_create(screen, ptr, bytes, - usage); + usage); if (result) return identity_resource_create(id_screen, result); diff --git a/src/gallium/drivers/llvmpipe/.gitignore b/src/gallium/drivers/llvmpipe/.gitignore index 257b72d7b2b..a1b6f56e0d2 100644 --- a/src/gallium/drivers/llvmpipe/.gitignore +++ b/src/gallium/drivers/llvmpipe/.gitignore @@ -1 +1,5 @@ lp_tile_soa.c +lp_test_blend +lp_test_conv +lp_test_format +lp_test_printf diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 466a2f54fbe..30e206a2b42 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -185,6 +185,8 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, * but there are more on SVN. */ /* TODO: Add more passes */ + LLVMAddCFGSimplificationPass(screen->pass); + LLVMAddPromoteMemoryToRegisterPass(screen->pass); LLVMAddConstantPropagationPass(screen->pass); if(util_cpu_caps.has_sse4_1) { /* FIXME: There is a bug in this pass, whereby the combination of fptosi @@ -193,9 +195,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) */ LLVMAddInstructionCombiningPass(screen->pass); } - LLVMAddPromoteMemoryToRegisterPass(screen->pass); LLVMAddGVNPass(screen->pass); - LLVMAddCFGSimplificationPass(screen->pass); } lp_jit_init_globals(screen); diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 1482a777ff8..887f2dbad91 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -25,6 +25,7 @@ * **************************************************************************/ +#include "util/u_framebuffer.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_inlines.h" diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 21509560084..1a2cd55b164 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -33,6 +33,7 @@ */ #include "pipe/p_defines.h" +#include "util/u_framebuffer.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_pack_color.h" diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 965777b6411..5f861d6ca4d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -618,7 +618,6 @@ generate_fragment(struct llvmpipe_context *lp, struct lp_type fs_type; struct lp_type blend_type; LLVMTypeRef fs_elem_type; - LLVMTypeRef fs_vec_type; LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; LLVMTypeRef arg_types[15]; @@ -675,7 +674,6 @@ generate_fragment(struct llvmpipe_context *lp, */ fs_elem_type = lp_build_elem_type(fs_type); - fs_vec_type = lp_build_vec_type(fs_type); fs_int_vec_type = lp_build_int_vec_type(fs_type); blend_vec_type = lp_build_vec_type(blend_type); @@ -1064,6 +1062,34 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, /** + * Return the blend factor equivalent to a destination alpha of one. + */ +static INLINE unsigned +force_dst_alpha_one(unsigned factor, boolean alpha) +{ + switch(factor) { + case PIPE_BLENDFACTOR_DST_ALPHA: + return PIPE_BLENDFACTOR_ONE; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return PIPE_BLENDFACTOR_ZERO; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return PIPE_BLENDFACTOR_ZERO; + } + + if (alpha) { + switch(factor) { + case PIPE_BLENDFACTOR_DST_COLOR: + return PIPE_BLENDFACTOR_ONE; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return PIPE_BLENDFACTOR_ZERO; + } + } + + return factor; +} + + +/** * We need to generate several variants of the fragment pipeline to match * all the combinations of the contributing state atoms. * @@ -1104,6 +1130,7 @@ make_variant_key(struct llvmpipe_context *lp, key->nr_cbufs = lp->framebuffer.nr_cbufs; for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { + struct pipe_rt_blend_state *blend_rt = &key->blend.rt[i]; const struct util_format_description *format_desc; unsigned chan; @@ -1111,7 +1138,7 @@ make_variant_key(struct llvmpipe_context *lp, assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB || format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB); - key->blend.rt[i].colormask = lp->blend->rt[i].colormask; + blend_rt->colormask = lp->blend->rt[i].colormask; /* mask out color channels not present in the color buffer. * Should be simple to incorporate per-cbuf writemasks: @@ -1120,7 +1147,27 @@ make_variant_key(struct llvmpipe_context *lp, enum util_format_swizzle swizzle = format_desc->swizzle[chan]; if(swizzle > UTIL_FORMAT_SWIZZLE_W) - key->blend.rt[i].colormask &= ~(1 << chan); + blend_rt->colormask &= ~(1 << chan); + } + + /* + * Our swizzled render tiles always have an alpha channel, but the linear + * render target format often does not, so force here the dst alpha to be + * one. + * + * This is not a mere optimization. Wrong results will be produced if the + * dst alpha is used, the dst format does not have alpha, and the previous + * rendering was not flushed from the swizzled to linear buffer. For + * example, NonPowTwo DCT. + * + * TODO: This should be generalized to all channels for better + * performance, but only alpha causes correctness issues. + */ + if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W) { + blend_rt->rgb_src_factor = force_dst_alpha_one(blend_rt->rgb_src_factor, FALSE); + blend_rt->rgb_dst_factor = force_dst_alpha_one(blend_rt->rgb_dst_factor, FALSE); + blend_rt->alpha_src_factor = force_dst_alpha_one(blend_rt->alpha_src_factor, TRUE); + blend_rt->alpha_dst_factor = force_dst_alpha_one(blend_rt->alpha_dst_factor, TRUE); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c index 63b8f27b39c..4b135aaf8ba 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -30,6 +30,7 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_framebuffer.h" #include "util/u_surface.h" #include "lp_context.h" #include "lp_scene.h" diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 8bd83f576f4..245171120dd 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "util/u_rect.h" +#include "util/u_surface.h" #include "lp_context.h" #include "lp_flush.h" #include "lp_limits.h" diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 74b7393e4ec..d3a9d39f616 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -170,7 +170,10 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, unsigned unit, unsigned num_coords, const LLVMValueRef *coords, - LLVMValueRef lodbias, + const LLVMValueRef *ddx, + const LLVMValueRef *ddy, + LLVMValueRef lod_bias, /* optional */ + LLVMValueRef explicit_lod, /* optional */ LLVMValueRef *texel) { struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base; @@ -182,9 +185,9 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base, &sampler->dynamic_state.base, type, unit, - num_coords, - coords, - lodbias, + num_coords, coords, + ddx, ddy, + lod_bias, explicit_lod, texel); } diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index b8b6b12120b..0156ff95ff9 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -3169,15 +3169,16 @@ nv50_program_tx_insn(struct nv50_pc *pc, if (pc->p->type == PIPE_SHADER_FRAGMENT) nv50_fp_move_results(pc); - /* last insn must be long so it can have the exit bit set */ - if (!is_long(pc->p->exec_tail)) - convert_to_long(pc, pc->p->exec_tail); - else - if (is_immd(pc->p->exec_tail) || + if (!pc->p->exec_tail || + is_immd(pc->p->exec_tail) || is_join(pc->p->exec_tail) || is_control_flow(pc->p->exec_tail)) emit_nop(pc); + /* last insn must be long so it can have the exit bit set */ + if (!is_long(pc->p->exec_tail)) + convert_to_long(pc, pc->p->exec_tail); + pc->p->exec_tail->inst[1] |= 1; /* set exit bit */ terminate_mbb(pc); @@ -4162,7 +4163,7 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) struct pipe_transfer *transfer; if (!p->data[0] && p->immd_nr) { - struct nouveau_resource *heap = nv50->screen->immd_heap[0]; + struct nouveau_resource *heap = nv50->screen->immd_heap; if (nouveau_resource_alloc(heap, p->immd_nr, p, &p->data[0])) { while (heap->next && heap->size < p->immd_nr) { @@ -4180,7 +4181,7 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) p->immd_nr, NV50_CB_PMISC); } - assert(p->param_nr <= 512); + assert(p->param_nr <= 16384); if (p->param_nr) { unsigned cb; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ad17991be9a..2dd10424245 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -190,9 +190,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen) nouveau_grobj_free(&screen->tesla); nouveau_grobj_free(&screen->eng2d); nouveau_grobj_free(&screen->m2mf); - nouveau_resource_destroy(&screen->immd_heap[0]); - nouveau_resource_destroy(&screen->parm_heap[0]); - nouveau_resource_destroy(&screen->parm_heap[1]); + nouveau_resource_destroy(&screen->immd_heap); nouveau_screen_fini(&screen->base); FREE(screen); } @@ -242,7 +240,7 @@ nv50_screen_relocs(struct nv50_screen *screen) OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl); OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl); OUT_RELOC (chan, screen->constbuf_parm[i], - ((NV50_CB_PVP + i) << 16) | 0x0800, rl, 0, 0); + ((NV50_CB_PVP + i) << 16) | 0x0000, rl, 0, 0); } } @@ -411,7 +409,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200); for (i = 0; i < 3; i++) { - ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4, + ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (4096 * 4) * 4, &screen->constbuf_parm[i]); if (ret) { nv50_screen_destroy(pscreen); @@ -420,14 +418,12 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl); OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl); - OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0800); + /* CB_DEF_SET_SIZE value of 0x0000 means 65536 */ + OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0000); } - if (nouveau_resource_init(&screen->immd_heap[0], 0, 128) || - nouveau_resource_init(&screen->parm_heap[0], 0, 512) || - nouveau_resource_init(&screen->parm_heap[1], 0, 512)) - { - NOUVEAU_ERR("Error initialising constant buffers.\n"); + if (nouveau_resource_init(&screen->immd_heap, 0, 128)) { + NOUVEAU_ERR("Error initialising shader immediates heap.\n"); nv50_screen_destroy(pscreen); return NULL; } diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h index 40ebbee72e2..fbf15a75967 100644 --- a/src/gallium/drivers/nv50/nv50_screen.h +++ b/src/gallium/drivers/nv50/nv50_screen.h @@ -20,8 +20,7 @@ struct nv50_screen { struct nouveau_bo *constbuf_misc[1]; struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES]; - struct nouveau_resource *immd_heap[1]; - struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES]; + struct nouveau_resource *immd_heap; struct pipe_resource *strm_vbuf[16]; diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index c2d9e835260..d905d95354f 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -31,6 +31,27 @@ #include "util/u_tile.h" #include "util/u_format.h" +/* return TRUE for formats that can be converted among each other by NV50_2D */ +static INLINE boolean +nv50_2d_format_faithful(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8X8_SRGB: + case PIPE_FORMAT_B5G6R5_UNORM: + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + case PIPE_FORMAT_R32G32B32_FLOAT: + return TRUE; + default: + return FALSE; + } +} + static INLINE int nv50_format(enum pipe_format format) { @@ -47,9 +68,12 @@ nv50_format(enum pipe_format format) return NV50_2D_DST_FORMAT_R5G6B5_UNORM; case PIPE_FORMAT_B5G5R5A1_UNORM: return NV50_2D_DST_FORMAT_A1R5G5B5_UNORM; + case PIPE_FORMAT_B10G10R10A2_UNORM: + return NV50_2D_DST_FORMAT_A2R10G10B10_UNORM; case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_R8_UNORM: return NV50_2D_DST_FORMAT_R8_UNORM; case PIPE_FORMAT_R32G32B32A32_FLOAT: return NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT; @@ -178,7 +202,9 @@ nv50_surface_copy(struct pipe_context *pipe, struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; - assert(src->format == dest->format); + assert((src->format == dest->format) || + (nv50_2d_format_faithful(src->format) && + nv50_2d_format_faithful(dest->format))); nv50_surface_do_copy(screen, dest, destx, desty, src, srcx, srcy, width, height); diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 928ad300eee..85c2c149016 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -129,15 +129,16 @@ void r300_surface_copy(struct pipe_context* pipe, if (dst->texture->format != src->texture->format) { debug_printf("r300: Implementation error: Format mismatch in %s\n" " : src: %s dst: %s\n", __FUNCTION__, - util_format_name(src->texture->format), - util_format_name(dst->texture->format)); + util_format_short_name(src->texture->format), + util_format_short_name(dst->texture->format)); debug_assert(0); } if (!pipe->screen->is_format_supported(pipe->screen, old_format, src->texture->target, PIPE_BIND_RENDER_TARGET | - PIPE_BIND_SAMPLER_VIEW, 0)) { + PIPE_BIND_SAMPLER_VIEW, 0) && + util_format_is_plain(old_format)) { switch (util_format_get_blocksize(old_format)) { case 1: new_format = PIPE_FORMAT_I8_UNORM; @@ -154,7 +155,7 @@ void r300_surface_copy(struct pipe_context* pipe, default: debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n" "r300: surface_copy: Software fallback doesn't work for tiled textures.\n", - util_format_name(old_format)); + util_format_short_name(old_format)); } } diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 4f721ebb599..e84bce0010f 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -76,7 +76,6 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); FREE(r300->textures_state.state); - FREE(r300->vap_output_state.state); FREE(r300->viewport_state.state); FREE(r300->ztop_state.state); FREE(r300->fs_constants.state); @@ -125,7 +124,6 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(viewport_state, 9); R300_INIT_ATOM(rs_block_state, 0); R300_INIT_ATOM(vertex_stream_state, 0); - R300_INIT_ATOM(vap_output_state, 6); R300_INIT_ATOM(pvs_flush, 2); R300_INIT_ATOM(vs_state, 0); R300_INIT_ATOM(vs_constants, 0); @@ -149,7 +147,6 @@ static void r300_setup_atoms(struct r300_context* r300) r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); r300->textures_state.state = CALLOC_STRUCT(r300_textures_state); - r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state); r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state); r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state); r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index a05bf3ce099..e9c8fcdc157 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -119,6 +119,10 @@ struct r300_rs_state { }; struct r300_rs_block { + uint32_t vap_vtx_state_cntl; /* R300_VAP_VTX_STATE_CNTL: 0x2180 */ + uint32_t vap_vsm_vtx_assm; /* R300_VAP_VSM_VTX_ASSM: 0x2184 */ + uint32_t vap_out_vtx_fmt[2]; /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */ + uint32_t ip[8]; /* R300_RS_IP_[0-7], R500_RS_IP_[0-7] */ uint32_t count; /* R300_RS_COUNT */ uint32_t inst_count; /* R300_RS_INST_COUNT */ @@ -190,12 +194,6 @@ struct r300_vertex_stream_state { unsigned count; }; -struct r300_vap_output_state { - uint32_t vap_vtx_state_cntl; /* R300_VAP_VTX_STATE_CNTL: 0x2180 */ - uint32_t vap_vsm_vtx_assm; /* R300_VAP_VSM_VTX_ASSM: 0x2184 */ - uint32_t vap_out_vtx_fmt[2]; /* R300_VAP_OUTPUT_VTX_FMT_[0-1]: 0x2090 */ -}; - struct r300_viewport_state { float xscale; /* R300_VAP_VPORT_XSCALE: 0x2098 */ float xoffset; /* R300_VAP_VPORT_XOFFSET: 0x209c */ @@ -381,7 +379,7 @@ struct r300_context { struct r300_atom query_start; /* Rasterizer state. */ struct r300_atom rs_state; - /* RS block state. */ + /* RS block state + VAP (vertex shader) output mapping state. */ struct r300_atom rs_block_state; /* Scissor state. */ struct r300_atom scissor_state; @@ -389,8 +387,6 @@ struct r300_context { struct r300_atom textures_state; /* Vertex stream formatting state. */ struct r300_atom vertex_stream_state; - /* VAP (vertex shader) output mapping state. */ - struct r300_atom vap_output_state; /* Vertex shader. */ struct r300_atom vs_state; /* Vertex shader constant buffer. */ @@ -424,6 +420,9 @@ struct r300_context { struct pipe_viewport_state viewport; + /* Stream locations for SWTCL. */ + int stream_loc_notcl[16]; + /* Flag indicating whether or not the HW is dirty. */ uint32_t dirty_hw; /* Whether polygon offset is enabled. */ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 4c2836f36a8..8eb321fa08a 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -37,6 +37,7 @@ static struct debug_option debug_options[] = { { "cs", DBG_CS, "Command submissions (for debugging)" }, { "draw", DBG_DRAW, "Draw and emit (for debugging)" }, { "tex", DBG_TEX, "Textures (for debugging)" }, + { "texalloc", DBG_TEXALLOC, "Texture allocation (for debugging)" }, { "fall", DBG_FALL, "Fallbacks (for debugging)" }, { "rs", DBG_RS, "Rasterizer (for debugging)" }, { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" }, diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 92b7517b8d6..23bbc6a99c8 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -717,6 +717,13 @@ void r300_emit_rs_block_state(struct r300_context* r300, DBG(r300, DBG_DRAW, "r300: RS emit:\n"); BEGIN_CS(size); + OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); + OUT_CS(rs->vap_vtx_state_cntl); + OUT_CS(rs->vap_vsm_vtx_assm); + OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); + OUT_CS(rs->vap_out_vtx_fmt[0]); + OUT_CS(rs->vap_out_vtx_fmt[1]); + if (r300->screen->caps.is_r500) { OUT_CS_REG_SEQ(R500_RS_IP_0, count); } else { @@ -901,25 +908,6 @@ void r300_emit_vertex_stream_state(struct r300_context* r300, END_CS; } -void r300_emit_vap_output_state(struct r300_context* r300, - unsigned size, void* state) -{ - struct r300_vap_output_state *vap_out_state = - (struct r300_vap_output_state*)state; - CS_LOCALS(r300); - - DBG(r300, DBG_DRAW, "r300: VAP emit:\n"); - - BEGIN_CS(size); - OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2); - OUT_CS(vap_out_state->vap_vtx_state_cntl); - OUT_CS(vap_out_state->vap_vsm_vtx_assm); - OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2); - OUT_CS(vap_out_state->vap_out_vtx_fmt[0]); - OUT_CS(vap_out_state->vap_out_vtx_fmt[1]); - END_CS; -} - void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state) { CS_LOCALS(r300); diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index c3eb195d4e7..3c0edf6fdca 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -81,9 +81,6 @@ void r300_emit_vertex_buffer(struct r300_context* r300); void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state); -void r300_emit_vap_output_state(struct r300_context* r300, - unsigned size, void* state); - void r300_emit_vs_constants(struct r300_context* r300, unsigned size, void *state); diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index 735c233c9e2..d58aa138a70 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -73,6 +73,7 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) { #define DBG_NO_IMMD 0x0000200 #define DBG_STATS 0x0000400 #define DBG_RS 0x0000800 +#define DBG_TEXALLOC 0x0001000 /*@}*/ static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 9319dadfd1e..446422ca0f0 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -538,46 +538,12 @@ static void r300_set_stencil_ref(struct pipe_context* pipe, } /* This switcheroo is needed just because of goddamned MACRO_SWITCH. */ -static void r300_fb_update_tiling_flags(struct r300_context *r300, +static void r300_fb_set_tiling_flags(struct r300_context *r300, const struct pipe_framebuffer_state *old_state, const struct pipe_framebuffer_state *new_state) { struct r300_texture *tex; - unsigned i, j, level; - - /* Reset tiling flags for old surfaces to default values. */ - for (i = 0; i < old_state->nr_cbufs; i++) { - for (j = 0; j < new_state->nr_cbufs; j++) { - if (old_state->cbufs[i]->texture == new_state->cbufs[j]->texture) { - break; - } - } - /* If not binding the surface again... */ - if (j != new_state->nr_cbufs) { - continue; - } - - tex = r300_texture(old_state->cbufs[i]->texture); - - if (tex) { - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, - tex->pitch[0], - tex->microtile, - tex->macrotile); - } - } - if (old_state->zsbuf && - (!new_state->zsbuf || - old_state->zsbuf->texture != new_state->zsbuf->texture)) { - tex = r300_texture(old_state->zsbuf->texture); - - if (tex) { - r300->rws->buffer_set_tiling(r300->rws, tex->buffer, - tex->pitch[0], - tex->microtile, - tex->macrotile); - } - } + unsigned i, level; /* Set tiling flags for new surfaces. */ for (i = 0; i < new_state->nr_cbufs; i++) { @@ -585,7 +551,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, level = new_state->cbufs[i]->level; r300->rws->buffer_set_tiling(r300->rws, tex->buffer, - tex->pitch[level], + tex->pitch[0], tex->microtile, tex->mip_macrotile[level]); } @@ -594,7 +560,7 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300, level = new_state->zsbuf->level; r300->rws->buffer_set_tiling(r300->rws, tex->buffer, - tex->pitch[level], + tex->pitch[0], tex->microtile, tex->mip_macrotile[level]); } @@ -644,7 +610,8 @@ static void r300->dsa_state.dirty = TRUE; } - r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); + /* The tiling flags are dependent on the surface miplevel, unfortunately. */ + r300_fb_set_tiling_flags(r300, r300->fb_state.state, state); memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); @@ -719,10 +686,6 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) r300_mark_fs_code_dirty(r300); r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ - - if (r300->vs_state.state && r300_vertex_shader_setup_wpos(r300)) { - r300->vap_output_state.dirty = TRUE; - } } /* Delete fragment shader state. */ @@ -853,11 +816,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF; - /* XXX Disable point sprites until we know what's wrong with them. */ - rs->rs.sprite_coord_enable = 0; - /* Point sprites */ - if (rs->rs.sprite_coord_enable) { + if (state->sprite_coord_enable) { rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE; for (i = 0; i < 8; i++) { if (state->sprite_coord_enable & (1 << i)) @@ -1357,7 +1317,7 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, /* XXX Shouldn't we align the format? */ fprintf(stderr, "r300_create_vertex_elements_state: " "Unaligned format %s:%i isn't supported\n", - util_format_name(*format), size); + util_format_short_name(*format), size); assert(0); abort(); } @@ -1428,14 +1388,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) } r300->vs_state.state = vs; - // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block - if (r300->fs.state) { - r300_vertex_shader_setup_wpos(r300); - } - memcpy(r300->vap_output_state.state, &vs->vap_out, - sizeof(struct r300_vap_output_state)); - r300->vap_output_state.dirty = TRUE; - /* The majority of the RS block bits is dependent on the vertex shader. */ r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index ccc4b583a6a..e3adace0faa 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -115,12 +115,11 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300) static void r300_swtcl_vertex_psc(struct r300_context *r300) { struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state; - struct r300_vertex_shader* vs = r300->vs_state.state; - struct vertex_info* vinfo = &r300->vertex_info; + struct vertex_info* vinfo = &r300->vertex_info; uint16_t type, swizzle; enum pipe_format format; unsigned i, attrib_count; - int* vs_output_tab = vs->stream_loc_notcl; + int* vs_output_tab = r300->stream_loc_notcl; /* XXX hax */ memset(vstream, 0, sizeof(struct r300_vertex_stream_state)); @@ -269,21 +268,29 @@ static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) /* Set up the RS block. * - * This is the part of the chipset that actually does the rasterization - * of vertices into fragments. This is also the part of the chipset that - * locks up if any part of it is even slightly wrong. */ -static void r300_update_rs_block(struct r300_context* r300, - struct r300_shader_semantics* vs_outputs, - struct r300_shader_semantics* fs_inputs) + * This is the part of the chipset that is responsible for linking vertex + * and fragment shaders and stuffed texture coordinates. + * + * The rasterizer reads data from VAP, which produces vertex shader outputs, + * and GA, which produces stuffed texture coordinates. VAP outputs have + * precedence over GA. All outputs must be rasterized otherwise it locks up. + * If there are more outputs rasterized than is set in VAP/GA, it locks up + * too. The funky part is that this info has been pretty much obtained by trial + * and error. */ +static void r300_update_rs_block(struct r300_context *r300) { - struct r300_rs_block rs = { { 0 } }; - int i, col_count = 0, tex_count = 0, fp_offset = 0, count; + struct r300_vertex_shader *vs = r300->vs_state.state; + struct r300_shader_semantics *vs_outputs = &vs->outputs; + struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs; + struct r300_rs_block rs = {0}; + int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0; void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int); boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || vs_outputs->bcolor[1] != ATTR_UNUSED; + int *stream_loc_notcl = r300->stream_loc_notcl; if (r300->screen->caps.is_r500) { rX00_rs_col = r500_rs_col; @@ -297,15 +304,31 @@ static void r300_update_rs_block(struct r300_context* r300, rX00_rs_tex_write = r300_rs_tex_write; } - /* Rasterize colors. */ + /* The position is always present in VAP. */ + rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS; + rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; + stream_loc_notcl[loc++] = 0; + + /* Set up the point size in VAP. */ + if (vs_outputs->psize != ATTR_UNUSED) { + rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; + stream_loc_notcl[loc++] = 1; + } + + /* Set up and rasterize colors. */ for (i = 0; i < ATTR_COLOR_COUNT; i++) { if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || vs_outputs->color[1] != ATTR_UNUSED) { - /* Always rasterize if it's written by the VS, - * otherwise it locks up. */ + /* Set up the color in VAP. */ + rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; + rs.vap_out_vtx_fmt[0] |= + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; + stream_loc_notcl[loc++] = 2 + i; + + /* Rasterize it. */ rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW); - /* Write it to the FS input register if it's used by the FS. */ + /* Write it to the FS input register if it's needed by the FS. */ if (fs_inputs->color[i] != ATTR_UNUSED) { rX00_rs_col_write(&rs, col_count, fp_offset); fp_offset++; @@ -328,17 +351,33 @@ static void r300_update_rs_block(struct r300_context* r300, } } + /* Set up back-face colors. The rasterizer will do the color selection + * automatically. */ + if (any_bcolor_used) { + for (i = 0; i < ATTR_COLOR_COUNT; i++) { + rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; + rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); + stream_loc_notcl[loc++] = 4 + i; + } + } + /* Rasterize texture coordinates. */ - for (i = 0; i < ATTR_GENERIC_COUNT; i++) { + for (i = 0; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) { bool sprite_coord = !!(r300->sprite_coord_enable & (1 << i)); if (vs_outputs->generic[i] != ATTR_UNUSED || sprite_coord) { - /* Always rasterize if it's written by the VS, - * otherwise it locks up. */ + if (!sprite_coord) { + /* Set up the texture coordinates in VAP. */ + rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); + rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); + stream_loc_notcl[loc++] = 6 + tex_count; + } + + /* Rasterize it. */ rX00_rs_tex(&rs, tex_count, tex_count, sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); - /* Write it to the FS input register if it's used by the FS. */ + /* Write it to the FS input register if it's needed by the FS. */ if (fs_inputs->generic[i] != ATTR_UNUSED) { rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; @@ -365,12 +404,16 @@ static void r300_update_rs_block(struct r300_context* r300, } /* Rasterize fog coordinates. */ - if (vs_outputs->fog != ATTR_UNUSED) { - /* Always rasterize if it's written by the VS, - * otherwise it locks up. */ + if (vs_outputs->fog != ATTR_UNUSED && tex_count < 8) { + /* Set up the fog coordinates in VAP. */ + rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); + rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); + stream_loc_notcl[loc++] = 6 + tex_count; + + /* Rasterize it. */ rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_X001); - /* Write it to the FS input register if it's used by the FS. */ + /* Write it to the FS input register if it's needed by the FS. */ if (fs_inputs->fog != ATTR_UNUSED) { rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; @@ -391,9 +434,17 @@ 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 (vs_outputs->wpos != ATTR_UNUSED && fs_inputs->wpos != ATTR_UNUSED) { + /* Don't set it in VAP if the FS doesn't need it. */ + if (fs_inputs->wpos != ATTR_UNUSED && tex_count < 8) { + /* Set up the WPOS coordinates in VAP. */ + rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); + rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); + stream_loc_notcl[loc++] = 6 + tex_count; + + /* Rasterize it. */ rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); + + /* Write it to the FS input register. */ rX00_rs_tex_write(&rs, tex_count, fp_offset); DBG(r300, DBG_RS, "r300: Rasterized WPOS written to FS.\n"); @@ -402,6 +453,11 @@ static void r300_update_rs_block(struct r300_context* r300, tex_count++; } + /* Invalidate the rest of the no-TCL (GA) stream locations. */ + for (; loc < 16;) { + stream_loc_notcl[loc++] = -1; + } + /* Rasterize at least one color, or bad things happen. */ if (col_count == 0 && tex_count == 0) { rX00_rs_col(&rs, 0, 0, SWIZ_0001); @@ -422,18 +478,10 @@ static void r300_update_rs_block(struct r300_context* r300, /* 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.size = 5 + count*2; + r300->rs_block_state.size = 11 + count*2; } } -/* Update the shader-dependant states. */ -static void r300_update_derived_shader_state(struct r300_context* r300) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - - r300_update_rs_block(r300, &vs->outputs, &r300_fs(r300)->shader->inputs); -} - static void r300_merge_textures_and_samplers(struct r300_context* r300) { struct r300_textures_state *state = @@ -529,7 +577,7 @@ void r300_update_derived_state(struct r300_context* r300) } if (r300->rs_block_state.dirty) { - r300_update_derived_shader_state(r300); + r300_update_rs_block(r300); } if (r300->draw) { diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index fcbdb91b67e..715601042fa 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -371,7 +371,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { desc = util_format_description(format); if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_name(format), + fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_short_name(format), __FUNCTION__, __LINE__); assert(0); abort(); @@ -394,7 +394,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { break; default: fprintf(stderr, "r300: Bad format %s in %s:%d\n", - util_format_name(format), __FUNCTION__, __LINE__); + util_format_short_name(format), __FUNCTION__, __LINE__); assert(0); abort(); } @@ -416,7 +416,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { break; default: fprintf(stderr, "r300: Bad format %s in %s:%d\n", - util_format_name(format), __FUNCTION__, __LINE__); + util_format_short_name(format), __FUNCTION__, __LINE__); fprintf(stderr, "r300: desc->channel[0].size == %d\n", desc->channel[0].size); assert(0); @@ -425,7 +425,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { break; default: fprintf(stderr, "r300: Bad format %s in %s:%d\n", - util_format_name(format), __FUNCTION__, __LINE__); + util_format_short_name(format), __FUNCTION__, __LINE__); assert(0); abort(); } @@ -449,7 +449,7 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) { if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { fprintf(stderr, "r300: Bad format %s in %s:%d\n", - util_format_name(format), __FUNCTION__, __LINE__); + util_format_short_name(format), __FUNCTION__, __LINE__); return 0; } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 69e6a124458..d6f629cf9c6 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -46,18 +46,6 @@ static const unsigned microblock_table[5][3][2] = { {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */ }; -/* Return true for non-compressed and non-YUV formats. */ -static boolean r300_format_is_plain(enum pipe_format format) -{ - const struct util_format_description *desc = util_format_description(format); - - if (!format) { - return FALSE; - } - - return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN; -} - /* Translate a pipe_format into a useful texture format for sampling. * * Some special formats are translated directly using R300_EASY_TX_FORMAT, @@ -585,9 +573,6 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen, f->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) | R300_TXO_MICRO_TILE(tex->microtile); - - SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n", - pt->width0, pt->height0, pt->last_level); } static void r300_texture_setup_fb_state(struct r300_screen* screen, @@ -622,8 +607,8 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen, { struct r300_screen *r300screen = r300_screen(screen); - SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n", - util_format_name(tex->format), util_format_name(new_format)); + SCREEN_DBG(r300screen, DBG_TEX, "r300: texture_reinterpret_format: %s -> %s\n", + util_format_short_name(tex->format), util_format_short_name(new_format)); tex->format = new_format; @@ -714,7 +699,7 @@ unsigned r300_texture_get_stride(struct r300_screen* screen, width = u_minify(tex->b.b.width0, level); - if (r300_format_is_plain(tex->b.b.format)) { + if (util_format_is_plain(tex->b.b.format)) { tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, tex->mip_macrotile[level]); width = align(width, tile_width); @@ -732,7 +717,7 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, height = u_minify(tex->b.b.height0, level); - if (r300_format_is_plain(tex->b.b.format)) { + if (util_format_is_plain(tex->b.b.format)) { tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT, tex->mip_macrotile[level]); height = align(height, tile_height); @@ -774,8 +759,8 @@ static void r300_setup_miptree(struct r300_screen* screen, unsigned stride, size, layer_size, nblocksy, i; boolean rv350_mode = screen->caps.is_rv350; - SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n", - util_format_name(base->format)); + SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Making miptree for texture, format %s\n", + util_format_short_name(base->format)); for (i = 0; i <= base->last_level; i++) { /* Let's see if this miplevel can be macrotiled. */ @@ -801,7 +786,7 @@ static void r300_setup_miptree(struct r300_screen* screen, tex->hwpitch[i] = tex->pitch[i] * util_format_get_blockwidth(base->format); - SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d " + SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", i, u_minify(base->width0, i), u_minify(base->height0, i), u_minify(base->depth0, i), stride, tex->size, @@ -825,7 +810,7 @@ static void r300_setup_tiling(struct pipe_screen *screen, boolean is_zb = util_format_is_depth_or_stencil(format); boolean dbg_no_tiling = SCREEN_DBG_ON(r300_screen(screen), DBG_NO_TILING); - if (!r300_format_is_plain(format)) { + if (!util_format_is_plain(format)) { return; } @@ -927,6 +912,17 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, return NULL; } + /* Refuse to create a texture with size 0. */ + if (!base->width0 || + (!base->height0 && (base->target == PIPE_TEXTURE_2D || + base->target == PIPE_TEXTURE_CUBE)) || + (!base->depth0 && base->target == PIPE_TEXTURE_3D)) { + fprintf(stderr, "r300: texture_create: " + "Got invalid texture dimensions: %ix%ix%i\n", + base->width0, base->height0, base->depth0); + return NULL; + } + tex->b.b = *base; tex->b.vtbl = &r300_texture_vtbl; pipe_reference_init(&tex->b.b.reference, 1); @@ -942,6 +938,15 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, r300_texture_setup_immutable_state(rscreen, tex); r300_texture_setup_fb_state(rscreen, tex); + SCREEN_DBG(rscreen, DBG_TEX, + "r300: texture_create: Macro: %s, Micro: %s, Pitch: %i, " + "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n", + tex->macrotile ? "YES" : " NO", + tex->microtile ? "YES" : " NO", + tex->hwpitch[0], + base->width0, base->height0, base->depth0, base->last_level, + util_format_short_name(base->format)); + tex->buffer = rws->buffer_create(rws, 2048, PIPE_BIND_SAMPLER_VIEW, /* XXX */ tex->size); @@ -1039,6 +1044,14 @@ r300_texture_from_handle(struct pipe_screen* screen, rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile); r300_setup_flags(tex); + SCREEN_DBG(rscreen, DBG_TEX, + "r300: texture_from_handle: Macro: %s, Micro: %s, " + "Pitch: % 4i, Dim: %ix%i, Format: %s\n", + tex->macrotile ? "YES" : " NO", + tex->microtile ? "YES" : " NO", + stride / util_format_get_blocksize(base->format), + base->width0, base->height0, + util_format_short_name(base->format)); /* Enforce microtiled zbuffer. */ override_zb_flags = util_format_is_depth_or_stencil(base->format) && diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index bfab9c3b014..f3186431e1d 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -22,7 +22,6 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r300_vs.h" -#include "r300_fs.h" #include "r300_context.h" #include "r300_screen.h" @@ -94,94 +93,6 @@ static void r300_shader_read_vs_outputs( vs_outputs->wpos = i; } -/* This function sets up: - * - VAP mapping, which maps VS registers to output semantics and - * at the same time it indicates which attributes are enabled and should - * be rasterized. - * - Stream mapping to VS outputs if TCL is not present. */ -static void r300_init_vs_output_mapping(struct r300_vertex_shader* vs) -{ - struct r300_shader_semantics* vs_outputs = &vs->outputs; - struct r300_vap_output_state *vap_out = &vs->vap_out; - int *stream_loc = vs->stream_loc_notcl; - int i, gen_count, tabi = 0; - boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || - vs_outputs->bcolor[1] != ATTR_UNUSED; - - vap_out->vap_vtx_state_cntl = 0x5555; /* XXX this is classic Mesa bonghits */ - - /* Position. */ - if (vs_outputs->pos != ATTR_UNUSED) { - vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS; - vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; - - stream_loc[tabi++] = 0; - } else { - assert(0); - } - - /* Point size. */ - if (vs_outputs->psize != ATTR_UNUSED) { - vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; - - stream_loc[tabi++] = 1; - } - - /* Colors. */ - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || - vs_outputs->color[1] != ATTR_UNUSED) { - vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; - vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; - - stream_loc[tabi++] = 2 + i; - } - } - - /* Back-face colors. */ - if (any_bcolor_used) { - for (i = 0; i < ATTR_COLOR_COUNT; i++) { - vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; - vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); - - stream_loc[tabi++] = 4 + i; - } - } - - /* Texture coordinates. */ - gen_count = 0; - for (i = 0; i < ATTR_GENERIC_COUNT && gen_count < 8; i++) { - if (vs_outputs->generic[i] != ATTR_UNUSED) { - vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count); - vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count)); - - stream_loc[tabi++] = 6 + gen_count; - gen_count++; - } - } - - /* Fog coordinates. */ - if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) { - vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count); - vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count)); - - stream_loc[tabi++] = 6 + gen_count; - gen_count++; - } - - /* WPOS. */ - if (gen_count < 8) { - vs->wpos_tex_output = gen_count; - stream_loc[tabi++] = 6 + gen_count; - } else { - vs_outputs->wpos = ATTR_UNUSED; - } - - for (; tabi < 16;) { - stream_loc[tabi++] = -1; - } -} - static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) { struct r300_vertex_shader * vs = c->UserData; @@ -246,9 +157,7 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) } /* WPOS. */ - if (outputs->wpos != ATTR_UNUSED) { - c->code->outputs[outputs->wpos] = reg++; - } + c->code->outputs[outputs->wpos] = reg++; } static void r300_dummy_vertex_shader( @@ -286,7 +195,6 @@ void r300_translate_vertex_shader(struct r300_context* r300, tgsi_scan_shader(tokens, &vs->info); r300_shader_read_vs_outputs(&vs->info, &vs->outputs); - r300_init_vs_output_mapping(vs); /* Setup the compiler */ rc_init(&compiler.Base); @@ -307,16 +215,11 @@ void r300_translate_vertex_shader(struct r300_context* r300, r300_tgsi_to_rc(&ttr, tokens); - compiler.RequiredOutputs = - ~(~0 << (vs->info.num_outputs + - (vs->outputs.wpos != ATTR_UNUSED ? 1 : 0))); - + compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1)); compiler.SetHwInputOutput = &set_vertex_inputs_outputs; /* Insert the WPOS output. */ - if (vs->outputs.wpos != ATTR_UNUSED) { - rc_copy_output(&compiler.Base, 0, vs->outputs.wpos); - } + rc_copy_output(&compiler.Base, 0, vs->outputs.wpos); /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); @@ -343,32 +246,3 @@ void r300_translate_vertex_shader(struct r300_context* r300, /* And, finally... */ rc_destroy(&compiler.Base); } - -boolean r300_vertex_shader_setup_wpos(struct r300_context* r300) -{ - struct r300_vertex_shader* vs = r300->vs_state.state; - struct r300_vap_output_state *vap_out = &vs->vap_out; - int tex_output = vs->wpos_tex_output; - uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output; - - if (vs->outputs.wpos == ATTR_UNUSED) { - return FALSE; - } - - if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) { - /* Enable WPOS in VAP. */ - if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) { - vap_out->vap_vsm_vtx_assm |= tex_fmt; - vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * tex_output)); - return TRUE; - } - } else { - /* Disable WPOS in VAP. */ - if (vap_out->vap_vsm_vtx_assm & tex_fmt) { - vap_out->vap_vsm_vtx_assm &= ~tex_fmt; - vap_out->vap_out_vtx_fmt[1] &= ~(4 << (3 * tex_output)); - return TRUE; - } - } - return FALSE; -} diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h index 56bcc3b70b8..57b3fbca0bb 100644 --- a/src/gallium/drivers/r300/r300_vs.h +++ b/src/gallium/drivers/r300/r300_vs.h @@ -39,7 +39,6 @@ struct r300_vertex_shader { struct tgsi_shader_info info; struct r300_shader_semantics outputs; - struct r300_vap_output_state vap_out; /* Whether the shader was replaced by a dummy one due to a shader * compilation failure. */ @@ -49,12 +48,6 @@ struct r300_vertex_shader { unsigned externals_count; unsigned immediates_count; - /* Stream locations for SWTCL or if TCL is bypassed. */ - int stream_loc_notcl[16]; - - /* Output stream location for WPOS. */ - int wpos_tex_output; - /* HWTCL-specific. */ /* Machine code (if translated) */ struct r300_vertex_program_code code; @@ -67,7 +60,4 @@ void r300_translate_vertex_shader(struct r300_context* r300, struct r300_vertex_shader* vs, const struct tgsi_token *tokens); -/* Return TRUE if VAP (hwfmt) needs to be re-emitted. */ -boolean r300_vertex_shader_setup_wpos(struct r300_context* r300); - #endif /* R300_VS_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index ead489393ef..00187febf0c 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -33,6 +33,7 @@ #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_format.h" #include "sp_context.h" #include "sp_quad.h" #include "sp_tile_cache.h" @@ -224,7 +225,8 @@ static void blend_quad(struct quad_stage *qs, float (*quadColor)[4], float (*dest)[4], - unsigned cbuf) + unsigned cbuf, + boolean has_dst_alpha) { static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; @@ -259,24 +261,34 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ break; case PIPE_BLENDFACTOR_DST_ALPHA: - { - const float *alpha = dest[3]; - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; + if (has_dst_alpha) { + const float *alpha = dest[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + else { + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + } + break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4], temp[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(temp, alpha, diff); - VEC4_MUL(source[0], quadColor[0], temp); /* R */ - VEC4_MUL(source[1], quadColor[1], temp); /* G */ - VEC4_MUL(source[2], quadColor[2], temp); /* B */ - } - break; + if (has_dst_alpha) { + const float *alpha = quadColor[3]; + float diff[4], temp[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(source[0], quadColor[0], temp); /* R */ + VEC4_MUL(source[1], quadColor[1], temp); /* G */ + VEC4_MUL(source[2], quadColor[2], temp); /* B */ + } + else { + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + } + break; case PIPE_BLENDFACTOR_CONST_COLOR: { float comp[4]; @@ -329,14 +341,19 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; + if (has_dst_alpha) { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + else { + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + } + break; case PIPE_BLENDFACTOR_INV_DST_COLOR: { float inv_comp[4]; @@ -399,7 +416,10 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + if (has_dst_alpha) + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + else + VEC4_COPY(source[3], quadColor[3]); /* A */ break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: /* multiply alpha by 1.0 */ @@ -429,12 +449,15 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_INV_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ - } - break; + if (has_dst_alpha) { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + else { + VEC4_COPY(source[3], zero); /* A */ + } + break; case PIPE_BLENDFACTOR_INV_CONST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_CONST_ALPHA: @@ -468,9 +491,14 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ break; case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + if (has_dst_alpha) { + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + } + else { + /* dest = dest * 1 NO-OP, leave dest as-is */ + } break; case PIPE_BLENDFACTOR_DST_COLOR: VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ @@ -478,15 +506,20 @@ blend_quad(struct quad_stage *qs, VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4], temp[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(temp, alpha, diff); - VEC4_MUL(dest[0], quadColor[0], temp); /* R */ - VEC4_MUL(dest[1], quadColor[1], temp); /* G */ - VEC4_MUL(dest[2], quadColor[2], temp); /* B */ - } + if (has_dst_alpha) { + const float *alpha = quadColor[3]; + float diff[4], temp[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(dest[0], quadColor[0], temp); /* R */ + VEC4_MUL(dest[1], quadColor[1], temp); /* G */ + VEC4_MUL(dest[2], quadColor[2], temp); /* B */ + } + else { + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + } break; case PIPE_BLENDFACTOR_CONST_COLOR: { @@ -539,13 +572,18 @@ blend_quad(struct quad_stage *qs, } break; case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ - VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ - VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ - } + if (has_dst_alpha) { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + else { + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + } break; case PIPE_BLENDFACTOR_INV_DST_COLOR: { @@ -605,7 +643,12 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + if (has_dst_alpha) { + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + } + else { + /* dest = dest * 1 NO-OP, leave dest as-is */ + } break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: /* dest = dest * 1 NO-OP, leave dest as-is */ @@ -634,12 +677,15 @@ blend_quad(struct quad_stage *qs, case PIPE_BLENDFACTOR_INV_DST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ - } - break; + if (has_dst_alpha) { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + } + else { + VEC4_COPY(dest[3], zero); /* A */ + } + break; case PIPE_BLENDFACTOR_INV_CONST_COLOR: /* fall-through */ case PIPE_BLENDFACTOR_INV_CONST_ALPHA: @@ -751,6 +797,8 @@ blend_fallback(struct quad_stage *qs, = sp_get_cached_tile(softpipe->cbuf_cache[cbuf], quads[0]->input.x0, quads[0]->input.y0); + boolean has_dst_alpha + = util_format_has_alpha(softpipe->framebuffer.cbufs[cbuf]->format); uint q, i, j; for (q = 0; q < nr; q++) { @@ -774,7 +822,7 @@ blend_fallback(struct quad_stage *qs, logicop_quad( qs, quadColor, dest ); } else if (blend->rt[blend_buf].blend_enable) { - blend_quad( qs, quadColor, dest, cbuf ); + blend_quad( qs, quadColor, dest, cbuf, has_dst_alpha ); } if (blend->rt[blend_buf].colormask != 0xf) diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index b04c2a63ad6..32cab06004f 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "util/u_rect.h" +#include "util/u_surface.h" #include "sp_context.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index fbce9e042ba..b3e1c494069 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -115,6 +115,20 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc) } } +static boolean +sp_tex_tile_is_compat_view(struct softpipe_tex_tile_cache *tc, + struct pipe_sampler_view *view) +{ + if (!view) + return FALSE; + return (tc->texture == view->texture && + tc->format == view->format && + tc->swizzle_r == view->swizzle_r && + tc->swizzle_g == view->swizzle_g && + tc->swizzle_b == view->swizzle_b && + tc->swizzle_a == view->swizzle_a); +} + /** * Specify the sampler view to cache. */ @@ -127,7 +141,7 @@ sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, assert(!tc->transfer); - if (tc->texture != texture) { + if (!sp_tex_tile_is_compat_view(tc, view)) { pipe_resource_reference(&tc->texture, texture); if (tc->tex_trans) { diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index 3228a6d3d7f..75d8afb2ea8 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -194,6 +194,7 @@ void svga_context_flush( struct svga_context *svga, struct pipe_fence_handle **pfence ) { struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); + struct pipe_fence_handle *fence = NULL; svga->curr.nr_fbs = 0; @@ -202,21 +203,26 @@ void svga_context_flush( struct svga_context *svga, u_upload_flush(svga->upload_vb); u_upload_flush(svga->upload_ib); - /* Flush screen, to ensure that texture dma uploads are processed + /* Ensure that texture dma uploads are processed * before submitting commands. */ - svga_screen_flush(svgascreen, NULL); - svga_context_flush_buffers(svga); /* Flush pending commands to hardware: */ - svga->swc->flush(svga->swc, pfence); + svga->swc->flush(svga->swc, &fence); + + svga_screen_cache_flush(svgascreen, fence); if (SVGA_DEBUG & DEBUG_SYNC) { - if (pfence && *pfence) - svga->pipe.screen->fence_finish( svga->pipe.screen, *pfence, 0); + if (fence) + svga->pipe.screen->fence_finish( svga->pipe.screen, fence, 0); } + + if(pfence) + *pfence = fence; + else + svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); } diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c index 005996d05d3..da33fae62f1 100644 --- a/src/gallium/drivers/svga/svga_draw_arrays.c +++ b/src/gallium/drivers/svga/svga_draw_arrays.c @@ -277,12 +277,13 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl, ret = svga_hwtnl_simple_draw_range_elements( hwtnl, gen_buf, gen_size, + start, 0, count - 1, gen_prim, 0, - gen_nr, - start ); + gen_nr ); + if (ret) goto done; diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 9c6f5858ba4..96fb4b8e536 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -68,6 +68,7 @@ static boolean svga_get_query_result(struct pipe_context *pipe, static struct pipe_query *svga_create_query( struct pipe_context *pipe, unsigned query_type ) { + struct svga_context *svga = svga_context( pipe ); struct svga_screen *svgascreen = svga_screen(pipe->screen); struct svga_winsys_screen *sws = svgascreen->sws; struct svga_query *sq; @@ -80,7 +81,7 @@ static struct pipe_query *svga_create_query( struct pipe_context *pipe, sq->type = SVGA3D_QUERYTYPE_OCCLUSION; - sq->hwbuf = svga_winsys_buffer_create(svgascreen, + sq->hwbuf = svga_winsys_buffer_create(svga, 1, SVGA_BUFFER_USAGE_PINNED, sizeof *sq->queryResult); diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index 18eeff9c67e..198d4013328 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -125,8 +125,6 @@ svga_buffer_map_range( struct pipe_screen *screen, } if(map) { - pipe_mutex_lock(ss->swc_mutex); - ++sbuf->map.count; if (usage & PIPE_TRANSFER_WRITE) { @@ -135,8 +133,6 @@ svga_buffer_map_range( struct pipe_screen *screen, if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) sbuf->map.flush_explicit = TRUE; } - - pipe_mutex_unlock(ss->swc_mutex); } return map; diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h index 55e7321184f..d3ec11bfd52 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.h +++ b/src/gallium/drivers/svga/svga_resource_buffer.h @@ -238,7 +238,7 @@ void svga_context_flush_buffers(struct svga_context *svga); struct svga_winsys_buffer * -svga_winsys_buffer_create(struct svga_screen *ss, +svga_winsys_buffer_create(struct svga_context *svga, unsigned alignment, unsigned usage, unsigned size); diff --git a/src/gallium/drivers/svga/svga_resource_buffer_host.c b/src/gallium/drivers/svga/svga_resource_buffer_host.c deleted file mode 100644 index 139597f9cb0..00000000000 --- a/src/gallium/drivers/svga/svga_resource_buffer_host.c +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index acef60f4647..3de5216a949 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -40,15 +40,21 @@ #include "svga_debug.h" -/* Allocate a winsys_buffer (ie. DMA, aka GMR memory). +/** + * Allocate a winsys_buffer (ie. DMA, aka GMR memory). + * + * It will flush and retry in case the first attempt to create a DMA buffer + * fails, so it should not be called from any function involved in flushing + * to avoid recursion. */ struct svga_winsys_buffer * -svga_winsys_buffer_create( struct svga_screen *ss, +svga_winsys_buffer_create( struct svga_context *svga, unsigned alignment, unsigned usage, unsigned size ) { - struct svga_winsys_screen *sws = ss->sws; + struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); + struct svga_winsys_screen *sws = svgascreen->sws; struct svga_winsys_buffer *buf; /* Just try */ @@ -59,9 +65,8 @@ svga_winsys_buffer_create( struct svga_screen *ss, size); /* Try flushing all pending DMAs */ - svga_screen_flush(ss, NULL); + svga_context_flush(svga, NULL); buf = sws->buffer_create(sws, alignment, usage, size); - } return buf; @@ -95,11 +100,12 @@ svga_buffer_create_hw_storage(struct svga_screen *ss, assert(!sbuf->user); if(!sbuf->hwbuf) { + struct svga_winsys_screen *sws = ss->sws; unsigned alignment = 16; unsigned usage = 0; unsigned size = sbuf->b.b.width0; - sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size); + sbuf->hwbuf = sws->buffer_create(sws, alignment, usage, size); if(!sbuf->hwbuf) return PIPE_ERROR_OUT_OF_MEMORY; @@ -476,12 +482,12 @@ svga_buffer_upload_piecewise(struct svga_screen *ss, if (offset + size > range->end) size = range->end - offset; - hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size); + hwbuf = sws->buffer_create(sws, alignment, usage, size); while (!hwbuf) { size /= 2; if (!size) return PIPE_ERROR_OUT_OF_MEMORY; - hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size); + hwbuf = sws->buffer_create(sws, alignment, usage, size); } SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n", diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index f06b0323d8c..ff83c750aaf 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -163,12 +163,12 @@ svga_translate_format_render(enum pipe_format format) static INLINE void -svga_transfer_dma_band(struct svga_transfer *st, +svga_transfer_dma_band(struct svga_context *svga, + struct svga_transfer *st, SVGA3dTransferType transfer, unsigned y, unsigned h, unsigned srcy) { struct svga_texture *texture = svga_texture(st->base.resource); - struct svga_screen *screen = svga_screen(texture->b.b.screen); SVGA3dCopyBox box; enum pipe_error ret; @@ -195,20 +195,19 @@ svga_transfer_dma_band(struct svga_transfer *st, box.srcy = srcy; box.srcz = 0; - pipe_mutex_lock(screen->swc_mutex); - ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1); + ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1); if(ret != PIPE_OK) { - screen->swc->flush(screen->swc, NULL); - ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1); + svga->swc->flush(svga->swc, NULL); + ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1); assert(ret == PIPE_OK); } - pipe_mutex_unlock(screen->swc_mutex); } static INLINE void -svga_transfer_dma(struct svga_transfer *st, - SVGA3dTransferType transfer) +svga_transfer_dma(struct svga_context *svga, + struct svga_transfer *st, + SVGA3dTransferType transfer) { struct svga_texture *texture = svga_texture(st->base.resource); struct svga_screen *screen = svga_screen(texture->b.b.screen); @@ -223,10 +222,10 @@ svga_transfer_dma(struct svga_transfer *st, if(!st->swbuf) { /* Do the DMA transfer in a single go */ - svga_transfer_dma_band(st, transfer, st->base.box.y, st->base.box.height, 0); + svga_transfer_dma_band(svga, st, transfer, st->base.box.y, st->base.box.height, 0); if(transfer == SVGA3D_READ_HOST_VRAM) { - svga_screen_flush(screen, &fence); + svga_context_flush(svga, &fence); sws->fence_finish(sws, fence, 0); sws->fence_reference(sws, &fence, NULL); } @@ -256,7 +255,7 @@ svga_transfer_dma(struct svga_transfer *st, /* Wait for the previous DMAs to complete */ /* TODO: keep one DMA (at half the size) in the background */ if(y) { - svga_screen_flush(screen, &fence); + svga_context_flush(svga, &fence); sws->fence_finish(sws, fence, 0); sws->fence_reference(sws, &fence, NULL); } @@ -269,10 +268,10 @@ svga_transfer_dma(struct svga_transfer *st, } } - svga_transfer_dma_band(st, transfer, y, h, srcy); + svga_transfer_dma_band(svga, st, transfer, y, h, srcy); if(transfer == SVGA3D_READ_HOST_VRAM) { - svga_screen_flush(screen, &fence); + svga_context_flush(svga, &fence); sws->fence_finish(sws, fence, 0); hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_READ); @@ -342,6 +341,7 @@ svga_texture_get_transfer(struct pipe_context *pipe, unsigned usage, const struct pipe_box *box) { + struct svga_context *svga = svga_context(pipe); struct svga_screen *ss = svga_screen(pipe->screen); struct svga_winsys_screen *sws = ss->sws; struct svga_transfer *st; @@ -365,12 +365,12 @@ svga_texture_get_transfer(struct pipe_context *pipe, st->hw_nblocksy = nblocksy; - st->hwbuf = svga_winsys_buffer_create(ss, + st->hwbuf = svga_winsys_buffer_create(svga, 1, 0, st->hw_nblocksy*st->base.stride); while(!st->hwbuf && (st->hw_nblocksy /= 2)) { - st->hwbuf = svga_winsys_buffer_create(ss, + st->hwbuf = svga_winsys_buffer_create(svga, 1, 0, st->hw_nblocksy*st->base.stride); @@ -393,7 +393,7 @@ svga_texture_get_transfer(struct pipe_context *pipe, } if (usage & PIPE_TRANSFER_READ) - svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM); + svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM); return &st->base; @@ -445,13 +445,14 @@ static void svga_texture_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *transfer) { + struct svga_context *svga = svga_context(pipe); struct svga_texture *tex = svga_texture(transfer->resource); struct svga_screen *ss = svga_screen(pipe->screen); struct svga_winsys_screen *sws = ss->sws; struct svga_transfer *st = svga_transfer(transfer); if (st->base.usage & PIPE_TRANSFER_WRITE) { - svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM); + svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM); ss->texture_timestamp++; tex->view_age[transfer->sr.level] = ++(tex->age); tex->defined[transfer->sr.face][transfer->sr.level] = TRUE; diff --git a/src/gallium/drivers/svga/svga_sampler_view.c b/src/gallium/drivers/svga/svga_sampler_view.c index fbae552f78f..6911f13f778 100644 --- a/src/gallium/drivers/svga/svga_sampler_view.c +++ b/src/gallium/drivers/svga/svga_sampler_view.c @@ -169,7 +169,7 @@ svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view * for (i = v->min_lod; i <= v->max_lod; i++) { for (k = 0; k < numFaces; k++) { if (v->age < tex->view_age[i]) - svga_texture_copy_handle(svga, NULL, + svga_texture_copy_handle(svga, tex->handle, 0, 0, 0, i, k, v->handle, 0, 0, 0, i - v->min_lod, k, u_minify(tex->b.b.width0, i), diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index aeda3dcad51..27ac09e275d 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -34,6 +34,7 @@ #include "svga_resource_texture.h" #include "svga_resource.h" #include "svga_debug.h" +#include "svga_surface.h" #include "svga3d_shaderdefs.h" @@ -346,8 +347,6 @@ svga_destroy_screen( struct pipe_screen *screen ) pipe_mutex_destroy(svgascreen->swc_mutex); pipe_mutex_destroy(svgascreen->tex_mutex); - svgascreen->swc->destroy(svgascreen->swc); - svgascreen->sws->destroy(svgascreen->sws); FREE(svgascreen); @@ -397,6 +396,7 @@ svga_screen_create(struct svga_winsys_screen *sws) screen->fence_finish = svga_fence_finish; svgascreen->sws = sws; + svga_screen_init_surface_functions(screen); svga_init_screen_resource_functions(svgascreen); svgascreen->use_ps30 = @@ -416,10 +416,6 @@ svga_screen_create(struct svga_winsys_screen *sws) svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE; #endif - svgascreen->swc = sws->context_create(sws); - if(!svgascreen->swc) - goto error2; - pipe_mutex_init(svgascreen->tex_mutex); pipe_mutex_init(svgascreen->swc_mutex); @@ -432,25 +428,6 @@ error1: return NULL; } -void svga_screen_flush( struct svga_screen *svgascreen, - struct pipe_fence_handle **pfence ) -{ - struct pipe_fence_handle *fence = NULL; - - SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__); - - pipe_mutex_lock(svgascreen->swc_mutex); - svgascreen->swc->flush(svgascreen->swc, &fence); - pipe_mutex_unlock(svgascreen->swc_mutex); - - svga_screen_cache_flush(svgascreen, fence); - - if(pfence) - *pfence = fence; - else - svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL); -} - struct svga_winsys_screen * svga_winsys_screen(struct pipe_screen *screen) { diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h index 9dc229b0a87..86ec89d88c1 100644 --- a/src/gallium/drivers/svga/svga_screen.h +++ b/src/gallium/drivers/svga/svga_screen.h @@ -60,14 +60,11 @@ struct svga_screen boolean no_sampler_view; } debug; - /* The screen needs its own context */ - struct svga_winsys_context *swc; - struct SVGACmdMemory *fifo; - unsigned texture_timestamp; pipe_mutex tex_mutex; - pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */ - + + pipe_mutex swc_mutex; /* Used for buffer uploads */ + struct svga_host_surface_cache cache; }; @@ -83,7 +80,4 @@ struct svga_screen * svga_screen(struct pipe_screen *screen); #endif -void svga_screen_flush( struct svga_screen *svga_screen, - struct pipe_fence_handle **pfence ); - #endif /* SVGA_SCREEN_H */ diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c index dc1d9a850df..bd2cc380048 100644 --- a/src/gallium/drivers/svga/svga_surface.c +++ b/src/gallium/drivers/svga/svga_surface.c @@ -43,7 +43,6 @@ void svga_texture_copy_handle(struct svga_context *svga, - struct svga_screen *ss, struct svga_winsys_surface *src_handle, unsigned src_x, unsigned src_y, unsigned src_z, unsigned src_level, unsigned src_face, @@ -56,7 +55,7 @@ svga_texture_copy_handle(struct svga_context *svga, enum pipe_error ret; SVGA3dCopyBox box, *boxes; - assert(svga || ss); + assert(svga); src.handle = src_handle; src.real_level = src_level; @@ -84,39 +83,20 @@ svga_texture_copy_handle(struct svga_context *svga, dst_handle, dst_level, dst_x, dst_y, dst_z); */ - if (svga) { + ret = SVGA3D_BeginSurfaceCopy(svga->swc, + &src.base, + &dst.base, + &boxes, 1); + if(ret != PIPE_OK) { + svga_context_flush(svga, NULL); ret = SVGA3D_BeginSurfaceCopy(svga->swc, &src.base, &dst.base, &boxes, 1); - if(ret != PIPE_OK) { - svga_context_flush(svga, NULL); - ret = SVGA3D_BeginSurfaceCopy(svga->swc, - &src.base, - &dst.base, - &boxes, 1); - assert(ret == PIPE_OK); - } - *boxes = box; - SVGA_FIFOCommitAll(svga->swc); - } else { - pipe_mutex_lock(ss->swc_mutex); - ret = SVGA3D_BeginSurfaceCopy(ss->swc, - &src.base, - &dst.base, - &boxes, 1); - if(ret != PIPE_OK) { - ss->swc->flush(ss->swc, NULL); - ret = SVGA3D_BeginSurfaceCopy(ss->swc, - &src.base, - &dst.base, - &boxes, 1); - assert(ret == PIPE_OK); - } - *boxes = box; - SVGA_FIFOCommitAll(ss->swc); - pipe_mutex_unlock(ss->swc_mutex); + assert(ret == PIPE_OK); } + *boxes = box; + SVGA_FIFOCommitAll(svga->swc); } @@ -183,7 +163,6 @@ svga_texture_view_surface(struct pipe_context *pipe, 1); svga_texture_copy_handle(svga_context(pipe), - ss, tex->handle, 0, 0, z_offset, i + start_mip, @@ -346,7 +325,7 @@ svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf) if (s->handle != tex->handle) { SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf); - svga_texture_copy_handle(svga_context(pipe), ss, + svga_texture_copy_handle(svga_context(pipe), s->handle, 0, 0, 0, s->real_level, s->real_face, tex->handle, 0, 0, surf->zslice, surf->level, surf->face, u_minify(tex->b.b.width0, surf->level), diff --git a/src/gallium/drivers/svga/svga_surface.h b/src/gallium/drivers/svga/svga_surface.h index b50ecdc9942..13bd5b19b61 100644 --- a/src/gallium/drivers/svga/svga_surface.h +++ b/src/gallium/drivers/svga/svga_surface.h @@ -74,7 +74,6 @@ svga_texture_view_surface(struct pipe_context *pipe, void svga_texture_copy_handle(struct svga_context *svga, - struct svga_screen *ss, struct svga_winsys_surface *src_handle, unsigned src_x, unsigned src_y, unsigned src_z, unsigned src_level, unsigned src_face, diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index 3892addafd1..c155f5dae2f 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -85,7 +85,7 @@ struct svga_winsys_context /** * Emit a relocation for a host surface. * - * @param flags PIPE_BUFFER_USAGE_GPU_READ/WRITE + * @param flags bitmask of SVGA_RELOC_* flags * * NOTE: Order of this call does matter. It should be the same order * as relocations appear in the command buffer. @@ -99,7 +99,7 @@ struct svga_winsys_context /** * Emit a relocation for a guest memory region. * - * @param flags PIPE_BUFFER_USAGE_GPU_READ/WRITE + * @param flags bitmask of SVGA_RELOC_* flags * * NOTE: Order of this call does matter. It should be the same order * as relocations appear in the command buffer. @@ -230,7 +230,7 @@ struct svga_winsys_screen /** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * - * XXX usage seems to be a bitmask of SVGA_BUFFER_USAGE_* flags. + * @param usage bitmask of SVGA_BUFFER_USAGE_* flags. * * alignment indicates the client's alignment requirements, eg for * SSE instructions. @@ -243,15 +243,12 @@ struct svga_winsys_screen /** * Map the entire data store of a buffer object into the client's address. - * flags is a bitmask of: - * - PB_USAGE_CPU_READ/WRITE - * - PB_USAGE_DONTBLOCK - * - PB_USAGE_UNSYNCHRONIZED + * flags is a bitmaks of PIPE_TRANSFER_* */ void * (*buffer_map)( struct svga_winsys_screen *sws, struct svga_winsys_buffer *buf, - unsigned usage ); + unsigned flags ); void (*buffer_unmap)( struct svga_winsys_screen *sws, diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 71ba1e909df..3d1fb96b91e 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -812,7 +812,7 @@ trace_context_delete_vertex_elements_state(struct pipe_context *_pipe, struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin("pipe_context", "delete_verte_elements_state"); + trace_dump_call_begin("pipe_context", "delete_vertex_elements_state"); trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, state); |