svga: Do a more propper creation of textures from handles
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user