glamor: Introduce a central place for our pixmap format/type handling.
We had various helper functions trying to come up with the internalformat/format/type/render formats for pixmaps, and it's much nicer to just detect what those should be once at startup. This gives us a chance to do the right thing for GLES. It also, notably, fixes our format/type for depth 15 and 16 setup for desktop GL, so that we actually allocate 16bpp (GL_RGB/565) on most drivers instead of 32bpp (GL_RGB/UBYTE). GLES still has regressions over desktop (2 regressions in llvmpipe XTS, many in rendercheck), but I think this is a good baseline. Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
c94da112a7
commit
8702c938b3
167
glamor/glamor.c
167
glamor/glamor.c
|
@ -197,7 +197,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
|
||||||
w <= glamor_priv->glyph_max_dim &&
|
w <= glamor_priv->glyph_max_dim &&
|
||||||
h <= glamor_priv->glyph_max_dim)
|
h <= glamor_priv->glyph_max_dim)
|
||||||
|| (w == 0 && h == 0)
|
|| (w == 0 && h == 0)
|
||||||
|| !glamor_check_pixmap_fbo_depth(depth)))
|
|| !glamor_priv->formats[depth].format))
|
||||||
return fbCreatePixmap(screen, w, h, depth, usage);
|
return fbCreatePixmap(screen, w, h, depth, usage);
|
||||||
else
|
else
|
||||||
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
|
pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
|
||||||
|
@ -425,6 +425,165 @@ glamor_setup_debug_output(ScreenPtr screen)
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct glamor_format *
|
||||||
|
glamor_format_for_pixmap(PixmapPtr pixmap)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pixmap->drawable.pScreen;
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
|
||||||
|
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
|
||||||
|
if (pixmap_priv->is_cbcr)
|
||||||
|
return &glamor_priv->cbcr_format;
|
||||||
|
else
|
||||||
|
return &glamor_priv->formats[pixmap->drawable.depth];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
|
||||||
|
GLenum internalformat, GLenum format, GLenum type)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
struct glamor_format *f = &glamor_priv->formats[depth];
|
||||||
|
|
||||||
|
/* If we're trying to run on GLES, make sure that we get the read
|
||||||
|
* formats that we're expecting, since glamor_transfer relies on
|
||||||
|
* them matching to get data back out. To avoid this limitation, we
|
||||||
|
* would need to have a more general glReadPixels() path in
|
||||||
|
* glamor_transfer that re-encoded the bits to the pixel format that
|
||||||
|
* we intended after.
|
||||||
|
*
|
||||||
|
* Note that we can't just create a pixmap because we're in
|
||||||
|
* screeninit.
|
||||||
|
*/
|
||||||
|
if (glamor_priv->is_gles) {
|
||||||
|
unsigned fbo, tex;
|
||||||
|
int read_format, read_type;
|
||||||
|
GLenum status;
|
||||||
|
|
||||||
|
glGenTextures(1, &tex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0,
|
||||||
|
format, type, NULL);
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_TEXTURE_2D, tex, 0);
|
||||||
|
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
ErrorF("glamor: Test fbo for depth %d incomplete. "
|
||||||
|
"Falling back to software.\n", depth);
|
||||||
|
glDeleteTextures(1, &tex);
|
||||||
|
glDeleteFramebuffers(1, &fbo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
|
||||||
|
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
|
||||||
|
|
||||||
|
glDeleteTextures(1, &tex);
|
||||||
|
glDeleteFramebuffers(1, &fbo);
|
||||||
|
|
||||||
|
if (format != read_format || type != read_type) {
|
||||||
|
ErrorF("glamor: Implementation returned 0x%x/0x%x read format/type "
|
||||||
|
"for depth %d, expected 0x%x/0x%x. "
|
||||||
|
"Falling back to software.\n",
|
||||||
|
read_format, read_type, depth, format, type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f->depth = depth;
|
||||||
|
f->render_format = render_format;
|
||||||
|
f->internalformat = internalformat;
|
||||||
|
f->format = format;
|
||||||
|
f->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the GL format/types that glamor will use for the various depths
|
||||||
|
*
|
||||||
|
* X11's pixel data doesn't have channels, but to store our data in GL
|
||||||
|
* we have to pick some sort of format to move X11 pixel data in and
|
||||||
|
* out with in glamor_transfer.c. For X11 core operations, other than
|
||||||
|
* GL logic ops (non-GXcopy GC ops) what the driver chooses internally
|
||||||
|
* doesn't matter as long as it doesn't drop any bits (we expect them
|
||||||
|
* to generally expand, if anything). For Render, we can expect
|
||||||
|
* clients to tend to render with PictFormats matching our channel
|
||||||
|
* layouts here since ultimately X11 pixels tend to end up on the
|
||||||
|
* screen. The render implementation will fall back to fb if the
|
||||||
|
* channels don't match.
|
||||||
|
*
|
||||||
|
* Note that these formats don't affect what glamor_egl.c or
|
||||||
|
* Xwayland's EGL layer choose for surfaces exposed through DRI or
|
||||||
|
* scanout. For now, those layers need to match what we're choosing
|
||||||
|
* here, or channels will end up swizzled around. Similarly, the
|
||||||
|
* driver's visual masks also need to match what we're doing here.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
glamor_setup_formats(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
|
||||||
|
/* Prefer r8 textures since they're required by GLES3 and core,
|
||||||
|
* only falling back to a8 if we can't do them.
|
||||||
|
*/
|
||||||
|
if (glamor_priv->is_gles || epoxy_has_gl_extension("GL_ARB_texture_rg")) {
|
||||||
|
glamor_add_format(screen, 8, PICT_a8,
|
||||||
|
GL_R8, GL_RED, GL_UNSIGNED_BYTE);
|
||||||
|
} else {
|
||||||
|
glamor_add_format(screen, 8, PICT_a8,
|
||||||
|
GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glamor_priv->is_gles) {
|
||||||
|
/* For 15bpp, GLES supports format/type RGBA/5551, rather than
|
||||||
|
* bgra/1555_rev. GL_EXT_bgra lets the impl say the color
|
||||||
|
* read format/type is bgra/1555 even if we had to create it
|
||||||
|
* with rgba/5551, with Mesa does. That means we can't use
|
||||||
|
* the same format/type for TexSubImage and readpixels.
|
||||||
|
*
|
||||||
|
* Instead, just store 16 bits using the trusted 565 path, and
|
||||||
|
* disable render accel for now.
|
||||||
|
*/
|
||||||
|
glamor_add_format(screen, 15, PICT_x1r5g5b5,
|
||||||
|
GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
|
||||||
|
} else {
|
||||||
|
glamor_add_format(screen, 15, PICT_x1r5g5b5,
|
||||||
|
GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_add_format(screen, 16, PICT_r5g6b5,
|
||||||
|
GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
|
||||||
|
|
||||||
|
if (glamor_priv->is_gles) {
|
||||||
|
assert(X_BYTE_ORDER == X_LITTLE_ENDIAN);
|
||||||
|
glamor_add_format(screen, 24, PICT_x8b8g8r8,
|
||||||
|
GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||||
|
glamor_add_format(screen, 32, PICT_a8b8g8r8,
|
||||||
|
GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||||
|
} else {
|
||||||
|
glamor_add_format(screen, 24, PICT_x8r8g8b8,
|
||||||
|
GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
|
||||||
|
glamor_add_format(screen, 32, PICT_a8r8g8b8,
|
||||||
|
GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glamor_priv->is_gles) {
|
||||||
|
glamor_add_format(screen, 30, PICT_x2b10g10r10,
|
||||||
|
GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
|
||||||
|
} else {
|
||||||
|
glamor_add_format(screen, 30, PICT_x2r10g10b10,
|
||||||
|
GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV);
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_priv->cbcr_format.depth = 16;
|
||||||
|
glamor_priv->cbcr_format.internalformat = GL_RG8;
|
||||||
|
glamor_priv->cbcr_format.format = GL_RG;
|
||||||
|
glamor_priv->cbcr_format.type = GL_UNSIGNED_BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
/** Set up glamor for an already-configured GL context. */
|
/** Set up glamor for an already-configured GL context. */
|
||||||
Bool
|
Bool
|
||||||
glamor_init(ScreenPtr screen, unsigned int flags)
|
glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
|
@ -649,11 +808,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
(epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
|
(epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
|
||||||
(glamor_priv->is_gles && gl_version >= 30));
|
(glamor_priv->is_gles && gl_version >= 30));
|
||||||
|
|
||||||
glamor_priv->one_channel_format = GL_ALPHA;
|
glamor_setup_formats(screen);
|
||||||
if (epoxy_has_gl_extension("GL_ARB_texture_rg") &&
|
|
||||||
glamor_priv->has_texture_swizzle) {
|
|
||||||
glamor_priv->one_channel_format = GL_RED;
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_set_debug_level(&glamor_debug_level);
|
glamor_set_debug_level(&glamor_debug_level);
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ glamor_pixmap_fbo *
|
||||||
glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
|
glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
|
||||||
PixmapPtr pixmap, int w, int h, GLint tex, int flag)
|
PixmapPtr pixmap, int w, int h, GLint tex, int flag)
|
||||||
{
|
{
|
||||||
GLenum format = gl_iformat_for_pixmap(pixmap);
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
glamor_pixmap_fbo *fbo;
|
glamor_pixmap_fbo *fbo;
|
||||||
|
|
||||||
fbo = calloc(1, sizeof(*fbo));
|
fbo = calloc(1, sizeof(*fbo));
|
||||||
|
@ -107,7 +107,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
|
||||||
fbo->tex = tex;
|
fbo->tex = tex;
|
||||||
fbo->width = w;
|
fbo->width = w;
|
||||||
fbo->height = h;
|
fbo->height = h;
|
||||||
fbo->is_red = format == GL_RED;
|
fbo->is_red = f->format == GL_RED;
|
||||||
|
|
||||||
if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
|
if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
|
||||||
if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
|
if (glamor_pixmap_ensure_fb(glamor_priv, fbo) != 0) {
|
||||||
|
@ -123,23 +123,19 @@ static int
|
||||||
_glamor_create_tex(glamor_screen_private *glamor_priv,
|
_glamor_create_tex(glamor_screen_private *glamor_priv,
|
||||||
PixmapPtr pixmap, int w, int h)
|
PixmapPtr pixmap, int w, int h)
|
||||||
{
|
{
|
||||||
GLenum iformat = gl_iformat_for_pixmap(pixmap);
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
GLenum format = iformat;
|
|
||||||
unsigned int tex;
|
unsigned int tex;
|
||||||
|
|
||||||
if (format == GL_RGB10_A2)
|
|
||||||
format = GL_RGBA;
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
glGenTextures(1, &tex);
|
glGenTextures(1, &tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
if (format == glamor_priv->one_channel_format && format == GL_RED)
|
if (f->format == GL_RED)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
|
||||||
glamor_priv->suppress_gl_out_of_memory_logging = true;
|
glamor_priv->suppress_gl_out_of_memory_logging = true;
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, f->internalformat, w, h, 0,
|
||||||
format, GL_UNSIGNED_BYTE, NULL);
|
f->format, f->type, NULL);
|
||||||
glamor_priv->suppress_gl_out_of_memory_logging = false;
|
glamor_priv->suppress_gl_out_of_memory_logging = false;
|
||||||
|
|
||||||
if (glGetError() == GL_OUT_OF_MEMORY) {
|
if (glGetError() == GL_OUT_OF_MEMORY) {
|
||||||
|
|
|
@ -83,7 +83,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case PICT_a1:
|
case PICT_a1:
|
||||||
*tex_format = glamor_priv->one_channel_format;
|
*tex_format = glamor_priv->formats[1].format;
|
||||||
*tex_type = GL_UNSIGNED_BYTE;
|
*tex_type = GL_UNSIGNED_BYTE;
|
||||||
*temp_format = PICT_a8;
|
*temp_format = PICT_a8;
|
||||||
break;
|
break;
|
||||||
|
@ -195,7 +195,7 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PICT_a8:
|
case PICT_a8:
|
||||||
*tex_format = glamor_priv->one_channel_format;
|
*tex_format = glamor_priv->formats[8].format;
|
||||||
*tex_type = GL_UNSIGNED_BYTE;
|
*tex_type = GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -286,6 +286,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
|
||||||
Bool ret = TRUE;
|
Bool ret = TRUE;
|
||||||
Bool needs_swizzle;
|
Bool needs_swizzle;
|
||||||
pixman_image_t *converted_image = NULL;
|
pixman_image_t *converted_image = NULL;
|
||||||
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
|
|
||||||
assert(glamor_pixmap_is_memory(pixmap));
|
assert(glamor_pixmap_is_memory(pixmap));
|
||||||
assert(!pixmap_priv->fbo);
|
assert(!pixmap_priv->fbo);
|
||||||
|
@ -336,7 +337,7 @@ glamor_upload_picture_to_texture(PicturePtr picture)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!glamor_priv->is_gles)
|
if (!glamor_priv->is_gles)
|
||||||
iformat = gl_iformat_for_pixmap(pixmap);
|
iformat = f->internalformat;
|
||||||
else
|
else
|
||||||
iformat = format;
|
iformat = format;
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,21 @@ struct glamor_pixmap_private;
|
||||||
|
|
||||||
#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
|
#define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024)
|
||||||
|
|
||||||
|
struct glamor_format {
|
||||||
|
/** X Server's "depth" value */
|
||||||
|
int depth;
|
||||||
|
/** GL internalformat for creating textures of this type */
|
||||||
|
GLenum internalformat;
|
||||||
|
/** GL format transferring pixels in/out of textures of this type. */
|
||||||
|
GLenum format;
|
||||||
|
/** GL type transferring pixels in/out of textures of this type. */
|
||||||
|
GLenum type;
|
||||||
|
/* Render PICT_* matching GL's channel layout for pixels
|
||||||
|
* transferred using format/type.
|
||||||
|
*/
|
||||||
|
CARD32 render_format;
|
||||||
|
};
|
||||||
|
|
||||||
struct glamor_saved_procs {
|
struct glamor_saved_procs {
|
||||||
CloseScreenProcPtr close_screen;
|
CloseScreenProcPtr close_screen;
|
||||||
CreateGCProcPtr create_gc;
|
CreateGCProcPtr create_gc;
|
||||||
|
@ -198,7 +213,8 @@ typedef struct glamor_screen_private {
|
||||||
Bool can_copyplane;
|
Bool can_copyplane;
|
||||||
int max_fbo_size;
|
int max_fbo_size;
|
||||||
|
|
||||||
GLuint one_channel_format;
|
struct glamor_format formats[33];
|
||||||
|
struct glamor_format cbcr_format;
|
||||||
|
|
||||||
/* glamor point shader */
|
/* glamor point shader */
|
||||||
glamor_program point_prog;
|
glamor_program point_prog;
|
||||||
|
@ -535,6 +551,8 @@ void glamor_destroy_fbo(glamor_screen_private *glamor_priv,
|
||||||
void glamor_pixmap_destroy_fbo(PixmapPtr pixmap);
|
void glamor_pixmap_destroy_fbo(PixmapPtr pixmap);
|
||||||
Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
|
Bool glamor_pixmap_fbo_fixup(ScreenPtr screen, PixmapPtr pixmap);
|
||||||
|
|
||||||
|
const struct glamor_format *glamor_format_for_pixmap(PixmapPtr pixmap);
|
||||||
|
|
||||||
/* Return whether 'picture' is alpha-only */
|
/* Return whether 'picture' is alpha-only */
|
||||||
static inline Bool glamor_picture_is_alpha(PicturePtr picture)
|
static inline Bool glamor_picture_is_alpha(PicturePtr picture)
|
||||||
{
|
{
|
||||||
|
@ -547,7 +565,7 @@ glamor_picture_red_is_alpha(PicturePtr picture)
|
||||||
{
|
{
|
||||||
/* True when the picture is alpha only and the screen is using GL_RED for alpha pictures */
|
/* True when the picture is alpha only and the screen is using GL_RED for alpha pictures */
|
||||||
return glamor_picture_is_alpha(picture) &&
|
return glamor_picture_is_alpha(picture) &&
|
||||||
glamor_get_screen_private(picture->pDrawable->pScreen)->one_channel_format == GL_RED;
|
glamor_get_screen_private(picture->pDrawable->pScreen)->formats[8].format == GL_RED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void glamor_bind_texture(glamor_screen_private *glamor_priv,
|
void glamor_bind_texture(glamor_screen_private *glamor_priv,
|
||||||
|
|
|
@ -772,12 +772,15 @@ static Bool
|
||||||
glamor_render_format_is_supported(PicturePtr picture)
|
glamor_render_format_is_supported(PicturePtr picture)
|
||||||
{
|
{
|
||||||
PictFormatShort storage_format;
|
PictFormatShort storage_format;
|
||||||
|
glamor_screen_private *glamor_priv;
|
||||||
|
|
||||||
/* Source-only pictures should always work */
|
/* Source-only pictures should always work */
|
||||||
if (!picture->pDrawable)
|
if (!picture->pDrawable)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
storage_format = format_for_depth(picture->pDrawable->depth);
|
glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
|
||||||
|
storage_format =
|
||||||
|
glamor_priv->formats[picture->pDrawable->depth].render_format;
|
||||||
|
|
||||||
switch (picture->format) {
|
switch (picture->format) {
|
||||||
case PICT_a2r10g10b10:
|
case PICT_a2r10g10b10:
|
||||||
|
@ -898,7 +901,7 @@ glamor_composite_choose_shader(CARD8 op,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
|
if (dest_pixmap->drawable.bitsPerPixel <= 8 &&
|
||||||
glamor_priv->one_channel_format == GL_RED) {
|
glamor_priv->formats[8].format == GL_RED) {
|
||||||
key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED;
|
key.dest_swizzle = SHADER_DEST_SWIZZLE_ALPHA_TO_RED;
|
||||||
} else {
|
} else {
|
||||||
key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT;
|
key.dest_swizzle = SHADER_DEST_SWIZZLE_DEFAULT;
|
||||||
|
|
|
@ -187,9 +187,8 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
|
||||||
int box_index;
|
int box_index;
|
||||||
int n;
|
int n;
|
||||||
char *d;
|
char *d;
|
||||||
GLenum type;
|
|
||||||
GLenum format;
|
|
||||||
int off_x, off_y;
|
int off_x, off_y;
|
||||||
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
|
||||||
|
@ -197,8 +196,6 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
|
||||||
|
|
||||||
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||||
|
|
||||||
glamor_format_for_pixmap(pixmap, &format, &type);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
glamor_pixmap_loop(pixmap_priv, box_index) {
|
glamor_pixmap_loop(pixmap_priv, box_index) {
|
||||||
|
@ -234,7 +231,8 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
|
||||||
if (y >= box->y2)
|
if (y >= box->y2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glReadPixels(x1 - box->x1, y - box->y1, x2 - x1, 1, format, type, l);
|
glReadPixels(x1 - box->x1, y - box->y1, x2 - x1, 1,
|
||||||
|
f->format, f->type, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,11 +267,10 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
glamor_pixmap_private *pixmap_priv;
|
glamor_pixmap_private *pixmap_priv;
|
||||||
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
int box_index;
|
int box_index;
|
||||||
int n;
|
int n;
|
||||||
char *s;
|
char *s;
|
||||||
GLenum type;
|
|
||||||
GLenum format;
|
|
||||||
int off_x, off_y;
|
int off_x, off_y;
|
||||||
|
|
||||||
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
|
@ -287,7 +284,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
|
||||||
glamor_format_for_pixmap(pixmap, &format, &type);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
@ -348,7 +344,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
|
||||||
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
x1 - box->x1, y1 - box->y1, x2 - x1, 1,
|
x1 - box->x1, y1 - box->y1, x2 - x1, 1,
|
||||||
format, type,
|
f->format, f->type,
|
||||||
l);
|
l);
|
||||||
}
|
}
|
||||||
s += PixmapBytePad(w, drawable->depth);
|
s += PixmapBytePad(w, drawable->depth);
|
||||||
|
|
|
@ -23,44 +23,6 @@
|
||||||
#include "glamor_priv.h"
|
#include "glamor_priv.h"
|
||||||
#include "glamor_transfer.h"
|
#include "glamor_transfer.h"
|
||||||
|
|
||||||
/* XXX a kludge for now */
|
|
||||||
void
|
|
||||||
glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type)
|
|
||||||
{
|
|
||||||
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
switch (pixmap->drawable.depth) {
|
|
||||||
case 24:
|
|
||||||
case 32:
|
|
||||||
*format = GL_BGRA;
|
|
||||||
*type = GL_UNSIGNED_INT_8_8_8_8_REV;
|
|
||||||
break;
|
|
||||||
case 30:
|
|
||||||
*format = GL_BGRA;
|
|
||||||
*type = GL_UNSIGNED_INT_2_10_10_10_REV;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
if (priv->is_cbcr) {
|
|
||||||
*format = GL_RG;
|
|
||||||
*type = GL_UNSIGNED_BYTE;
|
|
||||||
} else {
|
|
||||||
*format = GL_RGB;
|
|
||||||
*type = GL_UNSIGNED_SHORT_5_6_5;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
*format = GL_BGRA;
|
|
||||||
*type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
*format = glamor_get_screen_private(pixmap->drawable.pScreen)->one_channel_format;
|
|
||||||
*type = GL_UNSIGNED_BYTE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FatalError("Invalid pixmap depth %d\n", pixmap->drawable.depth);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write a region of bits into a pixmap
|
* Write a region of bits into a pixmap
|
||||||
*/
|
*/
|
||||||
|
@ -75,10 +37,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
||||||
int box_index;
|
int box_index;
|
||||||
int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
|
int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
|
||||||
GLenum type;
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
GLenum format;
|
|
||||||
|
|
||||||
glamor_format_for_pixmap(pixmap, &format, &type);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
@ -116,14 +75,14 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
x1 - box->x1, y1 - box->y1,
|
x1 - box->x1, y1 - box->y1,
|
||||||
x2 - x1, y2 - y1,
|
x2 - x1, y2 - y1,
|
||||||
format, type,
|
f->format, f->type,
|
||||||
bits + ofs);
|
bits + ofs);
|
||||||
} else {
|
} else {
|
||||||
for (; y1 < y2; y1++, ofs += byte_stride)
|
for (; y1 < y2; y1++, ofs += byte_stride)
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
x1 - box->x1, y1 - box->y1,
|
x1 - box->x1, y1 - box->y1,
|
||||||
x2 - x1, 1,
|
x2 - x1, 1,
|
||||||
format, type,
|
f->format, f->type,
|
||||||
bits + ofs);
|
bits + ofs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,10 +137,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
|
||||||
int box_index;
|
int box_index;
|
||||||
int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
|
int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
|
||||||
GLenum type;
|
const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
|
||||||
GLenum format;
|
|
||||||
|
|
||||||
glamor_format_for_pixmap(pixmap, &format, &type);
|
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
||||||
|
@ -216,10 +172,10 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
|
|
||||||
if (glamor_priv->has_pack_subimage ||
|
if (glamor_priv->has_pack_subimage ||
|
||||||
x2 - x1 == byte_stride / bytes_per_pixel) {
|
x2 - x1 == byte_stride / bytes_per_pixel) {
|
||||||
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
|
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, f->format, f->type, bits + ofs);
|
||||||
} else {
|
} else {
|
||||||
for (; y1 < y2; y1++, ofs += byte_stride)
|
for (; y1 < y2; y1++, ofs += byte_stride)
|
||||||
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
|
glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, f->format, f->type, bits + ofs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,6 @@
|
||||||
#ifndef _GLAMOR_TRANSFER_H_
|
#ifndef _GLAMOR_TRANSFER_H_
|
||||||
#define _GLAMOR_TRANSFER_H_
|
#define _GLAMOR_TRANSFER_H_
|
||||||
|
|
||||||
void
|
|
||||||
glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
|
||||||
int dx_src, int dy_src,
|
int dx_src, int dy_src,
|
||||||
|
|
|
@ -121,10 +121,9 @@ glamor_set_color_depth(ScreenPtr pScreen,
|
||||||
|
|
||||||
glamor_get_rgba_from_pixel(pixel,
|
glamor_get_rgba_from_pixel(pixel,
|
||||||
&color[0], &color[1], &color[2], &color[3],
|
&color[0], &color[1], &color[2], &color[3],
|
||||||
format_for_depth(depth));
|
glamor_priv->formats[depth].render_format);
|
||||||
|
|
||||||
if ((depth == 1 || depth == 8) &&
|
if ((depth <= 8) && glamor_priv->formats[8].format == GL_RED)
|
||||||
glamor_priv->one_channel_format == GL_RED)
|
|
||||||
color[0] = color[3];
|
color[0] = color[3];
|
||||||
|
|
||||||
glUniform4fv(uniform, 1, color);
|
glUniform4fv(uniform, 1, color);
|
||||||
|
|
|
@ -570,65 +570,8 @@
|
||||||
&& (_w_) <= _glamor_->max_fbo_size \
|
&& (_w_) <= _glamor_->max_fbo_size \
|
||||||
&& (_h_) <= _glamor_->max_fbo_size)
|
&& (_h_) <= _glamor_->max_fbo_size)
|
||||||
|
|
||||||
/* For 1bpp pixmap, we don't store it as texture. */
|
|
||||||
#define glamor_check_pixmap_fbo_depth(_depth_) ( \
|
|
||||||
_depth_ == 8 \
|
|
||||||
|| _depth_ == 15 \
|
|
||||||
|| _depth_ == 16 \
|
|
||||||
|| _depth_ == 24 \
|
|
||||||
|| _depth_ == 30 \
|
|
||||||
|| _depth_ == 32)
|
|
||||||
|
|
||||||
#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
|
#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
|
||||||
|
|
||||||
/**
|
|
||||||
* Borrow from uxa.
|
|
||||||
*/
|
|
||||||
static inline CARD32
|
|
||||||
format_for_depth(int depth)
|
|
||||||
{
|
|
||||||
switch (depth) {
|
|
||||||
case 1:
|
|
||||||
return PICT_a1;
|
|
||||||
case 4:
|
|
||||||
return PICT_a4;
|
|
||||||
case 8:
|
|
||||||
return PICT_a8;
|
|
||||||
case 15:
|
|
||||||
return PICT_x1r5g5b5;
|
|
||||||
case 16:
|
|
||||||
return PICT_r5g6b5;
|
|
||||||
default:
|
|
||||||
case 24:
|
|
||||||
return PICT_x8r8g8b8;
|
|
||||||
case 30:
|
|
||||||
return PICT_x2r10g10b10;
|
|
||||||
case 32:
|
|
||||||
return PICT_a8r8g8b8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline GLenum
|
|
||||||
gl_iformat_for_pixmap(PixmapPtr pixmap)
|
|
||||||
{
|
|
||||||
glamor_screen_private *glamor_priv =
|
|
||||||
glamor_get_screen_private((pixmap)->drawable.pScreen);
|
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
|
||||||
|
|
||||||
if (!glamor_priv->is_gles &&
|
|
||||||
((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
|
|
||||||
return glamor_priv->one_channel_format;
|
|
||||||
} else if (!glamor_priv->is_gles &&
|
|
||||||
(pixmap)->drawable.depth == 16 && pixmap_priv->is_cbcr) {
|
|
||||||
return GL_RG;
|
|
||||||
} else if (!glamor_priv->is_gles &&
|
|
||||||
(pixmap)->drawable.depth == 30) {
|
|
||||||
return GL_RGB10_A2;
|
|
||||||
} else {
|
|
||||||
return GL_RGBA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define REVERT_NONE 0
|
#define REVERT_NONE 0
|
||||||
#define REVERT_NORMAL 1
|
#define REVERT_NORMAL 1
|
||||||
#define REVERT_UPLOADING_A1 3
|
#define REVERT_UPLOADING_A1 3
|
||||||
|
|
Loading…
Reference in New Issue
Block a user