diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index ada519598a6..15690e6e35f 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -890,6 +890,56 @@ static const struct dri2_format_mapping g8r8_b8r8_mapping = { { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888 } } }; +static enum __DRIFixedRateCompression +to_dri_compression_rate(uint32_t rate) +{ + switch (rate) { + case PIPE_COMPRESSION_FIXED_RATE_NONE: + return __DRI_FIXED_RATE_COMPRESSION_NONE; + case PIPE_COMPRESSION_FIXED_RATE_DEFAULT: + return __DRI_FIXED_RATE_COMPRESSION_DEFAULT; + case 1: return __DRI_FIXED_RATE_COMPRESSION_1BPC; + case 2: return __DRI_FIXED_RATE_COMPRESSION_2BPC; + case 3: return __DRI_FIXED_RATE_COMPRESSION_3BPC; + case 4: return __DRI_FIXED_RATE_COMPRESSION_4BPC; + case 5: return __DRI_FIXED_RATE_COMPRESSION_5BPC; + case 6: return __DRI_FIXED_RATE_COMPRESSION_6BPC; + case 7: return __DRI_FIXED_RATE_COMPRESSION_7BPC; + case 8: return __DRI_FIXED_RATE_COMPRESSION_8BPC; + case 9: return __DRI_FIXED_RATE_COMPRESSION_9BPC; + case 10: return __DRI_FIXED_RATE_COMPRESSION_10BPC; + case 11: return __DRI_FIXED_RATE_COMPRESSION_11BPC; + case 12: return __DRI_FIXED_RATE_COMPRESSION_12BPC; + default: + unreachable("invalid compression fixed-rate value"); + } +} + +static uint32_t +from_dri_compression_rate(enum __DRIFixedRateCompression rate) +{ + switch (rate) { + case __DRI_FIXED_RATE_COMPRESSION_NONE: + return PIPE_COMPRESSION_FIXED_RATE_NONE; + case __DRI_FIXED_RATE_COMPRESSION_DEFAULT: + return PIPE_COMPRESSION_FIXED_RATE_DEFAULT; + case __DRI_FIXED_RATE_COMPRESSION_1BPC: return 1; + case __DRI_FIXED_RATE_COMPRESSION_2BPC: return 2; + case __DRI_FIXED_RATE_COMPRESSION_3BPC: return 3; + case __DRI_FIXED_RATE_COMPRESSION_4BPC: return 4; + case __DRI_FIXED_RATE_COMPRESSION_5BPC: return 5; + case __DRI_FIXED_RATE_COMPRESSION_6BPC: return 6; + case __DRI_FIXED_RATE_COMPRESSION_7BPC: return 7; + case __DRI_FIXED_RATE_COMPRESSION_8BPC: return 8; + case __DRI_FIXED_RATE_COMPRESSION_9BPC: return 9; + case __DRI_FIXED_RATE_COMPRESSION_10BPC: return 10; + case __DRI_FIXED_RATE_COMPRESSION_11BPC: return 11; + case __DRI_FIXED_RATE_COMPRESSION_12BPC: return 12; + default: + unreachable("invalid compression fixed-rate value"); + } +} + static __DRIimage * dri2_create_image_from_winsys(__DRIscreen *_screen, int width, int height, const struct dri2_format_mapping *map, @@ -1342,6 +1392,13 @@ dri2_query_image_common(__DRIimage *image, int attrib, int *value) *value = map->dri_fourcc; } return true; + case __DRI_IMAGE_ATTRIB_COMPRESSION_RATE: + if (!image->texture) + *value = __DRI_FIXED_RATE_COMPRESSION_NONE; + else + *value = to_dri_compression_rate(image->texture->compression_rate); + return true; + default: return false; } @@ -1831,6 +1888,58 @@ dri2_from_dma_bufs3(__DRIscreen *screen, return img; } +static bool +dri2_query_compression_rates(__DRIscreen *_screen, const __DRIconfig *config, int max, + enum __DRIFixedRateCompression *rates, int *count) +{ + struct dri_screen *screen = dri_screen(_screen); + struct pipe_screen *pscreen = screen->base.screen; + struct gl_config *gl_config = (struct gl_config *) config; + enum pipe_format format = gl_config->color_format; + uint32_t pipe_rates[max]; + + if (!pscreen->is_format_supported(pscreen, format, screen->target, 0, 0, + PIPE_BIND_RENDER_TARGET)) + return false; + + if (pscreen->query_compression_rates != NULL) { + pscreen->query_compression_rates(pscreen, format, max, pipe_rates, count); + for (int i = 0; i < *count && i < max; ++i) + rates[i] = to_dri_compression_rate(pipe_rates[i]); + } else { + *count = 0; + } + + return true; +} + +static bool +dri2_query_compression_modifiers(__DRIscreen *_screen, uint32_t fourcc, + enum __DRIFixedRateCompression rate, int max, + uint64_t *modifiers, int *count) +{ + struct dri_screen *screen = dri_screen(_screen); + struct pipe_screen *pscreen = screen->base.screen; + const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc); + uint32_t pipe_rate = from_dri_compression_rate(rate); + + if (!map) + return false; + + if (!pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, + 0, 0, PIPE_BIND_RENDER_TARGET)) + return false; + + if (pscreen->query_compression_modifiers != NULL) { + pscreen->query_compression_modifiers(pscreen, map->pipe_format, pipe_rate, + max, modifiers, count); + } else { + *count = 0; + } + + return true; +} + static void dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src, int dstx0, int dsty0, int dstwidth, int dstheight, @@ -1953,7 +2062,7 @@ dri2_get_capabilities(__DRIscreen *_screen) /* The extension is modified during runtime if DRI_PRIME is detected */ static const __DRIimageExtension dri2ImageExtensionTempl = { - .base = { __DRI_IMAGE, 21 }, + .base = { __DRI_IMAGE, 22 }, .createImageFromName = dri2_create_image_from_name, .createImageFromRenderbuffer = dri2_create_image_from_renderbuffer, @@ -1980,6 +2089,8 @@ static const __DRIimageExtension dri2ImageExtensionTempl = { .queryDmaBufFormatModifierAttribs = NULL, .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2, .createImageWithModifiers2 = NULL, + .queryCompressionRates = NULL, + .queryCompressionModifiers = NULL, }; const __DRIimageExtension driVkImageExtension = { @@ -2287,6 +2398,15 @@ dri2_init_screen_extensions(struct dri_screen *screen, dri2_query_dma_buf_format_modifier_attribs; } } + + if (pscreen->query_compression_rates && + pscreen->query_compression_modifiers) { + screen->image_extension.queryCompressionRates = + dri2_query_compression_rates; + screen->image_extension.queryCompressionModifiers = + dri2_query_compression_modifiers; + } + *nExt++ = &screen->image_extension.base; if (!is_kms_screen) {