static void init(void) { int fd = drmOpen("kgsl", NULL); drmSetMaster(fd); dev = fd_device_new(fd); pipe = fd_pipe_new(dev, FD_PIPE_2D); context_bos[0] = fd_bo_new(dev, 0x1000, DRM_FREEDRENO_GEM_TYPE_KMEM); context_bos[1] = fd_bo_new(dev, 0x9000, DRM_FREEDRENO_GEM_TYPE_KMEM); context_bos[2] = fd_bo_new(dev, 0x81000, DRM_FREEDRENO_GEM_TYPE_KMEM); next_ring(); ring_pre(ring); BEGIN_RING(8); OUT_RING (ring, REGM(VGV1_DIRTYBASE, 3)); OUT_RELOC (ring, context_bos[0]); /* VGV1_DIRTYBASE */ OUT_RELOC (ring, context_bos[1]); /* VGV1_CBASE1 */ OUT_RELOC (ring, context_bos[2]); /* VGV1_UBASE2 */ OUT_RING (ring, 0x11000000); OUT_RING (ring, 0x10fff000); OUT_RING (ring, 0x10ffffff); OUT_RING (ring, 0x0d000404); END_RING (); }
struct pipe_screen * fd_screen_create(struct fd_device *dev) { struct fd_screen *screen = CALLOC_STRUCT(fd_screen); struct pipe_screen *pscreen; uint64_t val; fd_mesa_debug = debug_get_option_fd_mesa_debug(); if (fd_mesa_debug & FD_DBG_NOBIN) fd_binning_enabled = false; glsl120 = !!(fd_mesa_debug & FD_DBG_GLSL120); if (!screen) return NULL; pscreen = &screen->base; screen->dev = dev; screen->refcnt = 1; // maybe this should be in context? screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D); if (!screen->pipe) { DBG("could not create 3d pipe"); goto fail; } if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) { DBG("could not get GMEM size"); goto fail; } screen->gmemsize_bytes = val; if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) { DBG("could not get device-id"); goto fail; } screen->device_id = val; if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) { DBG("could not get gpu-id"); goto fail; } screen->gpu_id = val; if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) { DBG("could not get chip-id"); /* older kernels may not have this property: */ unsigned core = screen->gpu_id / 100; unsigned major = (screen->gpu_id % 100) / 10; unsigned minor = screen->gpu_id % 10; unsigned patch = 0; /* assume the worst */ val = (patch & 0xff) | ((minor & 0xff) << 8) | ((major & 0xff) << 16) | ((core & 0xff) << 24); } screen->chip_id = val; DBG("Pipe Info:"); DBG(" GPU-id: %d", screen->gpu_id); DBG(" Chip-id: 0x%08x", screen->chip_id); DBG(" GMEM size: 0x%08x", screen->gmemsize_bytes); /* explicitly checking for GPU revisions that are known to work. This * may be overly conservative for a3xx, where spoofing the gpu_id with * the blob driver seems to generate identical cmdstream dumps. But * on a2xx, there seem to be small differences between the GPU revs * so it is probably better to actually test first on real hardware * before enabling: * * If you have a different adreno version, feel free to add it to one * of the cases below and see what happens. And if it works, please * send a patch ;-) */ switch (screen->gpu_id) { case 220: fd2_screen_init(pscreen); break; case 305: case 307: case 320: case 330: fd3_screen_init(pscreen); break; case 420: fd4_screen_init(pscreen); break; default: debug_printf("unsupported GPU: a%03d\n", screen->gpu_id); goto fail; } pscreen->destroy = fd_screen_destroy; pscreen->get_param = fd_screen_get_param; pscreen->get_paramf = fd_screen_get_paramf; pscreen->get_shader_param = fd_screen_get_shader_param; fd_resource_screen_init(pscreen); fd_query_screen_init(pscreen); pscreen->get_name = fd_screen_get_name; pscreen->get_vendor = fd_screen_get_vendor; pscreen->get_device_vendor = fd_screen_get_device_vendor; pscreen->get_timestamp = fd_screen_get_timestamp; pscreen->fence_reference = fd_screen_fence_ref; pscreen->fence_finish = fd_screen_fence_finish; util_format_s3tc_init(); return pscreen; fail: fd_screen_destroy(pscreen); return NULL; }
Bool MSMAccelInit(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); MSMPtr pMsm = MSMPTR(pScrn); Bool ret, softexa = FALSE; pMsm->pipe = fd_pipe_new(pMsm->dev, FD_PIPE_2D); #ifdef HAVE_XA if (!pMsm->pipe && !pMsm->NoAccel) { struct fd_pipe *p; INFO_MSG("no 2D, trying 3D/XA"); p = fd_pipe_new(pMsm->dev, FD_PIPE_3D); if (!p) { ERROR_MSG("no 3D pipe"); goto no_xa; } pMsm->xa = xa_tracker_create(pMsm->drmFD); if (!pMsm->xa) { ERROR_MSG("could not setup XA"); goto no_xa; } pMsm->pipe = p; INFO_MSG("using 3D/XA"); goto out; } no_xa: #endif if (!pMsm->pipe) { INFO_MSG("no 2D pipe, falling back to software!"); if (pMsm->NoKMS) { /* fbdev mode is lame.. we need a pipe, any pipe, to get a * bo for the scanout/fbdev buffer. So just do this instead * of special casing the PrepareAccess stuff for scanout bo: */ pMsm->pipe = fd_pipe_new(pMsm->dev, FD_PIPE_3D); } softexa = TRUE; goto out; } if (pMsm->NoAccel) { INFO_MSG("Acceleration disabled in config file"); softexa = TRUE; } out: #ifdef HAVE_XA if (pMsm->xa) ret = MSMSetupExaXA(pScreen); else #endif ret = MSMSetupExa(pScreen, softexa); if (ret) { pMsm->dri = MSMDRI2ScreenInit(pScreen); } return ret; }
struct pipe_screen * fd_screen_create(struct fd_device *dev) { struct fd_screen *screen = CALLOC_STRUCT(fd_screen); struct pipe_screen *pscreen; uint64_t val; fd_mesa_debug = debug_get_option_fd_mesa_debug(); if (fd_mesa_debug & FD_DBG_NOBIN) fd_binning_enabled = false; glsl120 = !!(fd_mesa_debug & FD_DBG_GLSL120); if (!screen) return NULL; pscreen = &screen->base; screen->dev = dev; screen->refcnt = 1; // maybe this should be in context? screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D); if (!screen->pipe) { DBG("could not create 3d pipe"); goto fail; } if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) { DBG("could not get GMEM size"); goto fail; } screen->gmemsize_bytes = val; if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) { DBG("could not get device-id"); goto fail; } screen->device_id = val; if (fd_pipe_get_param(screen->pipe, FD_MAX_FREQ, &val)) { DBG("could not get gpu freq"); /* this limits what performance related queries are * supported but is not fatal */ screen->max_freq = 0; } else { screen->max_freq = val; if (fd_pipe_get_param(screen->pipe, FD_TIMESTAMP, &val) == 0) screen->has_timestamp = true; } if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) { DBG("could not get gpu-id"); goto fail; } screen->gpu_id = val; if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) { DBG("could not get chip-id"); /* older kernels may not have this property: */ unsigned core = screen->gpu_id / 100; unsigned major = (screen->gpu_id % 100) / 10; unsigned minor = screen->gpu_id % 10; unsigned patch = 0; /* assume the worst */ val = (patch & 0xff) | ((minor & 0xff) << 8) | ((major & 0xff) << 16) | ((core & 0xff) << 24); } screen->chip_id = val; if (fd_pipe_get_param(screen->pipe, FD_NR_RINGS, &val)) { DBG("could not get # of rings"); screen->priority_mask = 0; } else { /* # of rings equates to number of unique priority values: */ screen->priority_mask = (1 << val) - 1; } struct sysinfo si; sysinfo(&si); screen->ram_size = si.totalram; DBG("Pipe Info:"); DBG(" GPU-id: %d", screen->gpu_id); DBG(" Chip-id: 0x%08x", screen->chip_id); DBG(" GMEM size: 0x%08x", screen->gmemsize_bytes); /* explicitly checking for GPU revisions that are known to work. This * may be overly conservative for a3xx, where spoofing the gpu_id with * the blob driver seems to generate identical cmdstream dumps. But * on a2xx, there seem to be small differences between the GPU revs * so it is probably better to actually test first on real hardware * before enabling: * * If you have a different adreno version, feel free to add it to one * of the cases below and see what happens. And if it works, please * send a patch ;-) */ switch (screen->gpu_id) { case 220: fd2_screen_init(pscreen); break; case 305: case 307: case 320: case 330: fd3_screen_init(pscreen); break; case 420: case 430: fd4_screen_init(pscreen); break; case 530: fd5_screen_init(pscreen); break; default: debug_printf("unsupported GPU: a%03d\n", screen->gpu_id); goto fail; } if (screen->gpu_id >= 500) { screen->gmem_alignw = 64; screen->gmem_alignh = 32; screen->num_vsc_pipes = 16; } else { screen->gmem_alignw = 32; screen->gmem_alignh = 32; screen->num_vsc_pipes = 8; } /* NOTE: don't enable reordering on a2xx, since completely untested. * Also, don't enable if we have too old of a kernel to support * growable cmdstream buffers, since memory requirement for cmdstream * buffers would be too much otherwise. */ if ((screen->gpu_id >= 300) && (fd_device_version(dev) >= FD_VERSION_UNLIMITED_CMDS)) screen->reorder = !(fd_mesa_debug & FD_DBG_INORDER); fd_bc_init(&screen->batch_cache); (void) mtx_init(&screen->lock, mtx_plain); pscreen->destroy = fd_screen_destroy; pscreen->get_param = fd_screen_get_param; pscreen->get_paramf = fd_screen_get_paramf; pscreen->get_shader_param = fd_screen_get_shader_param; pscreen->get_compute_param = fd_get_compute_param; pscreen->get_compiler_options = fd_get_compiler_options; fd_resource_screen_init(pscreen); fd_query_screen_init(pscreen); pscreen->get_name = fd_screen_get_name; pscreen->get_vendor = fd_screen_get_vendor; pscreen->get_device_vendor = fd_screen_get_device_vendor; pscreen->get_timestamp = fd_screen_get_timestamp; pscreen->fence_reference = fd_fence_ref; pscreen->fence_finish = fd_fence_finish; pscreen->fence_get_fd = fd_fence_get_fd; slab_create_parent(&screen->transfer_pool, sizeof(struct fd_transfer), 16); return pscreen; fail: fd_screen_destroy(pscreen); return NULL; }
int main(int argc, char *argv[]) { struct fd_device *dev; struct fd_pipe *pipe; struct fd_ringbuffer *ring; struct fd_bo *bo; uint32_t i = 0; uint32_t *ptr; int fd, ret; fd = drmOpen("msm", NULL); if (fd < 0) { printf("failed to initialize DRM\n"); return fd; } dev = fd_device_new(fd); if (!dev) { printf("failed to initialize freedreno device\n"); return -1; } pipe = fd_pipe_new(dev, FD_PIPE_3D); if (!pipe) { printf("failed to initialize freedreno pipe\n"); return -1; } ring = fd_ringbuffer_new(pipe, 4096); if (!ring) { printf("failed to initialize freedreno ring\n"); return -1; } bo = fd_bo_new(dev, 4096, 0); #define BASE REG_A3XX_GRAS_CL_VPORT_XOFFSET #define SIZE 6 OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG4, 1); OUT_RING(ring, 0x123); OUT_PKT0(ring, BASE, SIZE); for (i = 0; i < SIZE; i++) OUT_RING(ring, i); /* this adds the value of CP_SCRATCH_REG4 to 0x111 and writes * to REG_BASE+2 */ OUT_PKT3(ring, CP_SET_CONSTANT, 3); OUT_RING(ring, 0x80000000 | CP_REG(BASE + 2)); OUT_RING(ring, REG_AXXX_CP_SCRATCH_REG4); OUT_RING(ring, 0x111); /* read back all the regs: */ for (i = 0; i < SIZE; i++) { OUT_PKT3(ring, CP_REG_TO_MEM, 2); OUT_RING(ring, BASE + i); OUT_RELOCW(ring, bo, i * 4, 0, 0); } fd_ringbuffer_flush(ring); /* and read back the values: */ fd_bo_cpu_prep(bo, pipe, DRM_FREEDRENO_PREP_READ); ptr = fd_bo_map(bo); for (i = 0; i < SIZE; i++) { printf("%02x: %08x\n", i, ptr[i]); } fd_bo_cpu_fini(bo); return 0; }
struct pipe_screen * fd_screen_create(struct fd_device *dev) { struct fd_screen *screen = CALLOC_STRUCT(fd_screen); struct pipe_screen *pscreen; uint64_t val; fd_mesa_debug = debug_get_option_fd_mesa_debug(); if (!screen) return NULL; pscreen = &screen->base; screen->dev = dev; // maybe this should be in context? screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D); if (!screen->pipe) { DBG("could not create 3d pipe"); goto fail; } if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) { DBG("could not get GMEM size"); goto fail; } screen->gmemsize_bytes = val; if (fd_pipe_get_param(screen->pipe, FD_DEVICE_ID, &val)) { DBG("could not get device-id"); goto fail; } screen->device_id = val; if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) { DBG("could not get gpu-id"); goto fail; } screen->gpu_id = val; /* explicitly checking for GPU revisions that are known to work. This * may be overly conservative for a3xx, where spoofing the gpu_id with * the blob driver seems to generate identical cmdstream dumps. But * on a2xx, there seem to be small differences between the GPU revs * so it is probably better to actually test first on real hardware * before enabling: * * If you have a different adreno version, feel free to add it to one * of the two cases below and see what happens. And if it works, please * send a patch ;-) */ switch (screen->gpu_id) { case 220: fd2_screen_init(pscreen); break; case 320: fd3_screen_init(pscreen); break; default: debug_printf("unsupported GPU: a%03d\n", screen->gpu_id); goto fail; } pscreen->destroy = fd_screen_destroy; pscreen->get_param = fd_screen_get_param; pscreen->get_paramf = fd_screen_get_paramf; pscreen->get_shader_param = fd_screen_get_shader_param; fd_resource_screen_init(pscreen); pscreen->get_name = fd_screen_get_name; pscreen->get_vendor = fd_screen_get_vendor; pscreen->get_timestamp = fd_screen_get_timestamp; pscreen->fence_reference = fd_screen_fence_ref; pscreen->fence_signalled = fd_screen_fence_signalled; pscreen->fence_finish = fd_screen_fence_finish; util_format_s3tc_init(); return pscreen; fail: fd_screen_destroy(pscreen); return NULL; }