svga: Do a more propper creation of textures from handles

This commit is contained in:
Jakob Bornecrantz
2010-01-19 22:26:01 +01:00
parent c78fe6e050
commit bea9ed4dc6
3 changed files with 90 additions and 52 deletions
+65 -3
View File
@@ -308,11 +308,19 @@ svga_texture_create(struct pipe_screen *screen,
tex->key.numFaces = 1;
}
tex->key.cachable = 1;
if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
tex->key.cachable = 0;
}
if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
tex->key.cachable = 0;
}
/*
* XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
@@ -335,8 +343,6 @@ svga_texture_create(struct pipe_screen *screen,
if(tex->key.format == SVGA3D_FORMAT_INVALID)
goto error2;
tex->key.cachable = 1;
SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
if (tex->handle)
@@ -418,6 +424,62 @@ svga_texture_blanket(struct pipe_screen * screen,
}
struct pipe_texture *
svga_screen_texture_wrap_surface(struct pipe_screen *screen,
struct pipe_texture *base,
enum SVGA3dSurfaceFormat format,
struct svga_winsys_surface *srf)
{
struct svga_texture *tex;
assert(screen);
/* Only supports one type */
if (base->target != PIPE_TEXTURE_2D ||
base->last_level != 0 ||
base->depth[0] != 1) {
return NULL;
}
if (!srf)
return NULL;
if (svga_translate_format(base->format) != format) {
unsigned f1 = svga_translate_format(base->format);
unsigned f2 = format;
/* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
(f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
(f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
return NULL;
}
}
tex = CALLOC_STRUCT(svga_texture);
if (!tex)
return NULL;
tex->base = *base;
if (format == 1)
tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM;
else if (format == 2)
tex->base.format = PIPE_FORMAT_A8R8G8B8_UNORM;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf);
tex->key.cachable = 0;
tex->handle = srf;
return &tex->base;
}
static void
svga_texture_destroy(struct pipe_texture *pt)
{
+6
View File
@@ -296,4 +296,10 @@ svga_screen_buffer_from_texture(struct pipe_texture *texture,
struct pipe_buffer **buffer,
unsigned *stride);
struct pipe_texture *
svga_screen_texture_wrap_surface(struct pipe_screen *screen,
struct pipe_texture *base,
enum SVGA3dSurfaceFormat format,
struct svga_winsys_surface *srf);
#endif /* SVGA_WINSYS_H_ */
@@ -237,22 +237,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
vmw_svga_winsys_surface_reference(&vsrf, NULL);
}
/**
* FIXME: We'd probably want to cache these buffers in the
* screen, based on handle.
*/
static struct pipe_buffer *
vmw_drm_buffer_from_handle(struct drm_api *drm_api,
struct pipe_screen *screen,
const char *name,
unsigned handle)
static struct pipe_texture *
vmw_drm_texture_from_handle(struct drm_api *drm_api,
struct pipe_screen *screen,
struct pipe_texture *templat,
const char *name,
unsigned stride,
unsigned handle)
{
struct vmw_svga_winsys_surface *vsrf;
struct svga_winsys_surface *ssrf;
struct vmw_winsys_screen *vws =
vmw_winsys_screen(svga_winsys_screen(screen));
struct pipe_buffer *buf;
struct pipe_texture *tex;
union drm_vmw_surface_reference_arg arg;
struct drm_vmw_surface_arg *req = &arg.req;
struct drm_vmw_surface_create_req *rep = &arg.rep;
@@ -299,43 +296,28 @@ vmw_drm_buffer_from_handle(struct drm_api *drm_api,
pipe_reference_init(&vsrf->refcnt, 1);
p_atomic_set(&vsrf->validated, 0);
vsrf->screen = vws;
vsrf->sid = handle;
ssrf = svga_winsys_surface(vsrf);
buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf);
if (!buf)
tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf);
if (!tex)
vmw_svga_winsys_surface_reference(&vsrf, NULL);
return buf;
return tex;
out_mip:
vmw_ioctl_surface_destroy(vws, handle);
return NULL;
}
static struct pipe_texture *
vmw_drm_texture_from_handle(struct drm_api *drm_api,
struct pipe_screen *screen,
struct pipe_texture *templat,
const char *name,
unsigned stride,
unsigned handle)
{
struct pipe_buffer *buffer;
buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle);
if (!buffer)
return NULL;
return screen->texture_blanket(screen, templat, &stride, buffer);
}
static boolean
vmw_drm_handle_from_buffer(struct drm_api *drm_api,
vmw_drm_handle_from_texture(struct drm_api *drm_api,
struct pipe_screen *screen,
struct pipe_buffer *buffer,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle)
{
struct svga_winsys_surface *surface =
svga_screen_buffer_get_winsys_surface(buffer);
svga_screen_texture_get_winsys_surface(texture);
struct vmw_svga_winsys_surface *vsrf;
if (!surface)
@@ -343,25 +325,13 @@ vmw_drm_handle_from_buffer(struct drm_api *drm_api,
vsrf = vmw_svga_winsys_surface(surface);
*handle = vsrf->sid;
*stride = pf_get_nblocksx(&texture->block, texture->width[0]) *
texture->block.size;
vmw_svga_winsys_surface_reference(&vsrf, NULL);
return TRUE;
}
static boolean
vmw_drm_handle_from_texture(struct drm_api *drm_api,
struct pipe_screen *screen,
struct pipe_texture *texture,
unsigned *stride,
unsigned *handle)
{
struct pipe_buffer *buffer;
if (!svga_screen_buffer_from_texture(texture, &buffer, stride))
return FALSE;
return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle);
}
static struct pipe_context*
vmw_drm_create_context(struct drm_api *drm_api,
struct pipe_screen *screen)