summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_surface.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c169
1 files changed, 101 insertions, 68 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 8e905b8d7a0..cf5e4a48cdd 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* Copyright 2007 VMware, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,11 +10,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,7 +22,7 @@
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
#include "util/u_rect.h"
@@ -36,6 +36,7 @@
#include "lp_query.h"
#include "lp_rast.h"
+
static void
lp_resource_copy_ms(struct pipe_context *pipe,
struct pipe_resource *dst, unsigned dst_level,
@@ -44,19 +45,18 @@ lp_resource_copy_ms(struct pipe_context *pipe,
const struct pipe_box *src_box)
{
struct pipe_box dst_box = *src_box;
- enum pipe_format src_format;
dst_box.x = dstx;
dst_box.y = dsty;
dst_box.z = dstz;
- src_format = src->format;
+ enum pipe_format src_format = src->format;
- for (unsigned i = 0; i < src->nr_samples; i++) {
+ for (unsigned i = 0; i < MAX2(src->nr_samples, dst->nr_samples); i++) {
struct pipe_transfer *src_trans, *dst_trans;
- const uint8_t *src_map = llvmpipe_transfer_map_ms(pipe,
- src, 0, PIPE_MAP_READ, i,
- src_box,
- &src_trans);
+ const uint8_t *src_map =
+ llvmpipe_transfer_map_ms(pipe,src, 0, PIPE_MAP_READ,
+ MIN2(i, src->nr_samples - 1),
+ src_box, &src_trans);
if (!src_map)
return;
@@ -81,6 +81,8 @@ lp_resource_copy_ms(struct pipe_context *pipe,
pipe->texture_unmap(pipe, src_trans);
}
}
+
+
static void
lp_resource_copy(struct pipe_context *pipe,
struct pipe_resource *dst, unsigned dst_level,
@@ -90,20 +92,21 @@ lp_resource_copy(struct pipe_context *pipe,
{
llvmpipe_flush_resource(pipe,
dst, dst_level,
- FALSE, /* read_only */
- TRUE, /* cpu_access */
- FALSE, /* do_not_block */
+ false, /* read_only */
+ true, /* cpu_access */
+ false, /* do_not_block */
"blit dest");
llvmpipe_flush_resource(pipe,
src, src_level,
- TRUE, /* read_only */
- TRUE, /* cpu_access */
- FALSE, /* do_not_block */
+ true, /* read_only */
+ true, /* cpu_access */
+ false, /* do_not_block */
"blit src");
if (dst->nr_samples > 1 &&
- dst->nr_samples == src->nr_samples) {
+ (dst->nr_samples == src->nr_samples ||
+ (src->nr_samples == 1 && dst->nr_samples > 1))) {
lp_resource_copy_ms(pipe, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box);
return;
@@ -113,8 +116,9 @@ lp_resource_copy(struct pipe_context *pipe,
}
-static void lp_blit(struct pipe_context *pipe,
- const struct pipe_blit_info *blit_info)
+static void
+lp_blit(struct pipe_context *pipe,
+ const struct pipe_blit_info *blit_info)
{
struct llvmpipe_context *lp = llvmpipe_context(pipe);
struct pipe_blit_info info = *blit_info;
@@ -122,10 +126,25 @@ static void lp_blit(struct pipe_context *pipe,
if (blit_info->render_condition_enable && !llvmpipe_check_render_cond(lp))
return;
- if (util_try_blit_via_copy_region(pipe, &info)) {
+ if (util_try_blit_via_copy_region(pipe, &info,
+ lp->render_cond_query != NULL)) {
return; /* done */
}
+ if (blit_info->src.resource->format == blit_info->src.format &&
+ blit_info->dst.resource->format == blit_info->dst.format &&
+ blit_info->src.format == blit_info->dst.format &&
+ blit_info->src.resource->nr_samples > 1 &&
+ blit_info->dst.resource->nr_samples < 2 &&
+ blit_info->sample0_only) {
+ util_resource_copy_region(pipe, blit_info->dst.resource,
+ blit_info->dst.level, blit_info->dst.box.x,
+ blit_info->dst.box.y, blit_info->dst.box.z,
+ blit_info->src.resource, blit_info->src.level,
+ &blit_info->src.box);
+ return;
+ }
+
if (!util_blitter_is_blit_supported(lp->blitter, &info)) {
debug_printf("llvmpipe: blit unsupported %s -> %s\n",
util_format_short_name(info.src.resource->format),
@@ -136,20 +155,20 @@ static void lp_blit(struct pipe_context *pipe,
/* for 32-bit unorm depth, avoid the conversions to float and back,
which can introduce accuracy errors. */
if (blit_info->src.format == PIPE_FORMAT_Z32_UNORM &&
- blit_info->dst.format == PIPE_FORMAT_Z32_UNORM && info.filter == PIPE_TEX_FILTER_NEAREST) {
+ blit_info->dst.format == PIPE_FORMAT_Z32_UNORM &&
+ info.filter == PIPE_TEX_FILTER_NEAREST) {
info.src.format = PIPE_FORMAT_R32_UINT;
info.dst.format = PIPE_FORMAT_R32_UINT;
info.mask = PIPE_MASK_R;
}
- /* XXX turn off occlusion and streamout queries */
-
- util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer);
+ util_blitter_save_vertex_buffers(lp->blitter, lp->vertex_buffer,
+ lp->num_vertex_buffers);
util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems);
util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs);
util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs);
util_blitter_save_so_targets(lp->blitter, lp->num_so_targets,
- (struct pipe_stream_output_target**)lp->so_targets);
+ (struct pipe_stream_output_target**)lp->so_targets);
util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer);
util_blitter_save_viewport(lp->blitter, &lp->viewports[0]);
util_blitter_save_scissor(lp->blitter, &lp->scissors[0]);
@@ -157,9 +176,11 @@ static void lp_blit(struct pipe_context *pipe,
util_blitter_save_blend(lp->blitter, (void*)lp->blend);
util_blitter_save_tessctrl_shader(lp->blitter, (void*)lp->tcs);
util_blitter_save_tesseval_shader(lp->blitter, (void*)lp->tes);
- util_blitter_save_depth_stencil_alpha(lp->blitter, (void*)lp->depth_stencil);
+ util_blitter_save_depth_stencil_alpha(lp->blitter,
+ (void*)lp->depth_stencil);
util_blitter_save_stencil_ref(lp->blitter, &lp->stencil_ref);
- util_blitter_save_sample_mask(lp->blitter, lp->sample_mask);
+ util_blitter_save_sample_mask(lp->blitter, lp->sample_mask,
+ lp->min_samples);
util_blitter_save_framebuffer(lp->blitter, &lp->framebuffer);
util_blitter_save_fragment_sampler_states(lp->blitter,
lp->num_samplers[PIPE_SHADER_FRAGMENT],
@@ -168,7 +189,8 @@ static void lp_blit(struct pipe_context *pipe,
lp->num_sampler_views[PIPE_SHADER_FRAGMENT],
lp->sampler_views[PIPE_SHADER_FRAGMENT]);
util_blitter_save_render_condition(lp->blitter, lp->render_cond_query,
- lp->render_cond_cond, lp->render_cond_mode);
+ lp->render_cond_cond,
+ lp->render_cond_mode);
util_blitter_blit(lp->blitter, &info);
}
@@ -176,6 +198,7 @@ static void lp_blit(struct pipe_context *pipe,
static void
lp_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
{
+ llvmpipe_flush_resource(ctx, resource, 0, true, true, false, "resource");
}
@@ -184,8 +207,6 @@ llvmpipe_create_surface(struct pipe_context *pipe,
struct pipe_resource *pt,
const struct pipe_surface *surf_tmpl)
{
- struct pipe_surface *ps;
-
if (!(pt->bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET))) {
debug_printf("Illegal surface creation without bind flag\n");
if (util_format_is_depth_or_stencil(surf_tmpl->format)) {
@@ -196,7 +217,7 @@ llvmpipe_create_surface(struct pipe_context *pipe,
}
}
- ps = CALLOC_STRUCT(pipe_surface);
+ struct pipe_surface *ps = CALLOC_STRUCT(pipe_surface);
if (ps) {
pipe_reference_init(&ps->reference, 1);
pipe_resource_reference(&ps->texture, pt);
@@ -210,10 +231,12 @@ llvmpipe_create_surface(struct pipe_context *pipe,
ps->u.tex.level = surf_tmpl->u.tex.level;
ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
- }
- else {
- /* setting width as number of elements should get us correct renderbuffer width */
- ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1;
+ } else {
+ /* setting width as number of elements should get us correct
+ * renderbuffer width
+ */
+ ps->width = surf_tmpl->u.buf.last_element
+ - surf_tmpl->u.buf.first_element + 1;
ps->height = pt->height0;
ps->u.buf.first_element = surf_tmpl->u.buf.first_element;
ps->u.buf.last_element = surf_tmpl->u.buf.last_element;
@@ -240,7 +263,6 @@ llvmpipe_surface_destroy(struct pipe_context *pipe,
}
-
static void
llvmpipe_get_sample_position(struct pipe_context *pipe,
unsigned sample_count,
@@ -257,12 +279,14 @@ llvmpipe_get_sample_position(struct pipe_context *pipe,
}
}
+
static void
lp_clear_color_texture_helper(struct pipe_transfer *dst_trans,
- ubyte *dst_map,
- enum pipe_format format,
- const union pipe_color_union *color,
- unsigned width, unsigned height, unsigned depth)
+ uint8_t *dst_map,
+ enum pipe_format format,
+ const union pipe_color_union *color,
+ unsigned width, unsigned height,
+ unsigned depth)
{
union util_color uc;
@@ -275,6 +299,7 @@ lp_clear_color_texture_helper(struct pipe_transfer *dst_trans,
0, 0, 0, width, height, depth, &uc);
}
+
static void
lp_clear_color_texture_msaa(struct pipe_context *pipe,
struct pipe_resource *texture,
@@ -284,7 +309,7 @@ lp_clear_color_texture_msaa(struct pipe_context *pipe,
const struct pipe_box *box)
{
struct pipe_transfer *dst_trans;
- ubyte *dst_map;
+ uint8_t *dst_map;
dst_map = llvmpipe_transfer_map_ms(pipe, texture, 0, PIPE_MAP_WRITE,
sample, box, &dst_trans);
@@ -298,6 +323,7 @@ lp_clear_color_texture_msaa(struct pipe_context *pipe,
pipe->texture_unmap(pipe, dst_trans);
}
+
static void
llvmpipe_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
@@ -311,6 +337,9 @@ llvmpipe_clear_render_target(struct pipe_context *pipe,
if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe))
return;
+ width = MIN2(width, dst->texture->width0 - dstx);
+ height = MIN2(height, dst->texture->height0 - dsty);
+
if (dst->texture->nr_samples > 1) {
struct pipe_box box;
u_box_2d(dstx, dsty, width, height, &box);
@@ -322,9 +351,10 @@ llvmpipe_clear_render_target(struct pipe_context *pipe,
lp_clear_color_texture_msaa(pipe, dst->texture, dst->format,
color, s, &box);
}
- } else
+ } else {
util_clear_render_target(pipe, dst, color,
dstx, dsty, width, height);
+ }
}
@@ -337,20 +367,20 @@ lp_clear_depth_stencil_texture_msaa(struct pipe_context *pipe,
const struct pipe_box *box)
{
struct pipe_transfer *dst_trans;
- ubyte *dst_map;
- boolean need_rmw = FALSE;
+ bool need_rmw = false;
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) &&
((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
- util_format_is_depth_and_stencil(format))
- need_rmw = TRUE;
-
- dst_map = llvmpipe_transfer_map_ms(pipe,
- texture,
- 0,
- (need_rmw ? PIPE_MAP_READ_WRITE :
- PIPE_MAP_WRITE),
- sample, box, &dst_trans);
+ util_format_is_depth_and_stencil(format)) {
+ need_rmw = true;
+ }
+
+ uint8_t *dst_map = llvmpipe_transfer_map_ms(pipe,
+ texture,
+ 0,
+ (need_rmw ? PIPE_MAP_READ_WRITE :
+ PIPE_MAP_WRITE),
+ sample, box, &dst_trans);
assert(dst_map);
if (!dst_map)
return;
@@ -358,12 +388,13 @@ lp_clear_depth_stencil_texture_msaa(struct pipe_context *pipe,
assert(dst_trans->stride > 0);
util_fill_zs_box(dst_map, format, need_rmw, clear_flags,
- dst_trans->stride, dst_trans->layer_stride,
- box->width, box->height, box->depth, zstencil);
+ dst_trans->stride, dst_trans->layer_stride,
+ box->width, box->height, box->depth, zstencil);
pipe->texture_unmap(pipe, dst_trans);
}
+
static void
llvmpipe_clear_depth_stencil(struct pipe_context *pipe,
struct pipe_surface *dst,
@@ -379,6 +410,9 @@ llvmpipe_clear_depth_stencil(struct pipe_context *pipe,
if (render_condition_enabled && !llvmpipe_check_render_cond(llvmpipe))
return;
+ width = MIN2(width, dst->texture->width0 - dstx);
+ height = MIN2(height, dst->texture->height0 - dsty);
+
if (dst->texture->nr_samples > 1) {
uint64_t zstencil = util_pack64_z_stencil(dst->format, depth, stencil);
struct pipe_box box;
@@ -391,12 +425,14 @@ llvmpipe_clear_depth_stencil(struct pipe_context *pipe,
lp_clear_depth_stencil_texture_msaa(pipe, dst->texture,
dst->format, clear_flags,
zstencil, s, &box);
- } else
+ } else {
util_clear_depth_stencil(pipe, dst, clear_flags,
depth, stencil,
dstx, dsty, width, height);
+ }
}
+
static void
llvmpipe_clear_texture(struct pipe_context *pipe,
struct pipe_resource *tex,
@@ -407,7 +443,7 @@ llvmpipe_clear_texture(struct pipe_context *pipe,
const struct util_format_description *desc =
util_format_description(tex->format);
if (tex->nr_samples <= 1) {
- util_clear_texture(pipe, tex, level, box, data);
+ util_clear_texture_sw(pipe, tex, level, box, data);
return;
}
union pipe_color_union color;
@@ -431,8 +467,8 @@ llvmpipe_clear_texture(struct pipe_context *pipe,
zstencil = util_pack64_z_stencil(tex->format, depth, stencil);
for (unsigned s = 0; s < util_res_sample_count(tex); s++)
- lp_clear_depth_stencil_texture_msaa(pipe, tex, tex->format, clear, zstencil,
- s, box);
+ lp_clear_depth_stencil_texture_msaa(pipe, tex, tex->format, clear,
+ zstencil, s, box);
} else {
util_format_unpack_rgba(tex->format, color.ui, data, 1);
@@ -443,6 +479,7 @@ llvmpipe_clear_texture(struct pipe_context *pipe,
}
}
+
static void
llvmpipe_clear_buffer(struct pipe_context *pipe,
struct pipe_resource *res,
@@ -453,15 +490,10 @@ llvmpipe_clear_buffer(struct pipe_context *pipe,
{
struct pipe_transfer *dst_t;
struct pipe_box box;
- char *dst;
+
u_box_1d(offset, size, &box);
- dst = pipe->buffer_map(pipe,
- res,
- 0,
- PIPE_MAP_WRITE,
- &box,
- &dst_t);
+ char *dst = pipe->buffer_map(pipe, res, 0, PIPE_MAP_WRITE, &box, &dst_t);
switch (clear_value_size) {
case 1:
@@ -478,6 +510,7 @@ llvmpipe_clear_buffer(struct pipe_context *pipe,
pipe->buffer_unmap(pipe, dst_t);
}
+
void
llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
{