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);
}
Exemple #2
0
static uint32_t r300_depth_clear_value(enum pipe_format format,
                                       double depth, unsigned stencil)
{
    switch (format) {
        case PIPE_FORMAT_Z16_UNORM:
        case PIPE_FORMAT_X8Z24_UNORM:
            return util_pack_z(format, depth);

        case PIPE_FORMAT_S8_UINT_Z24_UNORM:
            return util_pack_z_stencil(format, depth, stencil);

        default:
            assert(0);
            return 0;
    }
}
static void
write_texture_border_color(struct vc5_job *job,
                           struct vc5_cl_out **uniforms,
                           struct vc5_texture_stateobj *texstate,
                           uint32_t unit)
{
        struct pipe_sampler_state *sampler = texstate->samplers[unit];
        struct pipe_sampler_view *texture = texstate->textures[unit];
        struct vc5_resource *rsc = vc5_resource(texture->texture);
        union util_color uc;

        const struct util_format_description *tex_format_desc =
                util_format_description(texture->format);

        float border_color[4];
        for (int i = 0; i < 4; i++)
                border_color[i] = sampler->border_color.f[i];
        if (util_format_is_srgb(texture->format)) {
                for (int i = 0; i < 3; i++)
                        border_color[i] =
                                util_format_linear_to_srgb_float(border_color[i]);
        }

        /* Turn the border color into the layout of channels that it would
         * have when stored as texture contents.
         */
        float storage_color[4];
        util_format_unswizzle_4f(storage_color,
                                 border_color,
                                 tex_format_desc->swizzle);

        /* Now, pack so that when the vc5_format-sampled texture contents are
         * replaced with our border color, the vc5_get_format_swizzle()
         * swizzling will get the right channels.
         */
        if (util_format_is_depth_or_stencil(texture->format)) {
                uc.ui[0] = util_pack_z(PIPE_FORMAT_Z24X8_UNORM,
                                       sampler->border_color.f[0]) << 8;
        } else {
                switch (rsc->vc5_format) {
                default:
                case VC5_TEXTURE_TYPE_RGBA8888:
                        util_pack_color(storage_color,
                                        PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
                        break;
                case VC5_TEXTURE_TYPE_RGBA4444:
                        util_pack_color(storage_color,
                                        PIPE_FORMAT_A8B8G8R8_UNORM, &uc);
                        break;
                case VC5_TEXTURE_TYPE_RGB565:
                        util_pack_color(storage_color,
                                        PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
                        break;
                case VC5_TEXTURE_TYPE_ALPHA:
                        uc.ui[0] = float_to_ubyte(storage_color[0]) << 24;
                        break;
                case VC5_TEXTURE_TYPE_LUMALPHA:
                        uc.ui[0] = ((float_to_ubyte(storage_color[1]) << 24) |
                                    (float_to_ubyte(storage_color[0]) << 0));
                        break;
                }
        }

        cl_aligned_u32(uniforms, uc.ui[0]);
}
Exemple #4
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);
}
bool
ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter,
                              struct pipe_surface *zs,
                              unsigned clear_flags,
                              double depth, unsigned stencil)
{
    struct ilo_texture *tex = ilo_texture(zs->texture);
    struct pipe_depth_stencil_alpha_state dsa_state;
    uint32_t uses, clear_value;

    if (!ilo_image_can_enable_aux(&tex->image, zs->u.tex.level))
        return false;

    if (!hiz_can_clear_zs(blitter, tex))
        return false;

    if (ilo_dev_gen(blitter->ilo->dev) >= ILO_GEN(8))
        clear_value = fui(depth);
    else
        clear_value = util_pack_z(tex->image.format, depth);

    ilo_blit_resolve_surface(blitter->ilo, zs,
                             ILO_TEXTURE_RENDER_WRITE | ILO_TEXTURE_CLEAR);
    ilo_texture_set_slice_clear_value(tex, zs->u.tex.level,
                                      zs->u.tex.first_layer,
                                      zs->u.tex.last_layer - zs->u.tex.first_layer + 1,
                                      clear_value);

    /*
     * From the Sandy Bridge PRM, volume 2 part 1, page 313-314:
     *
     *     "- Depth Test Enable must be disabled and Depth Buffer Write Enable
     *        must be enabled (if depth is being cleared).
     *
     *      - Stencil buffer clear can be performed at the same time by
     *        enabling Stencil Buffer Write Enable.  Stencil Test Enable must
     *        be enabled and Stencil Pass Depth Pass Op set to REPLACE, and the
     *        clear value that is placed in the stencil buffer is the Stencil
     *        Reference Value from COLOR_CALC_STATE.
     *
     *      - Note also that stencil buffer clear can be performed without
     *        depth buffer clear. For stencil only clear, Depth Test Enable and
     *        Depth Buffer Write Enable must be disabled.
     *
     *      - [DevSNB] errata: For stencil buffer only clear, the previous
     *        depth clear value must be delivered during the clear."
     */
    memset(&dsa_state, 0, sizeof(dsa_state));

    if (clear_flags & PIPE_CLEAR_DEPTH)
        dsa_state.depth.writemask = true;

    if (clear_flags & PIPE_CLEAR_STENCIL) {
        dsa_state.stencil[0].enabled = true;
        dsa_state.stencil[0].func = PIPE_FUNC_ALWAYS;
        dsa_state.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
        dsa_state.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
        dsa_state.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;

        /*
         * From the Ivy Bridge PRM, volume 2 part 1, page 277:
         *
         *     "Additionally the following must be set to the correct values.
         *
         *      - DEPTH_STENCIL_STATE::Stencil Write Mask must be 0xFF
         *      - DEPTH_STENCIL_STATE::Stencil Test Mask must be 0xFF
         *      - DEPTH_STENCIL_STATE::Back Face Stencil Write Mask must be 0xFF
         *      - DEPTH_STENCIL_STATE::Back Face Stencil Test Mask must be 0xFF"
         */
        dsa_state.stencil[0].valuemask = 0xff;
        dsa_state.stencil[0].writemask = 0xff;
        dsa_state.stencil[1].valuemask = 0xff;
        dsa_state.stencil[1].writemask = 0xff;
    }

    ilo_blitter_set_invariants(blitter);
    ilo_blitter_set_op(blitter, ILO_BLITTER_RECTLIST_CLEAR_ZS);

    ilo_blitter_set_dsa(blitter, &dsa_state);
    ilo_blitter_set_clear_values(blitter, clear_value, (ubyte) stencil);
    ilo_blitter_set_fb_from_surface(blitter, zs);

    uses = ILO_BLITTER_USE_DSA;
    if (clear_flags & PIPE_CLEAR_DEPTH)
        uses |= ILO_BLITTER_USE_VIEWPORT | ILO_BLITTER_USE_FB_DEPTH;
    if (clear_flags & PIPE_CLEAR_STENCIL)
        uses |= ILO_BLITTER_USE_CC | ILO_BLITTER_USE_FB_STENCIL;
    ilo_blitter_set_uses(blitter, uses);

    hiz_emit_rectlist(blitter);

    return true;
}