static struct pipe_resource * llvmpipe_resource_create(struct pipe_screen *_screen, const struct pipe_resource *templat) { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource); if (!lpr) return NULL; lpr->base = *templat; pipe_reference_init(&lpr->base.reference, 1); lpr->base.screen = &screen->base; /* assert(lpr->base.bind); */ if (resource_is_texture(&lpr->base)) { if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) { /* displayable surface */ if (!llvmpipe_displaytarget_layout(screen, lpr)) goto fail; assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE); } else { /* texture map */ if (!llvmpipe_texture_layout(screen, lpr)) goto fail; assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE); } assert(lpr->layout[0]); } else { /* other data (vertex buffer, const buffer, etc) */ const enum pipe_format format = templat->format; const uint w = templat->width0 / util_format_get_blockheight(format); /* XXX buffers should only have one dimension, those values should be 1 */ const uint h = templat->height0 / util_format_get_blockwidth(format); const uint d = templat->depth0; const uint bpp = util_format_get_blocksize(format); const uint bytes = w * h * d * bpp; lpr->data = align_malloc(bytes, 16); if (!lpr->data) goto fail; memset(lpr->data, 0, bytes); } lpr->id = id_counter++; #ifdef DEBUG insert_at_tail(&resource_list, lpr); #endif return &lpr->base; fail: FREE(lpr); return NULL; }
/** * Check the size of the texture specified by 'res'. * \return TRUE if OK, FALSE if too large. */ static boolean llvmpipe_can_create_resource(struct pipe_screen *screen, const struct pipe_resource *res) { struct llvmpipe_resource lpr; memset(&lpr, 0, sizeof(lpr)); lpr.base = *res; return llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr); }
static struct pipe_resource * llvmpipe_resource_create(struct pipe_screen *_screen, const struct pipe_resource *templat) { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource); if (!lpr) return NULL; lpr->base = *templat; pipe_reference_init(&lpr->base.reference, 1); lpr->base.screen = &screen->base; /* assert(lpr->base.bind); */ if (llvmpipe_resource_is_texture(&lpr->base)) { if (lpr->base.bind & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) { /* displayable surface */ if (!llvmpipe_displaytarget_layout(screen, lpr)) goto fail; } else { /* texture map */ if (!llvmpipe_texture_layout(screen, lpr)) goto fail; } } else { /* other data (vertex buffer, const buffer, etc) */ const uint bytes = templat->width0; assert(util_format_get_blocksize(templat->format) == 1); assert(templat->height0 == 1); assert(templat->depth0 == 1); assert(templat->last_level == 0); /* * Reserve some extra storage since if we'd render to a buffer we * read/write always LP_RASTER_BLOCK_SIZE pixels, but the element * offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE. */ lpr->data = align_malloc(bytes + (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float), 64); /* * buffers don't really have stride but it's probably safer * (for code doing same calculations for buffers and textures) * to put something sane in there. */ lpr->row_stride[0] = bytes; if (!lpr->data) goto fail; memset(lpr->data, 0, bytes); } lpr->id = id_counter++; #ifdef DEBUG insert_at_tail(&resource_list, lpr); #endif return &lpr->base; fail: FREE(lpr); return NULL; }