X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnouveau%2Fnv50%2Fnv50_surface.c;h=34c2633916bd1d20b8252b073500ec810d74227e;hb=c574cda3c6a3f880f99e4e22967fc82e34609942;hp=916a7d44a3127fc4c6932e778cc546c28294977e;hpb=c4182bb9b0897b4a4ac4f06b54fc7f6a2ddeb105;p=mesa.git diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c index 916a7d44a31..34c2633916b 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c @@ -26,7 +26,7 @@ #include "util/u_inlines.h" #include "util/u_pack_color.h" -#include "util/u_format.h" +#include "util/format/u_format.h" #include "util/u_math.h" #include "util/u_surface.h" @@ -37,8 +37,8 @@ #include "nv50/nv50_context.h" #include "nv50/nv50_resource.h" -#include "nv50/nv50_defs.xml.h" -#include "nv50/nv50_texture.xml.h" +#include "nv50/g80_defs.xml.h" +#include "nv50/g80_texture.xml.h" /* these are used in nv50_blit.h */ #define NV50_ENG2D_SUPPORTED_FORMATS 0xff0843e080608409ULL @@ -64,15 +64,15 @@ nv50_2d_format(enum pipe_format format, bool dst, bool dst_src_equal) switch (util_format_get_blocksize(format)) { case 1: - return NV50_SURFACE_FORMAT_R8_UNORM; + return G80_SURFACE_FORMAT_R8_UNORM; case 2: - return NV50_SURFACE_FORMAT_R16_UNORM; + return G80_SURFACE_FORMAT_R16_UNORM; case 4: - return NV50_SURFACE_FORMAT_BGRA8_UNORM; + return G80_SURFACE_FORMAT_BGRA8_UNORM; case 8: - return NV50_SURFACE_FORMAT_RGBA16_FLOAT; + return G80_SURFACE_FORMAT_RGBA16_FLOAT; case 16: - return NV50_SURFACE_FORMAT_RGBA32_FLOAT; + return G80_SURFACE_FORMAT_RGBA32_FLOAT; default: return 0; } @@ -277,7 +277,8 @@ nv50_clear_render_target(struct pipe_context *pipe, struct pipe_surface *dst, const union pipe_color_union *color, unsigned dstx, unsigned dsty, - unsigned width, unsigned height) + unsigned width, unsigned height, + bool render_condition_enabled) { struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; @@ -286,13 +287,15 @@ nv50_clear_render_target(struct pipe_context *pipe, struct nouveau_bo *bo = mt->base.bo; unsigned z; + assert(dst->texture->target != PIPE_BUFFER); + BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4); PUSH_DATAf(push, color->f[0]); PUSH_DATAf(push, color->f[1]); PUSH_DATAf(push, color->f[2]); PUSH_DATAf(push, color->f[3]); - if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) + if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0)) return; PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR); @@ -339,13 +342,23 @@ nv50_clear_render_target(struct pipe_context *pipe, PUSH_DATA (push, (width << 16) | dstx); PUSH_DATA (push, (height << 16) | dsty); + if (!render_condition_enabled) { + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); + } + BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), sf->depth); for (z = 0; z < sf->depth; ++z) { PUSH_DATA (push, 0x3c | (z << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT)); } - nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR; + if (!render_condition_enabled) { + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, nv50->cond_condmode); + } + + nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR; } static void @@ -355,7 +368,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, double depth, unsigned stencil, unsigned dstx, unsigned dsty, - unsigned width, unsigned height) + unsigned width, unsigned height, + bool render_condition_enabled) { struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; @@ -365,6 +379,7 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, uint32_t mode = 0; unsigned z; + assert(dst->texture->target != PIPE_BUFFER); assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */ if (clear_flags & PIPE_CLEAR_DEPTH) { @@ -379,7 +394,7 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, mode |= NV50_3D_CLEAR_BUFFERS_S; } - if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) + if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0)) return; PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR); @@ -415,13 +430,23 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, PUSH_DATA (push, (width << 16) | dstx); PUSH_DATA (push, (height << 16) | dsty); + if (!render_condition_enabled) { + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); + } + BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), sf->depth); for (z = 0; z < sf->depth; ++z) { PUSH_DATA (push, mode | (z << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT)); } - nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR; + if (!render_condition_enabled) { + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, nv50->cond_condmode); + } + + nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR; } void @@ -450,14 +475,14 @@ nv50_clear_texture(struct pipe_context *pipe, if (util_format_has_depth(desc)) { clear |= PIPE_CLEAR_DEPTH; - desc->unpack_z_float(&depth, 0, data, 0, 1, 1); + util_format_unpack_z_float(res->format, &depth, data, 1); } if (util_format_has_stencil(desc)) { clear |= PIPE_CLEAR_STENCIL; - desc->unpack_s_8uint(&stencil, 0, data, 0, 1, 1); + util_format_unpack_s_8uint(res->format, &stencil, data, 1); } pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil, - box->x, box->y, box->width, box->height); + box->x, box->y, box->width, box->height, false); } else { union pipe_color_union color; @@ -493,7 +518,7 @@ nv50_clear_texture(struct pipe_context *pipe, } pipe->clear_render_target(pipe, sf, &color, - box->x, box->y, box->width, box->height); + box->x, box->y, box->width, box->height, false); } pipe->surface_destroy(pipe, sf); } @@ -510,7 +535,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, uint32_t mode = 0; /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */ - if (!nv50_state_validate(nv50, NV50_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2))) + if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER)) return; /* We have to clear ALL of the layers, not up to the min number of layers @@ -579,6 +604,79 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, PUSH_DATA (push, nv50->rt_array_mode); } +static void +nv50_clear_buffer_push(struct pipe_context *pipe, + struct pipe_resource *res, + unsigned offset, unsigned size, + const void *data, int data_size) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_pushbuf *push = nv50->base.pushbuf; + struct nv04_resource *buf = nv04_resource(res); + unsigned count = (size + 3) / 4; + unsigned xcoord = offset & 0xff; + unsigned tmp, i; + + if (data_size == 1) { + tmp = *(unsigned char *)data; + tmp = (tmp << 24) | (tmp << 16) | (tmp << 8) | tmp; + data = &tmp; + data_size = 4; + } else if (data_size == 2) { + tmp = *(unsigned short *)data; + tmp = (tmp << 16) | tmp; + data = &tmp; + data_size = 4; + } + + unsigned data_words = data_size / 4; + + nouveau_bufctx_refn(nv50->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR); + nouveau_pushbuf_bufctx(push, nv50->bufctx); + nouveau_pushbuf_validate(push); + + offset &= ~0xff; + + BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2); + PUSH_DATA (push, G80_SURFACE_FORMAT_R8_UNORM); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_2D(DST_PITCH), 5); + PUSH_DATA (push, 262144); + PUSH_DATA (push, 65536); + PUSH_DATA (push, 1); + PUSH_DATAh(push, buf->address + offset); + PUSH_DATA (push, buf->address + offset); + BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, G80_SURFACE_FORMAT_R8_UNORM); + BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10); + PUSH_DATA (push, size); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, xcoord); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); + + while (count) { + unsigned nr_data = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN) / data_words; + unsigned nr = nr_data * data_words; + + BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr); + for (i = 0; i < nr_data; i++) + PUSH_DATAp(push, data, data_words); + + count -= nr; + } + + nv50_resource_validate(buf, NOUVEAU_BO_WR); + + nouveau_bufctx_reset(nv50->bufctx, 0); +} + static void nv50_clear_buffer(struct pipe_context *pipe, struct pipe_resource *res, @@ -626,19 +724,34 @@ nv50_clear_buffer(struct pipe_context *pipe, return; } + util_range_add(&buf->base, &buf->valid_buffer_range, offset, offset + size); + assert(size % data_size == 0); + if (offset & 0xff) { + unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset); + assert(fixup_size % data_size == 0); + nv50_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size); + offset += fixup_size; + size -= fixup_size; + if (!size) + return; + } + elements = size / data_size; height = (elements + 8191) / 8192; width = elements / height; + if (height > 1) + width &= ~0xff; + assert(width > 0); BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4); - PUSH_DATAf(push, color.f[0]); - PUSH_DATAf(push, color.f[1]); - PUSH_DATAf(push, color.f[2]); - PUSH_DATAf(push, color.f[3]); + PUSH_DATA (push, color.ui[0]); + PUSH_DATA (push, color.ui[1]); + PUSH_DATA (push, color.ui[2]); + PUSH_DATA (push, color.ui[3]); - if (nouveau_pushbuf_space(push, 32, 1, 0)) + if (nouveau_pushbuf_space(push, 64, 1, 0)) return; PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR); @@ -654,13 +767,13 @@ nv50_clear_buffer(struct pipe_context *pipe, BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1); PUSH_DATA (push, 1); BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5); - PUSH_DATAh(push, buf->bo->offset + buf->offset + offset); - PUSH_DATA (push, buf->bo->offset + buf->offset + offset); + PUSH_DATAh(push, buf->address + offset); + PUSH_DATA (push, buf->address + offset); PUSH_DATA (push, nv50_format_table[dst_fmt].rt); PUSH_DATA (push, 0); PUSH_DATA (push, 0); BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2); - PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size)); + PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | align(width * data_size, 0x100)); PUSH_DATA (push, height); BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1); PUSH_DATA (push, 0); @@ -673,27 +786,25 @@ nv50_clear_buffer(struct pipe_context *pipe, PUSH_DATA (push, (width << 16)); PUSH_DATA (push, (height << 16)); + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS); + BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1); PUSH_DATA (push, 0x3c); + BEGIN_NV04(push, NV50_3D(COND_MODE), 1); + PUSH_DATA (push, nv50->cond_condmode); + + nv50_resource_validate(buf, NOUVEAU_BO_WR); + if (width * height != elements) { offset += width * height * data_size; width = elements - width * height; - height = 1; - BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 2); - PUSH_DATAh(push, buf->bo->offset + buf->offset + offset); - PUSH_DATA (push, buf->bo->offset + buf->offset + offset); - BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2); - PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size)); - PUSH_DATA (push, height); - BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1); - PUSH_DATA (push, 0x3c); + nv50_clear_buffer_push(pipe, res, offset, width * data_size, + data, data_size); } - nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence); - nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr); - - nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR; + nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR; } /* =============================== BLIT CODE =================================== @@ -706,7 +817,7 @@ struct nv50_blitter struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */ - pipe_mutex mutex; + mtx_t mutex; }; struct nv50_blitctx @@ -720,6 +831,7 @@ struct nv50_blitctx enum pipe_texture_target target; struct { struct pipe_framebuffer_state fb; + struct nv50_window_rect_stateobj window_rect; struct nv50_rasterizer_stateobj *rast; struct nv50_program *vp; struct nv50_program *gp; @@ -729,7 +841,7 @@ struct nv50_blitctx struct pipe_sampler_view *texture[2]; struct nv50_tsc_entry *sampler[2]; unsigned min_samples; - uint32_t dirty; + uint32_t dirty_3d; } saved; struct nv50_rasterizer_stateobj rast; }; @@ -780,6 +892,10 @@ nv50_blitter_make_fp(struct pipe_context *pipe, bool tex_s = false; bool cvt_un8 = false; + bool int_clamp = mode == NV50_BLIT_MODE_INT_CLAMP; + if (int_clamp) + mode = NV50_BLIT_MODE_PASS; + if (mode != NV50_BLIT_MODE_PASS && mode != NV50_BLIT_MODE_Z24X8 && mode != NV50_BLIT_MODE_X8Z24) @@ -795,7 +911,7 @@ nv50_blitter_make_fp(struct pipe_context *pipe, mode != NV50_BLIT_MODE_XS) cvt_un8 = true; - ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + ureg = ureg_create(PIPE_SHADER_FRAGMENT); if (!ureg) return NULL; @@ -824,6 +940,10 @@ nv50_blitter_make_fp(struct pipe_context *pipe, target, tc, ureg_DECL_sampler(ureg, 0)); } + /* handle signed to unsigned integer conversions */ + if (int_clamp) + ureg_UMIN(ureg, data, ureg_src(data), ureg_imm1u(ureg, 0x7fffffff)); + if (cvt_un8) { struct ureg_src mask; struct ureg_src scale; @@ -892,12 +1012,14 @@ nv50_blitter_make_sampler(struct nv50_blitter *blit) blit->sampler[0].id = -1; - blit->sampler[0].tsc[0] = NV50_TSC_0_SRGB_CONVERSION_ALLOWED | - (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPS__SHIFT) | - (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPT__SHIFT) | - (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPR__SHIFT); + blit->sampler[0].tsc[0] = G80_TSC_0_SRGB_CONVERSION | + (G80_TSC_WRAP_CLAMP_TO_EDGE << G80_TSC_0_ADDRESS_U__SHIFT) | + (G80_TSC_WRAP_CLAMP_TO_EDGE << G80_TSC_0_ADDRESS_V__SHIFT) | + (G80_TSC_WRAP_CLAMP_TO_EDGE << G80_TSC_0_ADDRESS_P__SHIFT); blit->sampler[0].tsc[1] = - NV50_TSC_1_MAGF_NEAREST | NV50_TSC_1_MINF_NEAREST | NV50_TSC_1_MIPF_NONE; + G80_TSC_1_MAG_FILTER_NEAREST | + G80_TSC_1_MIN_FILTER_NEAREST | + G80_TSC_1_MIP_FILTER_NONE; /* clamp to edge, min/max lod = 0, bilinear filtering */ @@ -905,7 +1027,9 @@ nv50_blitter_make_sampler(struct nv50_blitter *blit) blit->sampler[1].tsc[0] = blit->sampler[0].tsc[0]; blit->sampler[1].tsc[1] = - NV50_TSC_1_MAGF_LINEAR | NV50_TSC_1_MINF_LINEAR | NV50_TSC_1_MIPF_NONE; + G80_TSC_1_MAG_FILTER_LINEAR | + G80_TSC_1_MIN_FILTER_LINEAR | + G80_TSC_1_MIP_FILTER_NONE; } unsigned @@ -942,6 +1066,9 @@ nv50_blit_select_mode(const struct pipe_blit_info *info) return NV50_BLIT_MODE_XS; } default: + if (util_format_is_pure_uint(info->src.format) && + util_format_is_pure_sint(info->dst.format)) + return NV50_BLIT_MODE_INT_CLAMP; return NV50_BLIT_MODE_PASS; } } @@ -958,11 +1085,11 @@ nv50_blit_select_fp(struct nv50_blitctx *ctx, const struct pipe_blit_info *info) const unsigned mode = ctx->mode; if (!blitter->fp[targ][mode]) { - pipe_mutex_lock(blitter->mutex); + mtx_lock(&blitter->mutex); if (!blitter->fp[targ][mode]) blitter->fp[targ][mode] = nv50_blitter_make_fp(&ctx->nv50->base.pipe, mode, ptarg); - pipe_mutex_unlock(blitter->mutex); + mtx_unlock(&blitter->mutex); } ctx->fp = blitter->fp[targ][mode]; } @@ -1013,10 +1140,10 @@ nv50_blit_set_src(struct nv50_blitctx *blit, templ.format = format; templ.u.tex.first_level = templ.u.tex.last_level = level; templ.u.tex.first_layer = templ.u.tex.last_layer = layer; - templ.swizzle_r = PIPE_SWIZZLE_RED; - templ.swizzle_g = PIPE_SWIZZLE_GREEN; - templ.swizzle_b = PIPE_SWIZZLE_BLUE; - templ.swizzle_a = PIPE_SWIZZLE_ALPHA; + templ.swizzle_r = PIPE_SWIZZLE_X; + templ.swizzle_g = PIPE_SWIZZLE_Y; + templ.swizzle_b = PIPE_SWIZZLE_Z; + templ.swizzle_a = PIPE_SWIZZLE_W; if (layer == -1) { templ.u.tex.first_layer = 0; @@ -1101,7 +1228,8 @@ nv50_blitctx_prepare_state(struct nv50_blitctx *blit) } static void -nv50_blitctx_pre_blit(struct nv50_blitctx *ctx) +nv50_blitctx_pre_blit(struct nv50_blitctx *ctx, + const struct pipe_blit_info *info) { struct nv50_context *nv50 = ctx->nv50; struct nv50_blitter *blitter = nv50->screen->blitter; @@ -1120,6 +1248,7 @@ nv50_blitctx_pre_blit(struct nv50_blitctx *ctx) ctx->saved.fp = nv50->fragprog; ctx->saved.min_samples = nv50->min_samples; + ctx->saved.window_rect = nv50->window_rect; nv50->rast = &ctx->rast; @@ -1127,6 +1256,13 @@ nv50_blitctx_pre_blit(struct nv50_blitctx *ctx) nv50->gmtyprog = NULL; nv50->fragprog = ctx->fp; + nv50->window_rect.rects = + MIN2(info->num_window_rectangles, NV50_MAX_WINDOW_RECTANGLES); + nv50->window_rect.inclusive = info->window_rectangle_include; + if (nv50->window_rect.rects) + memcpy(nv50->window_rect.rect, info->window_rectangles, + sizeof(struct pipe_scissor_state) * nv50->window_rect.rects); + for (s = 0; s < 3; ++s) { ctx->saved.num_textures[s] = nv50->num_textures[s]; ctx->saved.num_samplers[s] = nv50->num_samplers[s]; @@ -1144,15 +1280,15 @@ nv50_blitctx_pre_blit(struct nv50_blitctx *ctx) nv50->min_samples = 1; - ctx->saved.dirty = nv50->dirty; + ctx->saved.dirty_3d = nv50->dirty_3d; - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES); - nv50->dirty = - NV50_NEW_FRAMEBUFFER | NV50_NEW_MIN_SAMPLES | - NV50_NEW_VERTPROG | NV50_NEW_FRAGPROG | NV50_NEW_GMTYPROG | - NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS; + nv50->dirty_3d = + NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_MIN_SAMPLES | + NV50_NEW_3D_VERTPROG | NV50_NEW_3D_FRAGPROG | NV50_NEW_3D_GMTYPROG | + NV50_NEW_3D_TEXTURES | NV50_NEW_3D_SAMPLERS | NV50_NEW_3D_WINDOW_RECTS; } static void @@ -1176,6 +1312,7 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit) nv50->fragprog = blit->saved.fp; nv50->min_samples = blit->saved.min_samples; + nv50->window_rect = blit->saved.window_rect; pipe_sampler_view_reference(&nv50->textures[2][0], NULL); pipe_sampler_view_reference(&nv50->textures[2][1], NULL); @@ -1193,14 +1330,14 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit) nv50->base.pipe.render_condition(&nv50->base.pipe, nv50->cond_query, nv50->cond_cond, nv50->cond_mode); - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB); + nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES); - nv50->dirty = blit->saved.dirty | - (NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR | NV50_NEW_SAMPLE_MASK | - NV50_NEW_RASTERIZER | NV50_NEW_ZSA | NV50_NEW_BLEND | - NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS | - NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG | NV50_NEW_FRAGPROG); + nv50->dirty_3d = blit->saved.dirty_3d | + (NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR | NV50_NEW_3D_SAMPLE_MASK | + NV50_NEW_3D_RASTERIZER | NV50_NEW_3D_ZSA | NV50_NEW_3D_BLEND | + NV50_NEW_3D_TEXTURES | NV50_NEW_3D_SAMPLERS | NV50_NEW_3D_WINDOW_RECTS | + NV50_NEW_3D_VERTPROG | NV50_NEW_3D_GMTYPROG | NV50_NEW_3D_FRAGPROG); nv50->scissors_dirty |= 1; nv50->base.pipe.set_min_samples(&nv50->base.pipe, blit->saved.min_samples); @@ -1219,7 +1356,6 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) float x0, x1, y0, y1, z; float dz; float x_range, y_range; - float tri_x, tri_y; blit->mode = nv50_blit_select_mode(info); blit->color_mask = nv50_blit_derive_color_mask(info); @@ -1227,7 +1363,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) blit->render_condition_enable = info->render_condition_enable; nv50_blit_select_fp(blit, info); - nv50_blitctx_pre_blit(blit); + nv50_blitctx_pre_blit(blit, info); nv50_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format); nv50_blit_set_src(blit, src, info->src.level, -1, info->src.format, @@ -1235,19 +1371,16 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) nv50_blitctx_prepare_state(blit); - nv50_state_validate(nv50, ~0, 36); + nv50_state_validate_3d(nv50, ~0); x_range = (float)info->src.box.width / (float)info->dst.box.width; y_range = (float)info->src.box.height / (float)info->dst.box.height; - tri_x = 16384 << nv50_miptree(dst)->ms_x; - tri_y = 16384 << nv50_miptree(dst)->ms_y; - x0 = (float)info->src.box.x - x_range * (float)info->dst.box.x; y0 = (float)info->src.box.y - y_range * (float)info->dst.box.y; - x1 = x0 + tri_x * x_range; - y1 = y0 + tri_y * y_range; + x1 = x0 + 16384.0f * x_range; + y1 = y0 + 16384.0f * y_range; x0 *= (float)(1 << nv50_miptree(src)->ms_x); x1 *= (float)(1 << nv50_miptree(src)->ms_x); @@ -1320,7 +1453,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) PUSH_DATAf(push, y0); PUSH_DATAf(push, z); BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2); - PUSH_DATAf(push, tri_x); + PUSH_DATAf(push, 16384.0f); PUSH_DATAf(push, 0.0f); BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3); PUSH_DATAf(push, x0); @@ -1328,7 +1461,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info) PUSH_DATAf(push, z); BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2); PUSH_DATAf(push, 0.0f); - PUSH_DATAf(push, tri_y); + PUSH_DATAf(push, 16384.0f); BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1); PUSH_DATA (push, 0); } @@ -1532,6 +1665,13 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) struct nouveau_pushbuf *push = nv50->base.pushbuf; bool eng3d = FALSE; + if (info->src.box.width == 0 || info->src.box.height == 0 || + info->dst.box.width == 0 || info->dst.box.height == 0) { + pipe_debug_message(&nv50->base.debug, ERROR, + "Blit with zero-size src or dst box"); + return; + } + if (util_format_is_depth_or_stencil(info->dst.resource->format)) { if (!(info->mask & PIPE_MASK_ZS)) return; @@ -1579,6 +1719,9 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) info->dst.resource->nr_samples <= 1) eng3d = true; + if (info->num_window_rectangles > 0 || info->window_rectangle_include) + eng3d = true; + /* FIXME: can't make this work with eng2d anymore */ if ((info->src.resource->nr_samples | 1) != (info->dst.resource->nr_samples | 1)) @@ -1622,7 +1765,7 @@ nv50_blitter_create(struct nv50_screen *screen) return false; } - pipe_mutex_init(screen->blitter->mutex); + (void) mtx_init(&screen->blitter->mutex, mtx_plain); nv50_blitter_make_vp(screen->blitter); nv50_blitter_make_sampler(screen->blitter); @@ -1647,6 +1790,7 @@ nv50_blitter_destroy(struct nv50_screen *screen) } } + mtx_destroy(&blitter->mutex); FREE(blitter); }