static boolean r300_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned usage) { uint32_t retval = 0; boolean drm_2_8_0 = r300_screen(screen)->info.drm_minor >= 8; boolean is_r500 = r300_screen(screen)->caps.is_r500; boolean is_r400 = r300_screen(screen)->caps.is_r400; boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM || format == PIPE_FORMAT_R10G10B10X2_SNORM || format == PIPE_FORMAT_B10G10R10A2_UNORM || format == PIPE_FORMAT_B10G10R10X2_UNORM || format == PIPE_FORMAT_R10SG10SB10SA2U_NORM; boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC1_SNORM || format == PIPE_FORMAT_LATC1_UNORM || format == PIPE_FORMAT_LATC1_SNORM; boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM || format == PIPE_FORMAT_RGTC2_SNORM || format == PIPE_FORMAT_LATC2_UNORM || format == PIPE_FORMAT_LATC2_SNORM; boolean is_x16f_xy16f = format == PIPE_FORMAT_R16_FLOAT || format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_A16_FLOAT || format == PIPE_FORMAT_L16_FLOAT || format == PIPE_FORMAT_L16A16_FLOAT || format == PIPE_FORMAT_R16A16_FLOAT || format == PIPE_FORMAT_I16_FLOAT; boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT || format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_R16G16B16_FLOAT || format == PIPE_FORMAT_R16G16B16A16_FLOAT || format == PIPE_FORMAT_R16G16B16X16_FLOAT; const struct util_format_description *desc; if (!util_format_is_supported(format, usage)) return FALSE; /* Check multisampling support. */ switch (sample_count) { case 0: case 1: break; case 2: case 4: case 6: /* We need DRM 2.8.0. */ if (!drm_2_8_0) { return FALSE; } /* No texturing and scanout. */ if (usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT)) { return FALSE; } desc = util_format_description(format); if (is_r500) { /* Only allow depth/stencil, RGBA8, RGBA1010102, RGBA16F. */ if (!util_format_is_depth_or_stencil(format) && !util_format_is_rgba8_variant(desc) && !util_format_is_rgba1010102_variant(desc) && format != PIPE_FORMAT_R16G16B16A16_FLOAT && format != PIPE_FORMAT_R16G16B16X16_FLOAT) { return FALSE; } } else { /* Only allow depth/stencil, RGBA8. */ if (!util_format_is_depth_or_stencil(format) && !util_format_is_rgba8_variant(desc)) { return FALSE; } } break; default: return FALSE; } /* Check sampler format support. */ if ((usage & PIPE_BIND_SAMPLER_VIEW) && /* these two are broken for an unknown reason */ format != PIPE_FORMAT_R8G8B8X8_SNORM && format != PIPE_FORMAT_R16G16B16X16_SNORM && /* ATI1N is r5xx-only. */ (is_r500 || !is_ati1n) && /* ATI2N is supported on r4xx-r5xx. */ (is_r400 || is_r500 || !is_ati2n) && /* R16F and RG16F texture support was added in as late as DRM 2.8.0 */ (drm_2_8_0 || !is_x16f_xy16f) && r300_is_sampler_format_supported(format)) { retval |= PIPE_BIND_SAMPLER_VIEW; } /* Check colorbuffer format support. */ if ((usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_BLENDABLE)) && /* 2101010 cannot be rendered to on non-r5xx. */ (!is_color2101010 || (is_r500 && drm_2_8_0)) && r300_is_colorbuffer_format_supported(format)) { retval |= usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED); if (r300_is_blending_supported(r300_screen(screen), format)) { retval |= usage & PIPE_BIND_BLENDABLE; } } /* Check depth-stencil format support. */ if (usage & PIPE_BIND_DEPTH_STENCIL && r300_is_zs_format_supported(format)) { retval |= PIPE_BIND_DEPTH_STENCIL; } /* Check vertex buffer format support. */ if (usage & PIPE_BIND_VERTEX_BUFFER) { if (r300_screen(screen)->caps.has_tcl) { /* Half float is supported on >= R400. */ if ((is_r400 || is_r500 || !is_half_float) && r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) { retval |= PIPE_BIND_VERTEX_BUFFER; } } else { /* SW TCL */ if (!util_format_is_pure_integer(format)) { retval |= PIPE_BIND_VERTEX_BUFFER; } } } /* Transfers are always supported. */ if (usage & PIPE_BIND_TRANSFER_READ) retval |= PIPE_BIND_TRANSFER_READ; if (usage & PIPE_BIND_TRANSFER_WRITE) retval |= PIPE_BIND_TRANSFER_WRITE; return retval == usage; }
static boolean r300_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, unsigned usage) { uint32_t retval = 0; boolean drm_2_8_0 = r300_screen(screen)->info.drm_minor >= 8; boolean is_r500 = r300_screen(screen)->caps.is_r500; boolean is_r400 = r300_screen(screen)->caps.is_r400; boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM || format == PIPE_FORMAT_R10G10B10X2_SNORM || format == PIPE_FORMAT_B10G10R10A2_UNORM || format == PIPE_FORMAT_R10SG10SB10SA2U_NORM; boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC1_SNORM || format == PIPE_FORMAT_LATC1_UNORM || format == PIPE_FORMAT_LATC1_SNORM; boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM || format == PIPE_FORMAT_RGTC2_SNORM || format == PIPE_FORMAT_LATC2_UNORM || format == PIPE_FORMAT_LATC2_SNORM; boolean is_x16f_xy16f = format == PIPE_FORMAT_R16_FLOAT || format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_A16_FLOAT || format == PIPE_FORMAT_L16_FLOAT || format == PIPE_FORMAT_L16A16_FLOAT || format == PIPE_FORMAT_I16_FLOAT; boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT || format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_R16G16B16_FLOAT || format == PIPE_FORMAT_R16G16B16A16_FLOAT; boolean is_fixed = format == PIPE_FORMAT_R32_FIXED || format == PIPE_FORMAT_R32G32_FIXED || format == PIPE_FORMAT_R32G32B32_FIXED || format == PIPE_FORMAT_R32G32B32A32_FIXED; if (!util_format_is_supported(format, usage)) return FALSE; /* Check multisampling support. */ switch (sample_count) { case 0: case 1: break; case 2: case 3: case 4: case 6: return FALSE; #if 0 if (usage != PIPE_BIND_RENDER_TARGET || !util_format_is_rgba8_variant( util_format_description(format))) { return FALSE; } #endif break; default: return FALSE; } /* Check sampler format support. */ if ((usage & PIPE_BIND_SAMPLER_VIEW) && /* ATI1N is r5xx-only. */ (is_r500 || !is_ati1n) && /* ATI2N is supported on r4xx-r5xx. */ (is_r400 || is_r500 || !is_ati2n) && /* R16F and RG16F texture support was added in as late as DRM 2.8.0 */ (drm_2_8_0 || !is_x16f_xy16f) && r300_is_sampler_format_supported(format)) { retval |= PIPE_BIND_SAMPLER_VIEW; } /* Check colorbuffer format support. */ if ((usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) && /* 2101010 cannot be rendered to on non-r5xx. */ (!is_color2101010 || (is_r500 && drm_2_8_0)) && r300_is_colorbuffer_format_supported(format)) { retval |= usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED); } /* Check depth-stencil format support. */ if (usage & PIPE_BIND_DEPTH_STENCIL && r300_is_zs_format_supported(format)) { retval |= PIPE_BIND_DEPTH_STENCIL; } /* Check vertex buffer format support. */ if (usage & PIPE_BIND_VERTEX_BUFFER && /* Half float is supported on >= R400. */ (is_r400 || is_r500 || !is_half_float) && /* We have a fallback for FIXED. */ (is_fixed || r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT)) { retval |= PIPE_BIND_VERTEX_BUFFER; } /* Transfers are always supported. */ if (usage & PIPE_BIND_TRANSFER_READ) retval |= PIPE_BIND_TRANSFER_READ; if (usage & PIPE_BIND_TRANSFER_WRITE) retval |= PIPE_BIND_TRANSFER_WRITE; return retval == usage; }