static bool radv_is_storage_image_format_supported(struct radv_physical_device *physical_device, VkFormat format) { const struct vk_format_description *desc = vk_format_description(format); unsigned data_format, num_format; if (!desc || format == VK_FORMAT_UNDEFINED) return false; data_format = radv_translate_tex_dataformat(format, desc, vk_format_get_first_non_void_channel(format)); num_format = radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format)); if(data_format == ~0 || num_format == ~0) return false; /* Extracted from the GCN3 ISA document. */ switch(num_format) { case V_008F14_IMG_NUM_FORMAT_UNORM: case V_008F14_IMG_NUM_FORMAT_SNORM: case V_008F14_IMG_NUM_FORMAT_UINT: case V_008F14_IMG_NUM_FORMAT_SINT: case V_008F14_IMG_NUM_FORMAT_FLOAT: break; default: return false; } switch(data_format) { case V_008F14_IMG_DATA_FORMAT_8: case V_008F14_IMG_DATA_FORMAT_16: case V_008F14_IMG_DATA_FORMAT_8_8: case V_008F14_IMG_DATA_FORMAT_32: case V_008F14_IMG_DATA_FORMAT_16_16: case V_008F14_IMG_DATA_FORMAT_10_11_11: case V_008F14_IMG_DATA_FORMAT_11_11_10: case V_008F14_IMG_DATA_FORMAT_10_10_10_2: case V_008F14_IMG_DATA_FORMAT_2_10_10_10: case V_008F14_IMG_DATA_FORMAT_8_8_8_8: case V_008F14_IMG_DATA_FORMAT_32_32: case V_008F14_IMG_DATA_FORMAT_16_16_16_16: case V_008F14_IMG_DATA_FORMAT_32_32_32_32: case V_008F14_IMG_DATA_FORMAT_5_6_5: case V_008F14_IMG_DATA_FORMAT_1_5_5_5: case V_008F14_IMG_DATA_FORMAT_5_5_5_1: case V_008F14_IMG_DATA_FORMAT_4_4_4_4: /* TODO: FMASK formats. */ return true; default: return false; } }
static bool radv_is_buffer_format_supported(VkFormat format) { const struct vk_format_description *desc = vk_format_description(format); unsigned data_format, num_format; if (!desc || format == VK_FORMAT_UNDEFINED) return false; data_format = radv_translate_buffer_dataformat(desc, vk_format_get_first_non_void_channel(format)); num_format = radv_translate_buffer_numformat(desc, vk_format_get_first_non_void_channel(format)); return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID && num_format != ~0; }
static void radv_make_buffer_descriptor(struct radv_device *device, struct radv_buffer *buffer, VkFormat vk_format, unsigned offset, unsigned range, uint32_t *state) { const struct vk_format_description *desc; unsigned stride; uint64_t gpu_address = device->ws->buffer_get_va(buffer->bo); uint64_t va = gpu_address + buffer->offset; unsigned num_format, data_format; int first_non_void; desc = vk_format_description(vk_format); first_non_void = vk_format_get_first_non_void_channel(vk_format); stride = desc->block.bits / 8; num_format = radv_translate_buffer_numformat(desc, first_non_void); data_format = radv_translate_buffer_dataformat(desc, first_non_void); va += offset; state[0] = va; state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) | S_008F04_STRIDE(stride); state[2] = range; state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc->swizzle[0])) | S_008F0C_DST_SEL_Y(radv_map_swizzle(desc->swizzle[1])) | S_008F0C_DST_SEL_Z(radv_map_swizzle(desc->swizzle[2])) | S_008F0C_DST_SEL_W(radv_map_swizzle(desc->swizzle[3])) | S_008F0C_NUM_FORMAT(num_format) | S_008F0C_DATA_FORMAT(data_format); }
static bool radv_is_sampler_format_supported(VkFormat format, bool *linear_sampling) { const struct vk_format_description *desc = vk_format_description(format); uint32_t num_format; if (!desc || format == VK_FORMAT_UNDEFINED) return false; num_format = radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format)); if (num_format == V_008F14_IMG_NUM_FORMAT_USCALED || num_format == V_008F14_IMG_NUM_FORMAT_SSCALED) return false; if (num_format == V_008F14_IMG_NUM_FORMAT_UNORM || num_format == V_008F14_IMG_NUM_FORMAT_SNORM || num_format == V_008F14_IMG_NUM_FORMAT_FLOAT || num_format == V_008F14_IMG_NUM_FORMAT_SRGB) *linear_sampling = true; else *linear_sampling = false; return radv_translate_tex_dataformat(format, vk_format_description(format), vk_format_get_first_non_void_channel(format)) != ~0U; }
bool radv_is_colorbuffer_format_supported(VkFormat format, bool *blendable) { const struct vk_format_description *desc = vk_format_description(format); uint32_t color_format = radv_translate_colorformat(format); uint32_t color_swap = radv_translate_colorswap(format, false); uint32_t color_num_format = radv_translate_color_numformat(format, desc, vk_format_get_first_non_void_channel(format)); if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT || color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 || color_format == V_028C70_COLOR_X24_8_32_FLOAT) { *blendable = false; } else *blendable = true; return color_format != V_028C70_COLOR_INVALID && color_swap != ~0U && color_num_format != ~0; }
static uint32_t tu6_sp_2d_src_format(VkFormat format) { const struct vk_format_description *desc = vk_format_description(format); uint32_t reg = 0xf000 | A6XX_SP_2D_SRC_FORMAT_COLOR_FORMAT(tu6_get_native_format(format)->rb); int channel = vk_format_get_first_non_void_channel(format); if (channel < 0) { /* TODO special format. */ return reg; } if (desc->channel[channel].normalized) { if (desc->channel[channel].type == VK_FORMAT_TYPE_SIGNED) reg |= A6XX_SP_2D_SRC_FORMAT_SINT; reg |= A6XX_SP_2D_SRC_FORMAT_NORM; } else if (desc->channel[channel].pure_integer) { if (desc->channel[channel].type == VK_FORMAT_TYPE_SIGNED) reg |= A6XX_SP_2D_SRC_FORMAT_SINT; else reg |= A6XX_SP_2D_SRC_FORMAT_UINT; } return reg; }