Ejemplo n.º 1
0
static void
vc4_clear(struct pipe_context *pctx, unsigned buffers,
          const union pipe_color_union *color, double depth, unsigned stencil)
{
        struct vc4_context *vc4 = vc4_context(pctx);

        /* We can't flag new buffers for clearing once we've queued draws.  We
         * could avoid this by using the 3d engine to clear.
         */
        if (vc4->draw_call_queued)
                vc4_flush(pctx);

        if (buffers & PIPE_CLEAR_COLOR0) {
                vc4->clear_color[0] = vc4->clear_color[1] =
                        pack_rgba(vc4->framebuffer.cbufs[0]->format,
                                  color->f);
        }

        if (buffers & PIPE_CLEAR_DEPTH) {
                /* Though the depth buffer is stored with Z in the high 24,
                 * for this field we just need to store it in the low 24.
                 */
                vc4->clear_depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
        }

        if (buffers & PIPE_CLEAR_STENCIL)
                vc4->clear_stencil = stencil;

        vc4->cleared |= buffers;
        vc4->resolve |= buffers;

        vc4_start_draw(vc4);
}
Ejemplo n.º 2
0
static void
fd_clear(struct pipe_context *pctx, unsigned buffers,
		const union pipe_color_union *color, double depth, unsigned stencil)
{
	struct fd_context *ctx = fd_context(pctx);
	struct fd_ringbuffer *ring = ctx->ring;
	struct pipe_framebuffer_state *fb = &ctx->framebuffer.base;
	uint32_t reg, colr = 0;

	ctx->cleared |= buffers;
	ctx->resolve |= buffers;
	ctx->needs_flush = true;

	if (buffers & PIPE_CLEAR_COLOR)
		fd_resource(fb->cbufs[0]->texture)->dirty = true;

	if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))
		fd_resource(fb->zsbuf->texture)->dirty = true;

	DBG("depth=%f, stencil=%u", depth, stencil);

	if ((buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs)
		colr  = pack_rgba(fb->cbufs[0]->format, color->f);

	/* emit generic state now: */
	fd_state_emit(pctx, ctx->dirty &
			(FD_DIRTY_BLEND | FD_DIRTY_VIEWPORT |
					FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR));

	fd_emit_vertex_bufs(ring, 0x9c, (struct fd_vertex_buf[]) {
			{ .prsc = ctx->solid_vertexbuf, .size = 48 },
		}, 1);
Ejemplo n.º 3
0
static void
nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
                         const union pipe_color_union *color,
                         unsigned x, unsigned y, unsigned w, unsigned h)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nv30_surface *sf = nv30_surface(ps);
   struct nv30_miptree *mt = nv30_miptree(ps->texture);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   struct nouveau_pushbuf_refn refn;
   uint32_t rt_format;

   rt_format = nv30_format(pipe->screen, ps->format)->hw;
   if (util_format_get_blocksize(ps->format) == 4)
      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
   else
      rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;

   if (nv30_miptree(ps->texture)->swizzled) {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      rt_format |= util_logbase2(sf->width) << 16;
      rt_format |= util_logbase2(sf->height) << 24;
   } else {
      rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
   }

   refn.bo = mt->base.bo;
   refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
   if (nouveau_pushbuf_space(push, 16, 1, 0) ||
       nouveau_pushbuf_refn (push, &refn, 1))
      return;

   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
   PUSH_DATA (push, sf->width << 16);
   PUSH_DATA (push, sf->height << 16);
   PUSH_DATA (push, rt_format);
   BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);
   if (eng3d->oclass < NV40_3D_CLASS)
      PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
   else
      PUSH_DATA (push, sf->pitch);
   PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (w << 16) | x);
   PUSH_DATA (push, (h << 16) | y);

   BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);
   PUSH_DATA (push, pack_rgba(ps->format, color->f));
   PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |
                    NV30_3D_CLEAR_BUFFERS_COLOR_G |
                    NV30_3D_CLEAR_BUFFERS_COLOR_B |
                    NV30_3D_CLEAR_BUFFERS_COLOR_A);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
Ejemplo n.º 4
0
void convert_image_to_or_from_cairo_format(Image *image) {
	for (int y = 0; y < image->height; y++)
		for (int x = 0; x < image->width; x++) {
			if (image->is_half_float) {
				uint64_t pixel64 = *(uint64_t *)&image->pixels[(y *
					image->extended_width + x) * 2];
				*(uint64_t *)&image->pixels[(y * image->extended_width
					+ x) * 2] = pack_rgba16(pixel64_get_b16(pixel64), pixel64_get_g16(pixel64),
					 pixel64_get_r16(pixel64), pixel64_get_a16(pixel64));
			}
			else {
				uint32_t pixel = image->pixels[y * image->extended_width + x];
				image->pixels[y * image->extended_width + x] =
					pack_rgba(pixel_get_b(pixel), pixel_get_g(pixel), pixel_get_r(pixel),
					pixel_get_a(pixel));
			}
		}
}
Ejemplo n.º 5
0
static void
nv30_clear(struct pipe_context *pipe, unsigned buffers,
           const union pipe_color_union *color, double depth, unsigned stencil)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct pipe_framebuffer_state *fb = &nv30->framebuffer;
   uint32_t colr = 0, zeta = 0, mode = 0;

   if (!nv30_state_validate(nv30, TRUE))
      return;

   if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
      colr  = pack_rgba(fb->cbufs[0]->format, color->f);
      mode |= NV30_3D_CLEAR_BUFFERS_COLOR_R |
              NV30_3D_CLEAR_BUFFERS_COLOR_G |
              NV30_3D_CLEAR_BUFFERS_COLOR_B |
              NV30_3D_CLEAR_BUFFERS_COLOR_A;
   }

   if (fb->zsbuf) {
      zeta = pack_zeta(fb->zsbuf->format, depth, stencil);
      if (buffers & PIPE_CLEAR_DEPTH)
         mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
      if (buffers & PIPE_CLEAR_STENCIL)
         mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
   }

   /*XXX: wtf? fixes clears sometimes not clearing on nv3x... */
   if (nv30->screen->eng3d->oclass < NV40_3D_CLASS) {
      BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
      PUSH_DATA (push, zeta);
      PUSH_DATA (push, colr);
      PUSH_DATA (push, mode);
   }

   BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
   PUSH_DATA (push, zeta);
   PUSH_DATA (push, colr);
   PUSH_DATA (push, mode);

   nv30_state_release(nv30);
}
Ejemplo n.º 6
0
static void
fd2_clear(struct fd_context *ctx, unsigned buffers,
		const union pipe_color_union *color, double depth, unsigned stencil)
{
	struct fd2_context *fd2_ctx = fd2_context(ctx);
	struct fd_ringbuffer *ring = ctx->ring;
	struct pipe_framebuffer_state *fb = &ctx->framebuffer;
	uint32_t reg, colr = 0;

	if ((buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs)
		colr  = pack_rgba(fb->cbufs[0]->format, color->f);

	/* emit generic state now: */
	fd2_emit_state(ctx, ctx->dirty &
			(FD_DIRTY_BLEND | FD_DIRTY_VIEWPORT |
					FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR));

	fd2_emit_vertex_bufs(ring, 0x9c, (struct fd2_vertex_buf[]) {
			{ .prsc = fd2_ctx->solid_vertexbuf, .size = 48 },
		}, 1);
Ejemplo n.º 7
0
static void convert_image_set(int j) {
	for (int i = 0; i < current_nu_mipmaps[j]; i++) {
		for (int y = 0; y < current_image[j][i].height; y++)
			for (int x = 0; x < current_image[j][i].width; x++) {
				if (current_image[j][i].is_half_float) {
					uint64_t pixel64 = *(uint64_t *)&current_image[j][i].pixels[(y *
						current_image[j][i].extended_width + x) * 2];
					*(uint64_t *)&current_image[j][i].pixels[(y * current_image[j][i].extended_width
						+ x) * 2] = pack_rgba16(pixel64_get_b16(pixel64), pixel64_get_g16(pixel64),
						 pixel64_get_r16(pixel64), pixel64_get_a16(pixel64));
				}
				else {
					uint32_t pixel = current_image[j][i].pixels[y *
						current_image[j][i].extended_width + x];
					current_image[j][i].pixels[y * current_image[j][i].extended_width + x] =
						pack_rgba(pixel_get_b(pixel), pixel_get_g(pixel), pixel_get_r(pixel),
							pixel_get_a(pixel));
				}
			}	
	}
}
Ejemplo n.º 8
0
static void
fd4_clear(struct fd_context *ctx, unsigned buffers,
		const union pipe_color_union *color, double depth, unsigned stencil)
{
	struct fd4_context *fd4_ctx = fd4_context(ctx);
	struct fd_ringbuffer *ring = ctx->ring;
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
	unsigned dirty = ctx->dirty;
	unsigned ce, i;
	struct fd4_emit emit = {
		.vtx  = &fd4_ctx->solid_vbuf_state,
		.prog = &ctx->solid_prog,
		.key = {
			.half_precision = true,
		},
	};
	uint32_t colr = 0;

	if ((buffers & PIPE_CLEAR_COLOR) && pfb->nr_cbufs)
		colr  = pack_rgba(pfb->cbufs[0]->format, color->f);

	dirty &= FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
	dirty |= FD_DIRTY_PROG;
	emit.dirty = dirty;

	OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 1);
	OUT_RING(ring, A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);

	/* emit generic state now: */
	fd4_emit_state(ctx, ring, &emit);
	reset_viewport(ring, pfb);

	if (buffers & PIPE_CLEAR_DEPTH) {
		OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
		OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE |
				A4XX_RB_DEPTH_CONTROL_Z_ENABLE |
				A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS));

		fd_wfi(ctx, ring);
		OUT_PKT0(ring, REG_A4XX_GRAS_CL_VPORT_ZOFFSET_0, 2);
		OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZOFFSET_0(0.0));
		OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(depth));
		ctx->dirty |= FD_DIRTY_VIEWPORT;
	} else {
		OUT_PKT0(ring, REG_A4XX_RB_DEPTH_CONTROL, 1);
		OUT_RING(ring, A4XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
	}

	if (buffers & PIPE_CLEAR_STENCIL) {
		OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2);
		OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(stencil) |
				A4XX_RB_STENCILREFMASK_STENCILMASK(stencil) |
				A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
		OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(0) |
				A4XX_RB_STENCILREFMASK_STENCILMASK(0) |
				0xff000000 | // XXX ???
				A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));

		OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
		OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
				A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
				A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_REPLACE) |
				A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
				A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
		OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */
	} else {
		OUT_PKT0(ring, REG_A4XX_RB_STENCILREFMASK, 2);
		OUT_RING(ring, A4XX_RB_STENCILREFMASK_STENCILREF(0) |
				A4XX_RB_STENCILREFMASK_STENCILMASK(0) |
				A4XX_RB_STENCILREFMASK_STENCILWRITEMASK(0));
		OUT_RING(ring, A4XX_RB_STENCILREFMASK_BF_STENCILREF(0) |
				A4XX_RB_STENCILREFMASK_BF_STENCILMASK(0) |
				A4XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0));

		OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
		OUT_RING(ring, A4XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
				A4XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
				A4XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
				A4XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
		OUT_RING(ring, 0x00000000); /* RB_STENCIL_CONTROL2 */
	}

	if (buffers & PIPE_CLEAR_COLOR) {
		OUT_PKT0(ring, REG_A4XX_RB_ALPHA_CONTROL, 1);
		OUT_RING(ring, A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
		ce = 0xf;
	} else {
		ce = 0x0;
	}

	for (i = 0; i < 8; i++) {
		OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
		OUT_RING(ring, A4XX_RB_MRT_CONTROL_FASTCLEAR |
				A4XX_RB_MRT_CONTROL_B11 |
				A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(ce));

		OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);
		OUT_RING(ring, A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
				A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
				A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
				A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
				A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
				A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO));
	}

	fd4_emit_vertex_bufs(ring, &emit);

	OUT_PKT0(ring, REG_A4XX_GRAS_ALPHA_CONTROL, 1);
	OUT_RING(ring, 0x0);          /* XXX GRAS_ALPHA_CONTROL */

	OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1);
	OUT_RING(ring, 0x00000000);

	OUT_PKT0(ring, REG_A4XX_RB_CLEAR_COLOR_DW0, 4);
	OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW0 */
	OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW1 */
	OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW2 */
	OUT_RING(ring, colr);         /* RB_CLEAR_COLOR_DW3 */

	/* until fastclear works: */
	fd4_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);

	OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
	OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
	OUT_RING(ring, 0);            /* ??? UNKNOWN_2209 */

	OUT_PKT0(ring, REG_A4XX_PC_RESTART_INDEX, 1);
	OUT_RING(ring, 0xffffffff);   /* PC_RESTART_INDEX */

	OUT_PKT3(ring, CP_UNKNOWN_1A, 1);
	OUT_RING(ring, 0x00000001);

	fd4_draw(ctx, ring, DI_PT_RECTLIST, USE_VISIBILITY,
			DI_SRC_SEL_AUTO_INDEX, 2, INDEX_SIZE_IGN, 0, 0, NULL);

	OUT_PKT3(ring, CP_UNKNOWN_1A, 1);
	OUT_RING(ring, 0x00000000);

	OUT_PKT0(ring, REG_A4XX_GRAS_CLEAR_CNTL, 1);
	OUT_RING(ring, A4XX_GRAS_CLEAR_CNTL_NOT_FASTCLEAR);

	OUT_PKT0(ring, REG_A4XX_GRAS_SC_CONTROL, 1);
	OUT_RING(ring, A4XX_GRAS_SC_CONTROL_RENDER_MODE(RB_RENDERING_PASS) |
			A4XX_GRAS_SC_CONTROL_MSAA_DISABLE |
			A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
			A4XX_GRAS_SC_CONTROL_RASTER_MODE(0));
}
Ejemplo n.º 9
0
static void
vc4_clear(struct pipe_context *pctx, unsigned buffers,
          const union pipe_color_union *color, double depth, unsigned stencil)
{
        struct vc4_context *vc4 = vc4_context(pctx);
        struct vc4_job *job = vc4_get_job_for_fbo(vc4);

        /* We can't flag new buffers for clearing once we've queued draws.  We
         * could avoid this by using the 3d engine to clear.
         */
        if (job->draw_calls_queued) {
                perf_debug("Flushing rendering to process new clear.\n");
                vc4_job_submit(vc4, job);
                job = vc4_get_job_for_fbo(vc4);
        }

        if (buffers & PIPE_CLEAR_COLOR0) {
                struct vc4_resource *rsc =
                        vc4_resource(vc4->framebuffer.cbufs[0]->texture);
                uint32_t clear_color;

                if (vc4_rt_format_is_565(vc4->framebuffer.cbufs[0]->format)) {
                        /* In 565 mode, the hardware will be packing our color
                         * for us.
                         */
                        clear_color = pack_rgba(PIPE_FORMAT_R8G8B8A8_UNORM,
                                                color->f);
                } else {
                        /* Otherwise, we need to do this packing because we
                         * support multiple swizzlings of RGBA8888.
                         */
                        clear_color =
                                pack_rgba(vc4->framebuffer.cbufs[0]->format,
                                          color->f);
                }
                job->clear_color[0] = job->clear_color[1] = clear_color;
                rsc->initialized_buffers |= (buffers & PIPE_CLEAR_COLOR0);
        }

        if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
                struct vc4_resource *rsc =
                        vc4_resource(vc4->framebuffer.zsbuf->texture);
                unsigned zsclear = buffers & PIPE_CLEAR_DEPTHSTENCIL;

                /* Clearing ZS will clear both Z and stencil, so if we're
                 * trying to clear just one then we need to draw a quad to do
                 * it instead.
                 */
                if ((zsclear == PIPE_CLEAR_DEPTH ||
                     zsclear == PIPE_CLEAR_STENCIL) &&
                    (rsc->initialized_buffers & ~(zsclear | job->cleared)) &&
                    util_format_is_depth_and_stencil(vc4->framebuffer.zsbuf->format)) {
                        perf_debug("Partial clear of Z+stencil buffer, "
                                   "drawing a quad instead of fast clearing\n");
                        vc4_blitter_save(vc4);
                        util_blitter_clear(vc4->blitter,
                                           vc4->framebuffer.width,
                                           vc4->framebuffer.height,
                                           1,
                                           zsclear,
                                           NULL, depth, stencil);
                        buffers &= ~zsclear;
                        if (!buffers)
                                return;
                }

                /* Though the depth buffer is stored with Z in the high 24,
                 * for this field we just need to store it in the low 24.
                 */
                if (buffers & PIPE_CLEAR_DEPTH) {
                        job->clear_depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM,
                                                       depth);
                }
                if (buffers & PIPE_CLEAR_STENCIL)
                        job->clear_stencil = stencil;

                rsc->initialized_buffers |= zsclear;
        }

        job->draw_min_x = 0;
        job->draw_min_y = 0;
        job->draw_max_x = vc4->framebuffer.width;
        job->draw_max_y = vc4->framebuffer.height;
        job->cleared |= buffers;
        job->resolve |= buffers;

        vc4_start_draw(vc4);
}