Commit 548a2f66 authored by Gert Wollny's avatar Gert Wollny
Browse files

Eriks patch to clean up formats.

parent f12b154f
......@@ -413,6 +413,15 @@ virgl_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
return 0.0;
}
static boolean
find_format(uint32_t bitmask[16], enum pipe_format format)
{
int big = format / 32;
int small = format % 32;
assert(big < 16);
return (bitmask[big] & (1 << small)) != 0;
}
static boolean
virgl_is_vertex_format_supported(struct pipe_screen *screen,
enum pipe_format format)
......@@ -426,12 +435,7 @@ virgl_is_vertex_format_supported(struct pipe_screen *screen,
return FALSE;
if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
int vformat = VIRGL_FORMAT_R11G11B10_FLOAT;
int big = vformat / 32;
int small = vformat % 32;
if (!(vscreen->caps.caps.v1.vertexbuffer.bitmask[big] & (1 << small)))
return FALSE;
return TRUE;
return find_format(vscreen->caps.caps.v1.vertexbuffer.bitmask, format);
}
/* Find the first non-VOID channel. */
......@@ -452,6 +456,37 @@ virgl_is_vertex_format_supported(struct pipe_screen *screen,
return TRUE;
}
static boolean
virgl_is_sampler_format_supported(struct pipe_screen *screen,
enum pipe_format format)
{
struct virgl_screen *vscreen = virgl_screen(screen);
return find_format(vscreen->caps.caps.v1.sampler.bitmask, format);
}
static boolean
virgl_is_render_target_format_supported(struct pipe_screen *screen,
enum pipe_format format)
{
struct virgl_screen *vscreen = virgl_screen(screen);
return find_format(vscreen->caps.caps.v1.render.bitmask, format);
}
static boolean
virgl_is_depth_stencil_format_supported(struct pipe_screen *screen,
enum pipe_format format)
{
struct virgl_screen *vscreen = virgl_screen(screen);
if (vscreen->depthstencil_caps_valid)
return find_format(vscreen->caps.caps.v1.depthstencil.bitmask, format);
else
return find_format(vscreen->caps.caps.v1.sampler.bitmask, format);
}
/**
* Query format support for creating a texture, drawing surface, etc.
* \param format the format to test
......@@ -482,6 +517,9 @@ virgl_is_format_supported( struct pipe_screen *screen,
if (!format_desc)
return FALSE;
if (format == PIPE_FORMAT_R11G11B10_FLOAT)
return find_format(vscreen->caps.caps.v1.vertexbuffer.bitmask, format);
if (util_format_is_intensity(format))
return FALSE;
......@@ -492,11 +530,10 @@ virgl_is_format_supported( struct pipe_screen *screen,
return FALSE;
}
if (bind & PIPE_BIND_VERTEX_BUFFER) {
if (bind & PIPE_BIND_VERTEX_BUFFER)
return virgl_is_vertex_format_supported(screen, format);
}
if (bind & PIPE_BIND_RENDER_TARGET) {
if ((bind & PIPE_BIND_RENDER_TARGET) | (bind & PIPE_BIND_DISPLAY_TARGET)) {
if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
......@@ -509,60 +546,40 @@ virgl_is_format_supported( struct pipe_screen *screen,
format_desc->block.height != 1)
return FALSE;
{
int big = format / 32;
int small = format % 32;
if (!(vscreen->caps.caps.v1.render.bitmask[big] & (1 << small)))
return FALSE;
}
if (!virgl_is_render_target_format_supported(screen, format))
return FALSE;
}
if (bind & PIPE_BIND_DEPTH_STENCIL) {
if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
if (!virgl_is_depth_stencil_format_supported(screen, format))
return FALSE;
}
/*
* All other operations (sampling, transfer, etc).
*/
if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
goto out_lookup;
}
if (format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
goto out_lookup;
}
if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
goto out_lookup;
}
if (format == PIPE_FORMAT_R11G11B10_FLOAT) {
goto out_lookup;
} else if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
goto out_lookup;
}
/* Find the first non-VOID channel. */
for (i = 0; i < 4; i++) {
if (format_desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
break;
if (!util_format_is_compressed(format) &&
format != PIPE_FORMAT_R11G11B10_FLOAT &&
format != PIPE_FORMAT_R9G9B9E5_FLOAT) {
for (i = 0; i < 4; i++) {
if (format_desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
break;
}
}
}
if (i == 4)
return FALSE;
/* no L4A4 */
if (format_desc->nr_channels < 4 && format_desc->channel[i].size == 4)
return FALSE;
if (i == 4)
return FALSE;
out_lookup:
{
int big = format / 32;
int small = format % 32;
if (!(vscreen->caps.caps.v1.sampler.bitmask[big] & (1 << small)))
if (format_desc->nr_channels < 4 && format_desc->channel[i].size == 4)
return FALSE;
}
if (!virgl_is_sampler_format_supported(screen, format))
return FALSE;
/*
* Everything else should be supported by u_format.
*/
......@@ -626,6 +643,7 @@ virgl_destroy_screen(struct pipe_screen *screen)
struct pipe_screen *
virgl_create_screen(struct virgl_winsys *vws)
{
int i;
struct virgl_screen *screen = CALLOC_STRUCT(virgl_screen);
if (!screen)
......@@ -650,6 +668,12 @@ virgl_create_screen(struct virgl_winsys *vws)
vws->get_caps(vws, &screen->caps);
for (i = 0; i < 16; ++i)
if (screen->caps.caps.v1.depthstencil.bitmask[i] != 0) {
screen->depthstencil_caps_valid = true;
break;
}
screen->refcnt = 1;
slab_create_parent(&screen->texture_transfer_pool, sizeof(struct virgl_transfer), 16);
......
......@@ -39,6 +39,8 @@ struct virgl_screen {
struct virgl_drm_caps caps;
bool depthstencil_caps_valid;
struct slab_parent_pool texture_transfer_pool;
uint32_t sub_ctx_id;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment