Example #1
0
static void
parse_sublists(void)
{
        list_for_each_entry(struct vc4_mem_area_rec, rec, &dump.mem_areas,
                            link) {
                switch (rec->type) {
                case VC4_MEM_AREA_SUB_LIST:
                        printf("Sublist at 0x%08x:\n", rec->paddr);
                        if (!rec->addr) {
                                printf("    No mapping found\n");
                                continue;
                        }
                        vc4_dump_cl(rec->paddr, rec->paddr + rec->size, true,
                                    false, rec->prim_mode);
                        printf("\n");
                        break;
                case VC4_MEM_AREA_COMPRESSED_PRIM_LIST:
                        printf("Compressed list at 0x%08x:\n", rec->paddr);
                        if (!rec->addr) {
                                printf("    No mapping found\n");
                                continue;
                        }
                        vc4_dump_cl(rec->paddr, rec->paddr + rec->size, true,
                                    true, rec->prim_mode);
                        printf("\n");
                        break;
                default:
                        break;
                }
        }
}
Example #2
0
/**
 * Submits the job to the kernel and then reinitializes it.
 */
void
vc4_job_submit(struct vc4_context *vc4)
{
        if (vc4_debug & VC4_DEBUG_CL) {
                fprintf(stderr, "BCL:\n");
                vc4_dump_cl(vc4->bcl.base, vc4->bcl.next - vc4->bcl.base, false);
                fprintf(stderr, "RCL:\n");
                vc4_dump_cl(vc4->rcl.base, vc4->rcl.next - vc4->rcl.base, true);
        }

        struct drm_vc4_submit_cl submit;
        memset(&submit, 0, sizeof(submit));

        submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
        submit.bo_handle_count = (vc4->bo_handles.next -
                                  vc4->bo_handles.base) / 4;
        submit.bin_cl = (uintptr_t)vc4->bcl.base;
        submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base;
        submit.render_cl = (uintptr_t)vc4->rcl.base;
        submit.render_cl_size = vc4->rcl.next - vc4->rcl.base;
        submit.shader_rec = (uintptr_t)vc4->shader_rec.base;
        submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base;
        submit.shader_rec_count = vc4->shader_rec_count;
        submit.uniforms = (uintptr_t)vc4->uniforms.base;
        submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base;

        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
                int ret;

#ifndef USE_VC4_SIMULATOR
                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
#else
                ret = vc4_simulator_flush(vc4, &submit);
#endif
                if (ret) {
                        fprintf(stderr, "VC4 submit failed\n");
                        abort();
                }
        }

        vc4->last_emit_seqno = submit.seqno;

        if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) {
                if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno,
                                    PIPE_TIMEOUT_INFINITE)) {
                        fprintf(stderr, "Wait failed.\n");
                        abort();
                }
        }

        vc4_job_reset(vc4);
}
Example #3
0
static void
parse_cls(void)
{
        if (dump.state->start_bin != dump.state->ct0ea) {
                printf("Bin CL at 0x%08x\n", dump.state->start_bin);
                vc4_dump_cl(dump.state->start_bin, dump.state->ct0ea,
                            false, false, ~0);
        }

        printf("Render CL at 0x%08x\n", dump.state->start_render);
        vc4_dump_cl(dump.state->start_render, dump.state->ct1ea,
                    true, false, ~0);
}
/**
 * Submits the job to the kernel and then reinitializes it.
 */
void
vc4_job_submit(struct vc4_context *vc4)
{
        if (vc4_debug & VC4_DEBUG_CL) {
                fprintf(stderr, "BCL:\n");
                vc4_dump_cl(vc4->bcl.base, cl_offset(&vc4->bcl), false);
        }

        struct drm_vc4_submit_cl submit;
        memset(&submit, 0, sizeof(submit));

        cl_ensure_space(&vc4->bo_handles, 6 * sizeof(uint32_t));
        cl_ensure_space(&vc4->bo_pointers, 6 * sizeof(struct vc4_bo *));

        vc4_submit_setup_rcl_surface(vc4, &submit.color_read,
                                     vc4->color_read, false, false);
        vc4_submit_setup_rcl_render_config_surface(vc4, &submit.color_write,
                                                   vc4->color_write);
        vc4_submit_setup_rcl_surface(vc4, &submit.zs_read,
                                     vc4->zs_read, true, false);
        vc4_submit_setup_rcl_surface(vc4, &submit.zs_write,
                                     vc4->zs_write, true, true);

        vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_color_write,
                                          vc4->msaa_color_write);
        vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_zs_write,
                                          vc4->msaa_zs_write);

        if (vc4->msaa) {
                /* This bit controls how many pixels the general
                 * (i.e. subsampled) loads/stores are iterating over
                 * (multisample loads replicate out to the other samples).
                 */
                submit.color_write.bits |= VC4_RENDER_CONFIG_MS_MODE_4X;
                /* Controls whether color_write's
                 * VC4_PACKET_STORE_MS_TILE_BUFFER does 4x decimation
                 */
                submit.color_write.bits |= VC4_RENDER_CONFIG_DECIMATE_MODE_4X;
        }

        submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
        submit.bo_handle_count = cl_offset(&vc4->bo_handles) / 4;
        submit.bin_cl = (uintptr_t)vc4->bcl.base;
        submit.bin_cl_size = cl_offset(&vc4->bcl);
        submit.shader_rec = (uintptr_t)vc4->shader_rec.base;
        submit.shader_rec_size = cl_offset(&vc4->shader_rec);
        submit.shader_rec_count = vc4->shader_rec_count;
        submit.uniforms = (uintptr_t)vc4->uniforms.base;
        submit.uniforms_size = cl_offset(&vc4->uniforms);

        assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0);
        submit.min_x_tile = vc4->draw_min_x / vc4->tile_width;
        submit.min_y_tile = vc4->draw_min_y / vc4->tile_height;
        submit.max_x_tile = (vc4->draw_max_x - 1) / vc4->tile_width;
        submit.max_y_tile = (vc4->draw_max_y - 1) / vc4->tile_height;
        submit.width = vc4->draw_width;
        submit.height = vc4->draw_height;
        if (vc4->cleared) {
                submit.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR;
                submit.clear_color[0] = vc4->clear_color[0];
                submit.clear_color[1] = vc4->clear_color[1];
                submit.clear_z = vc4->clear_depth;
                submit.clear_s = vc4->clear_stencil;
        }

        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
                int ret;

#ifndef USE_VC4_SIMULATOR
                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
#else
                ret = vc4_simulator_flush(vc4, &submit);
#endif
                static bool warned = false;
                if (ret && !warned) {
                        fprintf(stderr, "Draw call returned %s.  "
                                        "Expect corruption.\n", strerror(errno));
                        warned = true;
                }
        }

        vc4->last_emit_seqno = submit.seqno;

        if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) {
                if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno,
                                    PIPE_TIMEOUT_INFINITE, "sync")) {
                        fprintf(stderr, "Wait failed.\n");
                        abort();
                }
        }

        vc4_job_reset(vc4);
}
Example #5
0
/**
 * Submits the job to the kernel and then reinitializes it.
 */
void
vc4_job_submit(struct vc4_context *vc4)
{
        if (vc4_debug & VC4_DEBUG_CL) {
                fprintf(stderr, "BCL:\n");
                vc4_dump_cl(vc4->bcl.base, cl_offset(&vc4->bcl), false);
        }

        struct drm_vc4_submit_cl submit;
        memset(&submit, 0, sizeof(submit));

        cl_ensure_space(&vc4->bo_handles, 4 * sizeof(uint32_t));
        cl_ensure_space(&vc4->bo_pointers, 4 * sizeof(struct vc4_bo *));

        vc4_submit_setup_rcl_surface(vc4, &submit.color_read,
                                     vc4->color_read, false, false);
        vc4_submit_setup_ms_rcl_surface(vc4, &submit.color_ms_write,
                                        vc4->color_write);
        vc4_submit_setup_rcl_surface(vc4, &submit.zs_read,
                                     vc4->zs_read, true, false);
        vc4_submit_setup_rcl_surface(vc4, &submit.zs_write,
                                     vc4->zs_write, true, true);

        submit.bo_handles = (uintptr_t)vc4->bo_handles.base;
        submit.bo_handle_count = cl_offset(&vc4->bo_handles) / 4;
        submit.bin_cl = (uintptr_t)vc4->bcl.base;
        submit.bin_cl_size = cl_offset(&vc4->bcl);
        submit.shader_rec = (uintptr_t)vc4->shader_rec.base;
        submit.shader_rec_size = cl_offset(&vc4->shader_rec);
        submit.shader_rec_count = vc4->shader_rec_count;
        submit.uniforms = (uintptr_t)vc4->uniforms.base;
        submit.uniforms_size = cl_offset(&vc4->uniforms);

        assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0);
        submit.min_x_tile = vc4->draw_min_x / 64;
        submit.min_y_tile = vc4->draw_min_y / 64;
        submit.max_x_tile = (vc4->draw_max_x - 1) / 64;
        submit.max_y_tile = (vc4->draw_max_y - 1) / 64;
        submit.width = vc4->draw_width;
        submit.height = vc4->draw_height;
        if (vc4->cleared) {
                submit.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR;
                submit.clear_color[0] = vc4->clear_color[0];
                submit.clear_color[1] = vc4->clear_color[1];
                submit.clear_z = vc4->clear_depth;
                submit.clear_s = vc4->clear_stencil;
        }

        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
                int ret;

#ifndef USE_VC4_SIMULATOR
                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
#else
                ret = vc4_simulator_flush(vc4, &submit);
#endif
                if (ret) {
                        fprintf(stderr, "VC4 submit failed\n");
                        abort();
                }
        }

        vc4->last_emit_seqno = submit.seqno;

        if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) {
                if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno,
                                    PIPE_TIMEOUT_INFINITE, "sync")) {
                        fprintf(stderr, "Wait failed.\n");
                        abort();
                }
        }

        vc4_job_reset(vc4);
}
int
vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args)
{
        struct vc4_screen *screen = vc4->screen;
        struct vc4_surface *csurf = vc4_surface(vc4->framebuffer.cbufs[0]);
        struct vc4_resource *ctex = csurf ? vc4_resource(csurf->base.texture) : NULL;
        uint32_t winsys_stride = ctex ? ctex->bo->simulator_winsys_stride : 0;
        uint32_t sim_stride = ctex ? ctex->slices[0].stride : 0;
        uint32_t row_len = MIN2(sim_stride, winsys_stride);
        struct exec_info exec;
        struct drm_device local_dev = {
                .vc4 = vc4,
                .simulator_mem_next = OVERFLOW_SIZE,
        };
        struct drm_device *dev = &local_dev;
        int ret;

        memset(&exec, 0, sizeof(exec));

        if (ctex && ctex->bo->simulator_winsys_map) {
#if 0
                fprintf(stderr, "%dx%d %d %d %d\n",
                        ctex->base.b.width0, ctex->base.b.height0,
                        winsys_stride,
                        sim_stride,
                        ctex->bo->size);
#endif

                for (int y = 0; y < ctex->base.b.height0; y++) {
                        memcpy(ctex->bo->map + y * sim_stride,
                               ctex->bo->simulator_winsys_map + y * winsys_stride,
                               row_len);
                }
        }

        exec.args = args;

        ret = vc4_simulator_pin_bos(dev, &exec);
        if (ret)
                return ret;

        ret = vc4_cl_validate(dev, &exec);
        if (ret)
                return ret;

        int bfc = simpenrose_do_binning(exec.ct0ca, exec.ct0ea);
        if (bfc != 1) {
                fprintf(stderr, "Binning returned %d flushes, should be 1.\n",
                        bfc);
                fprintf(stderr, "Relocated binning command list:\n");
                vc4_dump_cl(screen->simulator_mem_base + exec.ct0ca,
                            exec.ct0ea - exec.ct0ca, false);
                abort();
        }
        int rfc = simpenrose_do_rendering(exec.ct1ca, exec.ct1ea);
        if (rfc != 1) {
                fprintf(stderr, "Rendering returned %d frames, should be 1.\n",
                        rfc);
                fprintf(stderr, "Relocated render command list:\n");
                vc4_dump_cl(screen->simulator_mem_base + exec.ct1ca,
                            exec.ct1ea - exec.ct1ca, true);
                abort();
        }

        ret = vc4_simulator_unpin_bos(&exec);
        if (ret)
                return ret;

        vc4_bo_unreference(&exec.exec_bo->bo);
        free(exec.exec_bo);

        if (ctex && ctex->bo->simulator_winsys_map) {
                for (int y = 0; y < ctex->base.b.height0; y++) {
                        memcpy(ctex->bo->simulator_winsys_map + y * winsys_stride,
                               ctex->bo->map + y * sim_stride,
                               row_len);
                }
        }

        return 0;
}
Example #7
0
void
vc4_flush(struct pipe_context *pctx)
{
        struct vc4_context *vc4 = vc4_context(pctx);

        if (!vc4->needs_flush)
                return;

        /* The FLUSH caps all of our bin lists with a VC4_PACKET_RETURN. */
        cl_u8(&vc4->bcl, VC4_PACKET_FLUSH);

        cl_u8(&vc4->bcl, VC4_PACKET_NOP);
        cl_u8(&vc4->bcl, VC4_PACKET_HALT);

        vc4_setup_rcl(vc4);

        if (vc4_debug & VC4_DEBUG_CL) {
                fprintf(stderr, "BCL:\n");
                vc4_dump_cl(vc4->bcl.base, vc4->bcl.end - vc4->bcl.base, false);
                fprintf(stderr, "RCL:\n");
                vc4_dump_cl(vc4->rcl.base, vc4->rcl.end - vc4->rcl.base, true);
        }

        struct drm_vc4_submit_cl submit;
        memset(&submit, 0, sizeof(submit));

        submit.bo_handles = vc4->bo_handles.base;
        submit.bo_handle_count = (vc4->bo_handles.next -
                                  vc4->bo_handles.base) / 4;
        submit.bin_cl = vc4->bcl.base;
        submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base;
        submit.render_cl = vc4->rcl.base;
        submit.render_cl_size = vc4->rcl.next - vc4->rcl.base;
        submit.shader_rec = vc4->shader_rec.base;
        submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base;
        submit.shader_rec_count = vc4->shader_rec_count;
        submit.uniforms = vc4->uniforms.base;
        submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base;

        if (!(vc4_debug & VC4_DEBUG_NORAST)) {
                int ret;

#ifndef USE_VC4_SIMULATOR
                ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit);
#else
                ret = vc4_simulator_flush(vc4, &submit);
#endif
                if (ret) {
                        fprintf(stderr, "VC4 submit failed\n");
                        abort();
                }
        }

        vc4_reset_cl(&vc4->bcl);
        vc4_reset_cl(&vc4->rcl);
        vc4_reset_cl(&vc4->shader_rec);
        vc4_reset_cl(&vc4->uniforms);
        vc4_reset_cl(&vc4->bo_handles);
        struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
        for (int i = 0; i < submit.bo_handle_count; i++)
                vc4_bo_unreference(&referenced_bos[i]);
        vc4_reset_cl(&vc4->bo_pointers);
        vc4->shader_rec_count = 0;

        vc4->needs_flush = false;
        vc4->draw_call_queued = false;

        /* We have no hardware context saved between our draw calls, so we
         * need to flag the next draw as needing all state emitted.  Emitting
         * all state at the start of our draws is also what ensures that we
         * return to the state we need after a previous tile has finished.
         */
        vc4->dirty = ~0;
        vc4->resolve = 0;
        vc4->cleared = 0;
}