Compartir a través de


Formato BC7

El formato BC7 es un formato de compresión de textura utilizado para la compresión de alta calidad de los datos RGB y RGBA.

Para obtener información sobre los modos de bloqueo del formato BC7, consulta referencia del modo de formato BC7.

Acerca de BC7/DXGI_FORMAT_BC7

BC7 se especifica mediante los siguientes valores de enumeración DXGI_FORMAT:

  • DXGI_FORMAT_BC7_TYPELESS.
  • DXGI_FORMAT_BC7_UNORM.
  • DXGI_FORMAT_BC7_UNORM_SRGB.

El formato BC7 se puede usar para Texture2D (incluidas matrices), Texture3D o TextureCube (incluidas matrices). Del mismo modo, este formato se aplica a cualquier superficie de mapa MIP asociada a estos recursos.

BC7 usa un tamaño fijo de bloque de 16 bytes (128 bits) y un tamaño fijo de mosaico de 4 x 4 texels. Al igual que con los formatos BC anteriores, las imágenes de textura mayores que el tamaño de mosaico admitido (4x4) se comprimen mediante varios bloques. Esta identidad de direccionamiento también se aplica a imágenes tridimensionales y mapas MIP, mapas de cubos y matrices de texturas. Todos los iconos de imagen deben tener el mismo formato.

BC7 comprime las imágenes de datos de punto fijo de tres canales (RGB) y cuatro canales (RGBA). Normalmente, los datos de origen son de 8 bits por componente de color (canal), aunque el formato es capaz de codificar datos de origen con bits más altos por componente de color. Todos los iconos de imagen deben tener el mismo formato.

El descodificador BC7 realiza la descompresión antes de aplicar el filtrado de texturas.

El hardware de descompresión BC7 debe ser preciso a nivel de bit; es decir, el hardware debe devolver resultados idénticos a los resultados devueltos por el descodificador descrito en este documento.

Implementación de BC7

Una implementación bc7 puede especificar uno de los 8 modos, con el modo especificado en el bit menos significativo del bloque de 16 bytes (128 bits). El modo está codificado por cero o más bits con un valor de 0 seguido de 1.

Un bloque BC7 puede contener varios pares de puntos de conexión. El conjunto de índices que corresponden a un par de puntos de conexión se puede denominar "subconjunto". Además, en algunos modos de bloque, la representación del punto de conexión se codifica en un formulario que se puede denominar "RBGP", donde el bit "P" representa un bit menos significativo compartido para los componentes de color del punto de conexión. Por ejemplo, si la representación del extremo para el formato es "RGB 5.5.5.1", el extremo se interpreta como un valor RGB 6.6.6, donde el estado del bit P define el bit menos significativo de cada componente. Del mismo modo, para los datos de origen con un canal alfa, si la representación del formato es "RGBAP 5.5.5.5.1", el extremo se interpreta como RGBA 6.6.6.6.6. Según el modo de bloque, puede especificar el bit menos significativo compartido para ambos puntos de conexión de un subconjunto individualmente (2 bits P por subconjunto) o compartir entre puntos de conexión de un subconjunto (1 P bits por subconjunto).

Para los bloques BC7 que no codifican explícitamente el componente alfa, un bloque BC7 consta de bits de modo, bits de partición, puntos de conexión comprimidos, índices comprimidos y un bit P opcional. En estos bloques, los extremos tienen una representación de solo RGB y el componente alfa se decodifica como 1.0 para todos los elementos de textura de los datos de origen.

Para los bloques BC7 que tienen componentes alfa y de color combinados, un bloque consta de bits de modo, puntos de conexión comprimidos, índices comprimidos y bits de partición opcionales y un bit P. En estos bloques, los colores del punto de conexión se expresan en formato RGBA y los valores de los componentes alfa se interpolan junto con los valores del componente de color.

Para los bloques BC7 que tienen componentes alfa y de color independientes, un bloque consta de bits de modo, bits de rotación, puntos de conexión comprimidos, índices comprimidos y un bit de selector de índice opcional. Estos bloques tienen un vector RGB efectivo [R, G, B] y un canal alfa escalar [A] codificados por separado.

En la tabla siguiente se enumeran los componentes de cada tipo de bloque.

El bloque BC7 contiene... bits de modo bits de rotación bit del selector de índice bits de partición puntos de conexión comprimidos P-bit índices comprimidos
solo componentes de color Obligatorio No disponible No disponible Obligatorio Obligatorio opcional Obligatorio
color + alfa combinado Obligatorio No disponible No disponible opcional Obligatorio opcional Obligatorio
color y alfa separados Obligatorio Obligatorio opcional No disponible Obligatorio No disponible Obligatorio

 

BC7 define una paleta de colores en una línea aproximada entre dos puntos de conexión. El valor del modo determina el número de pares de puntos finales de interpolación por bloque. BC7 almacena un índice de paleta por texel.

Por cada subconjunto de índices que corresponde a un par de extremos, el codificador fija el estado de un bit de los datos de índice comprimidos para ese subconjunto. Para ello, elige un orden de puntos de conexión que permita al índice designado como "fix-up" establecer su bit más significativo en 0, y que luego se puede descartar, ahorrando así un bit por subconjunto. En el caso de los modos de bloqueo con un solo subconjunto, el índice de corrección siempre es el índice 0.

Descodificación del formato BC7

El pseudocódigo siguiente describe los pasos para descomprimir el píxel en (x,y) según el bloque BC7 de 16 bytes.

decompress_bc7(x, y, block)
{
    mode = extract_mode(block);
    
    //decode partition data from explicit partition bits
    subset_index = 0;
    num_subsets = 1;
    
    if (mode.type == 0 OR == 1 OR == 2 OR == 3 OR == 7)
    {
        num_subsets = get_num_subsets(mode.type);
        partition_set_id = extract_partition_set_id(mode, block);
        subset_index = get_partition_index(num_subsets, partition_set_id, x, y);
    }
    
    //extract raw, compressed endpoint bits
    UINT8 endpoint_array[num_subsets][4] = extract_endpoints(mode, block);
    
    //decode endpoint color and alpha for each subset
    fully_decode_endpoints(endpoint_array, mode, block);
    
    //endpoints are now complete.
    UINT8 endpoint_start[4] = endpoint_array[2 * subset_index];
    UINT8 endpoint_end[4]   = endpoint_array[2 * subset_index + 1];
        
    //Determine the palette index for this pixel
    alpha_index     = get_alpha_index(block, mode, x, y);
    alpha_bitcount  = get_alpha_bitcount(block, mode);
    color_index     = get_color_index(block, mode, x, y);
    color_bitcount  = get_color_bitcount(block, mode);

    //determine output
    UINT8 output[4];
    output.rgb = interpolate(endpoint_start.rgb, endpoint_end.rgb, color_index, color_bitcount);
    output.a   = interpolate(endpoint_start.a,   endpoint_end.a,   alpha_index, alpha_bitcount);
    
    if (mode.type == 4 OR == 5)
    {
        //Decode the 2 color rotation bits as follows:
        // 00 – Block format is Scalar(A) Vector(RGB) - no swapping
        // 01 – Block format is Scalar(R) Vector(AGB) - swap A and R
        // 10 – Block format is Scalar(G) Vector(RAB) - swap A and G
        // 11 - Block format is Scalar(B) Vector(RGA) - swap A and B
        rotation = extract_rot_bits(mode, block);
        output = swap_channels(output, rotation);
    }
    
}

En el pseudocódigo siguiente se describen los pasos para descodificar completamente el color del punto de conexión y los componentes alfa para cada subconjunto dado un bloque BC7 de 16 bytes.

fully_decode_endpoints(endpoint_array, mode, block)
{
    //first handle modes that have P-bits
    if (mode.type == 0 OR == 1 OR == 3 OR == 6 OR == 7)
    {
        for each endpoint i
        {
            //component-wise left-shift
            endpoint_array[i].rgba = endpoint_array[i].rgba << 1;
        }
        
        //if P-bit is shared
        if (mode.type == 1) 
        {
            pbit_zero = extract_pbit_zero(mode, block);
            pbit_one = extract_pbit_one(mode, block);
            
            //rgb component-wise insert pbits
            endpoint_array[0].rgb |= pbit_zero;
            endpoint_array[1].rgb |= pbit_zero;
            endpoint_array[2].rgb |= pbit_one;
            endpoint_array[3].rgb |= pbit_one;  
        }
        else //unique P-bit per endpoint
        {  
            pbit_array = extract_pbit_array(mode, block);
            for each endpoint i
            {
                endpoint_array[i].rgba |= pbit_array[i];
            }
        }
    }

    for each endpoint i
    {
        // Color_component_precision & alpha_component_precision includes pbit
        // left shift endpoint components so that their MSB lies in bit 7
        endpoint_array[i].rgb = endpoint_array[i].rgb << (8 - color_component_precision(mode));
        endpoint_array[i].a = endpoint_array[i].a << (8 - alpha_component_precision(mode));

        // Replicate each component's MSB into the LSBs revealed by the left-shift operation above
        endpoint_array[i].rgb = endpoint_array[i].rgb | (endpoint_array[i].rgb >> color_component_precision(mode));
        endpoint_array[i].a = endpoint_array[i].a | (endpoint_array[i].a >> alpha_component_precision(mode));
    }
        
    //If this mode does not explicitly define the alpha component
    //set alpha equal to 1.0
    if (mode.type == 0 OR == 1 OR == 2 OR == 3)
    {
        for each endpoint i
        {
            endpoint_array[i].a = 255; //i.e. alpha = 1.0f
        }
    }
}

Para generar cada componente interpolado para cada subconjunto, use el siguiente algoritmo: deje que "c" sea el componente que se va a generar; permitir que "e0" sea ese componente del punto de conexión 0 del subconjunto; y deje que "e1" sea ese componente del punto de conexión 1 del subconjunto.

UINT16 aWeight2[] = {0, 21, 43, 64};
UINT16 aWeight3[] = {0, 9, 18, 27, 37, 46, 55, 64};
UINT16 aWeight4[] = {0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64};

UINT8 interpolate(UINT8 e0, UINT8 e1, UINT8 index, UINT8 indexprecision)
{
    if(indexprecision == 2)
        return (UINT8) (((64 - aWeights2[index])*UINT16(e0) + aWeights2[index]*UINT16(e1) + 32) >> 6);
    else if(indexprecision == 3)
        return (UINT8) (((64 - aWeights3[index])*UINT16(e0) + aWeights3[index]*UINT16(e1) + 32) >> 6);
    else // indexprecision == 4
        return (UINT8) (((64 - aWeights4[index])*UINT16(e0) + aWeights4[index]*UINT16(e1) + 32) >> 6);
}

En el pseudocódigo siguiente se muestra cómo extraer índices y recuentos de bits para los componentes de color y alfa. Los bloques con color y alfa independientes también tienen dos conjuntos de datos de índice: uno para el canal vectorial y otro para el canal escalar. Para el modo 4, estos índices son de anchos diferentes (2 o 3 bits) y hay un selector de un bit que especifica si los datos vectoriales o escalares usan los índices de 3 bits. (La extracción del recuento de bits alfa es similar a la extracción del recuento de bits de color, pero con un comportamiento inverso basado en el idxMode bit).

bitcount get_color_bitcount(block, mode)
{
    if (mode.type == 0 OR == 1)
        return 3;
    
    if (mode.type == 2 OR == 3 OR == 5 OR == 7)
        return 2;
    
    if (mode.type == 6)
        return 4;
        
    //The only remaining case is Mode 4 with 1-bit index selector
    idxMode = extract_idxMode(block);
    if (idxMode == 0)
        return 2;
    else
        return 3;
}

referencia del modo de formato BC7 de

Esta sección contiene una lista de los 8 modos de bloque y asignaciones de bits para los bloques de formato de compresión de textura BC7.

Los colores de cada subconjunto dentro de un bloque se representan mediante dos colores de punto de conexión explícitos y un conjunto de colores interpolados entre ellos. Según la precisión del índice del bloque, cada subconjunto puede tener 4, 8 o 16 colores posibles.

modo 0

El modo BC7 0 tiene las siguientes características:

  • Solo componentes de color (sin alfa)
  • 3 subconjuntos por bloque
  • Puntos de conexión RGBP 4.4.4.1 con un bit P único por punto de conexión
  • Índices de 3 bits
  • 16 particiones

modo de diseño de 0 bits

Modo 1

El modo BC7 1 tiene las siguientes características:

  • Solo componentes de color (sin alfa)
  • 2 subconjuntos por bloque
  • Puntos de conexión RGBP 6.6.6.1 con un bit P compartido por subconjunto)
  • Índices de 3 bits
  • 64 particiones

diseño de modo de 1 bit

Modo 2 de

El modo BC7 2 tiene las siguientes características:

  • Solo componentes de color (sin alfa)
  • 3 subconjuntos por bloque
  • Puntos de conexión RGB 5.5.5
  • Índices de 2 bits
  • 64 particiones

modo diseño de 2 bits

Modo 3 de

El modo BC7 3 tiene las siguientes características:

  • Solo componentes de color (sin alfa)
  • 2 subconjuntos por bloque
  • Puntos de conexión RGBP 7.7.7.1 con un bit P único por subconjunto)
  • Índices de 2 bits
  • 64 particiones

diseño de modo de 3 bits

Modo 4 de

El modo BC7 4 tiene las siguientes características:

  • Componentes de color con componente alfa independiente
  • 1 subconjunto por bloque
  • Puntos de conexión de color RGB 5.5.5
  • Puntos de conexión alfa de 6 bits
  • 16 índices de 2 bits
  • Índices de 16 x 3 bits
  • Rotación de componentes de 2 bits
  • Selector de índice de 1 bits (si se usan los índices de 2 o 3 bits)

modo de diseño de 4 bits

Modo 5

El modo BC7 5 tiene las siguientes características:

  • Componentes de color con componente alfa independiente
  • 1 subconjunto por bloque
  • Puntos finales de color RGB 7.7.7
  • Puntos de conexión alfa de 6 bits
  • Índices de color de 16 x 2 bits
  • Índices alfa de 16 x 2 bits
  • Rotación de componentes de 2 bits

diseño de modo de 5 bits

Modo 6 de

El modo BC7 6 tiene las siguientes características:

  • Componentes de color y alfa combinados
  • Un subconjunto por bloque
  • Puntos de conexión de color RGBAP 7.7.7.7.1 (y alfa) (bits P único por punto de conexión)
  • Índices de 16 por 4 bits

diseño de modo de 6 bits

Modo 7

El modo BC7 7 tiene las siguientes características:

  • Componentes de color y alfa combinados
  • 2 subconjuntos por bloque
  • Extremos de color y alfa RGBAP 5.5.5.5.1 (P-bit único por extremo)
  • Índices de 2 bits
  • 64 particiones

diseño de modo de 7 bits

Comentarios de

El modo 8 (el byte menos significativo se establece en 0x00) está reservado. No lo use en el codificador. Si pasa este modo al hardware, se devuelve un bloque inicializado con todos ceros.

En BC7, puede codificar el componente alfa de una de las maneras siguientes:

  • Bloquear tipos sin codificación explícita de componentes alfa. En estos bloques, los puntos de conexión de color tienen una codificación de solo RGB, con el componente alfa descodificado a 1.0 para todos los texeles.

  • Tipos de bloques con componentes alfa y color combinados. En estos bloques, los valores de color del punto de conexión se especifican en el formato RGBA y los valores del componente alfa se interpolan junto con los valores de color.

  • Tipos de bloques con componentes alfa y color separados. En estos bloques, los valores de color y alfa se especifican por separado, cada uno con su propio conjunto de índices. Como resultado, tienen un vector efectivo y un canal escalar codificados por separado, donde el vector suele especificar los canales de color [R, G, B] y el escalar especifica el canal alfa [A]. Para admitir este enfoque, se proporciona un campo de 2 bits independiente en la codificación, que permite la especificación de la codificación de canal independiente como un valor escalar. Como resultado, el bloque puede tener una de las cuatro representaciones diferentes siguientes de esta codificación alfa (como se indica en el campo de 2 bits):

    • RGB|A: canal alfa independiente
    • AGB|R: canal de color "rojo" independiente
    • RAB|G: canal de color "verde" independiente
    • RGA|B: canal de color "azul" independiente

    El descodificador vuelve a ordenar el orden del canal a RGBA después de la descodificación, por lo que el formato de bloque interno es invisible para el desarrollador. Los negros con componentes alfa y color independientes también tienen dos conjuntos de datos de índice: uno para el conjunto vectorial de canales y otro para el canal escalar. (En el caso del modo 4, estos índices son de anchos diferentes [2 o 3 bits]. El modo 4 también contiene un selector de 1 bits que especifica si el vector o el canal escalar usa los índices de 3 bits).

Compresión de bloques de textura