/* Shader output formats. This is essentially the swizzle from the shader * to the RB3D block. * * Note that formats are stored from C3 to C0. */ static uint32_t r300_translate_out_fmt(enum pipe_format format) { uint32_t modifier = 0; unsigned i; const struct util_format_description *desc; boolean uniform_sign; desc = util_format_description(format); /* Find the first non-VOID channel. */ for (i = 0; i < 4; i++) { if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { break; } } if (i == 4) return ~0; /* Unsupported/unknown. */ /* Specifies how the shader output is written to the fog unit. */ switch (desc->channel[i].type) { case UTIL_FORMAT_TYPE_FLOAT: switch (desc->channel[i].size) { case 32: switch (desc->nr_channels) { case 1: modifier |= R300_US_OUT_FMT_C_32_FP; break; case 2: modifier |= R300_US_OUT_FMT_C2_32_FP; break; case 4: modifier |= R300_US_OUT_FMT_C4_32_FP; break; } break; case 16: switch (desc->nr_channels) { case 1: modifier |= R300_US_OUT_FMT_C_16_FP; break; case 2: modifier |= R300_US_OUT_FMT_C2_16_FP; break; case 4: modifier |= R300_US_OUT_FMT_C4_16_FP; break; } break; } break; default: switch (desc->channel[i].size) { case 16: switch (desc->nr_channels) { case 1: modifier |= R300_US_OUT_FMT_C_16; break; case 2: modifier |= R300_US_OUT_FMT_C2_16; break; case 4: modifier |= R300_US_OUT_FMT_C4_16; break; } break; case 10: modifier |= R300_US_OUT_FMT_C4_10; break; default: /* C4_8 seems to be used for the formats whose pixel size * is <= 32 bits. */ modifier |= R300_US_OUT_FMT_C4_8; break; } } /* Add sign. */ uniform_sign = TRUE; for (i = 0; i < desc->nr_channels; i++) if (desc->channel[i].type != UTIL_FORMAT_TYPE_SIGNED) uniform_sign = FALSE; if (uniform_sign) modifier |= R300_OUT_SIGN(0xf); /* Add swizzles and return. */ switch (format) { /*** Special cases (non-standard channel mapping) ***/ /* X8 * COLORFORMAT_I8 stores the Z component (C2). */ case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_A8_SNORM: return modifier | R300_C2_SEL_A; case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_I8_SNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_L8_SNORM: case PIPE_FORMAT_R8_UNORM: case PIPE_FORMAT_R8_SNORM: return modifier | R300_C2_SEL_R; /* X8Y8 * COLORFORMAT_UV88 stores ZX (C2 and C0). */ case PIPE_FORMAT_L8A8_SNORM: case PIPE_FORMAT_L8A8_UNORM: case PIPE_FORMAT_R8A8_SNORM: case PIPE_FORMAT_R8A8_UNORM: return modifier | R300_C0_SEL_A | R300_C2_SEL_R; case PIPE_FORMAT_R8G8_SNORM: case PIPE_FORMAT_R8G8_UNORM: return modifier | R300_C0_SEL_G | R300_C2_SEL_R; /* X32Y32 * ARGB16161616 stores XZ for RG32F */ case PIPE_FORMAT_R32G32_FLOAT: return modifier | R300_C0_SEL_R | R300_C2_SEL_G; /*** Generic cases (standard channel mapping) ***/ /* BGRA outputs. */ case PIPE_FORMAT_B5G6R5_UNORM: case PIPE_FORMAT_B5G5R5A1_UNORM: case PIPE_FORMAT_B5G5R5X1_UNORM: case PIPE_FORMAT_B4G4R4A4_UNORM: case PIPE_FORMAT_B4G4R4X4_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ case PIPE_FORMAT_B8G8R8X8_UNORM: /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ case PIPE_FORMAT_B10G10R10A2_UNORM: case PIPE_FORMAT_B10G10R10X2_UNORM: return modifier | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; /* ARGB outputs. */ case PIPE_FORMAT_A16_UNORM: case PIPE_FORMAT_A16_SNORM: case PIPE_FORMAT_A16_FLOAT: case PIPE_FORMAT_A32_FLOAT: return modifier | R300_C0_SEL_A | R300_C1_SEL_R | R300_C2_SEL_G | R300_C3_SEL_B; /* RGBA outputs. */ case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_R8G8B8X8_SNORM: case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8A8_SNORM: case PIPE_FORMAT_R10G10B10A2_UNORM: case PIPE_FORMAT_R10G10B10X2_SNORM: case PIPE_FORMAT_R16_UNORM: case PIPE_FORMAT_R16G16_UNORM: case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16_SNORM: case PIPE_FORMAT_R16G16_SNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: case PIPE_FORMAT_R16_FLOAT: case PIPE_FORMAT_R16G16_FLOAT: case PIPE_FORMAT_R16G16B16A16_FLOAT: case PIPE_FORMAT_R32_FLOAT: case PIPE_FORMAT_R32G32B32A32_FLOAT: case PIPE_FORMAT_R32G32B32X32_FLOAT: case PIPE_FORMAT_L16_UNORM: case PIPE_FORMAT_L16_SNORM: case PIPE_FORMAT_L16_FLOAT: case PIPE_FORMAT_L32_FLOAT: case PIPE_FORMAT_I16_UNORM: case PIPE_FORMAT_I16_SNORM: case PIPE_FORMAT_I16_FLOAT: case PIPE_FORMAT_I32_FLOAT: case PIPE_FORMAT_R16G16B16X16_UNORM: case PIPE_FORMAT_R16G16B16X16_SNORM: case PIPE_FORMAT_R16G16B16X16_FLOAT: return modifier | R300_C0_SEL_R | R300_C1_SEL_G | R300_C2_SEL_B | R300_C3_SEL_A; /* LA outputs. */ case PIPE_FORMAT_L16A16_UNORM: case PIPE_FORMAT_L16A16_SNORM: case PIPE_FORMAT_L16A16_FLOAT: case PIPE_FORMAT_R16A16_UNORM: case PIPE_FORMAT_R16A16_SNORM: case PIPE_FORMAT_R16A16_FLOAT: case PIPE_FORMAT_L32A32_FLOAT: case PIPE_FORMAT_R32A32_FLOAT: return modifier | R300_C0_SEL_R | R300_C1_SEL_A; default: return ~0; /* Unsupported. */ } }
/* Shader output formats. This is essentially the swizzle from the shader * to the RB3D block. * * Note that formats are stored from C3 to C0. */ static uint32_t r300_translate_out_fmt(enum pipe_format format) { uint32_t modifier = 0; unsigned i; const struct util_format_description *desc; static const uint32_t sign_bit[4] = { R300_OUT_SIGN(0x1), R300_OUT_SIGN(0x2), R300_OUT_SIGN(0x4), R300_OUT_SIGN(0x8), }; desc = util_format_description(format); /* Specifies how the shader output is written to the fog unit. */ if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { if (desc->channel[0].size == 32) { modifier |= R300_US_OUT_FMT_C4_32_FP; } else { modifier |= R300_US_OUT_FMT_C4_16_FP; } } else { if (desc->channel[0].size == 16) { modifier |= R300_US_OUT_FMT_C4_16; } else { /* C4_8 seems to be used for the formats whose pixel size * is <= 32 bits. */ modifier |= R300_US_OUT_FMT_C4_8; } } /* Add sign. */ for (i = 0; i < 4; i++) if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { modifier |= sign_bit[i]; } /* Add swizzles and return. */ switch (format) { /* 8-bit outputs. * COLORFORMAT_I8 stores the C2 component. */ case PIPE_FORMAT_A8_UNORM: return modifier | R300_C2_SEL_A; case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_R8_UNORM: case PIPE_FORMAT_R8_SNORM: return modifier | R300_C2_SEL_R; /* BGRA outputs. */ case PIPE_FORMAT_B5G6R5_UNORM: case PIPE_FORMAT_B5G5R5A1_UNORM: case PIPE_FORMAT_B5G5R5X1_UNORM: case PIPE_FORMAT_B4G4R4A4_UNORM: case PIPE_FORMAT_B4G4R4X4_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B10G10R10A2_UNORM: return modifier | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; /* ARGB outputs. */ case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_UNORM: return modifier | R300_C0_SEL_A | R300_C1_SEL_R | R300_C2_SEL_G | R300_C3_SEL_B; /* ABGR outputs. */ case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: return modifier | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; /* RGBA outputs. */ case PIPE_FORMAT_R8G8B8X8_UNORM: case PIPE_FORMAT_R8G8B8A8_SNORM: case PIPE_FORMAT_R8SG8SB8UX8U_NORM: case PIPE_FORMAT_R10G10B10A2_UNORM: case PIPE_FORMAT_R10G10B10X2_SNORM: case PIPE_FORMAT_R10SG10SB10SA2U_NORM: case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: case PIPE_FORMAT_R16G16B16A16_FLOAT: case PIPE_FORMAT_R32G32B32A32_FLOAT: return modifier | R300_C0_SEL_R | R300_C1_SEL_G | R300_C2_SEL_B | R300_C3_SEL_A; default: return ~0; /* Unsupported. */ } }
/* Shader output formats. This is essentially the swizzle from the shader * to the RB3D block. * * Note that formats are stored from C3 to C0. */ static uint32_t r300_translate_out_fmt(enum pipe_format format) { uint32_t modifier = 0; unsigned i; const struct util_format_description *desc; static const uint32_t sign_bit[4] = { R300_OUT_SIGN(0x1), R300_OUT_SIGN(0x2), R300_OUT_SIGN(0x4), R300_OUT_SIGN(0x8), }; desc = util_format_description(format); /* Specifies how the shader output is written to the fog unit. */ if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { /* The gamma correction causes precision loss so we need * higher precision to maintain reasonable quality. * It has nothing to do with the colorbuffer format. */ modifier |= R300_US_OUT_FMT_C4_10_GAMMA; } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { if (desc->channel[0].size == 32) { modifier |= R300_US_OUT_FMT_C4_32_FP; } else { modifier |= R300_US_OUT_FMT_C4_16_FP; } } else { if (desc->channel[0].size == 16) { modifier |= R300_US_OUT_FMT_C4_16; } else { /* C4_8 seems to be used for the formats whose pixel size * is <= 32 bits. */ modifier |= R300_US_OUT_FMT_C4_8; } } /* Add sign. */ for (i = 0; i < 4; i++) if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { modifier |= sign_bit[i]; } /* Add swizzles and return. */ switch (format) { /* 8-bit outputs. * COLORFORMAT_I8 stores the C2 component. */ case PIPE_FORMAT_A8_UNORM: return modifier | R300_C2_SEL_A; case PIPE_FORMAT_I8_UNORM: case PIPE_FORMAT_L8_UNORM: case PIPE_FORMAT_L8_SRGB: case PIPE_FORMAT_R8_UNORM: case PIPE_FORMAT_R8_SNORM: return modifier | R300_C2_SEL_R; /* ARGB 32-bit outputs. */ case PIPE_FORMAT_B5G6R5_UNORM: case PIPE_FORMAT_B5G5R5A1_UNORM: case PIPE_FORMAT_B4G4R4A4_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_B8G8R8A8_SRGB: case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_B8G8R8X8_SRGB: return modifier | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; /* BGRA 32-bit outputs. */ case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_A8R8G8B8_SRGB: case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_SRGB: return modifier | R300_C0_SEL_A | R300_C1_SEL_R | R300_C2_SEL_G | R300_C3_SEL_B; /* RGBA 32-bit outputs. */ case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_R8G8B8A8_SNORM: case PIPE_FORMAT_A8B8G8R8_SRGB: case PIPE_FORMAT_X8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_SRGB: return modifier | R300_C0_SEL_A | R300_C1_SEL_B | R300_C2_SEL_G | R300_C3_SEL_R; /* ABGR 32-bit outputs. */ case PIPE_FORMAT_R8SG8SB8UX8U_NORM: case PIPE_FORMAT_R10G10B10A2_UNORM: /* RGBA high precision outputs (same swizzles as ABGR low precision) */ case PIPE_FORMAT_R16G16B16A16_UNORM: case PIPE_FORMAT_R16G16B16A16_SNORM: //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */ case PIPE_FORMAT_R32G32B32A32_FLOAT: return modifier | R300_C0_SEL_R | R300_C1_SEL_G | R300_C2_SEL_B | R300_C3_SEL_A; default: return ~0; /* Unsupported. */ } }