Add Vulkan color surface fallbacks for Adreno

This commit is contained in:
izzy2lost
2026-04-08 02:34:51 -04:00
parent a646620b77
commit 9007656f90
3 changed files with 116 additions and 10 deletions
+57
View File
@@ -331,8 +331,12 @@ typedef struct SurfaceFormatInfo {
static const BasicSurfaceFormatInfo kelvin_surface_color_format_map[] = {
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1R5G5B5_Z1R5G5B5] = { 2 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1R5G5B5_O1R5G5B5] = { 2 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_R5G6B5] = { 2 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X8R8G8B8_Z8R8G8B8] = { 4 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X8R8G8B8_O8R8G8B8] = { 4 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1A7R8G8B8_Z1A7R8G8B8] = { 4 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1A7R8G8B8_O1A7R8G8B8] = { 4 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_A8R8G8B8] = { 4 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_B8] = { 1 },
[NV097_SET_SURFACE_FORMAT_COLOR_LE_G8B8] = { 2 },
@@ -347,6 +351,14 @@ static const SurfaceFormatInfo kelvin_surface_color_format_vk_map[] = {
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
},
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1R5G5B5_O1R5G5B5] =
{
// FIXME: Force alpha to one
2,
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
},
[NV097_SET_SURFACE_FORMAT_COLOR_LE_R5G6B5] =
{
2,
@@ -362,6 +374,30 @@ static const SurfaceFormatInfo kelvin_surface_color_format_vk_map[] = {
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
},
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X8R8G8B8_O8R8G8B8] =
{
// FIXME: Force alpha to one
4,
VK_FORMAT_B8G8R8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
},
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1A7R8G8B8_Z1A7R8G8B8] =
{
// FIXME: Precise X1A7 alpha encoding not emulated; stored as 8-bit alpha
4,
VK_FORMAT_B8G8R8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
},
[NV097_SET_SURFACE_FORMAT_COLOR_LE_X1A7R8G8B8_O1A7R8G8B8] =
{
// FIXME: Precise X1A7 alpha encoding not emulated; stored as 8-bit alpha
4,
VK_FORMAT_B8G8R8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
},
[NV097_SET_SURFACE_FORMAT_COLOR_LE_A8R8G8B8] =
{
4,
@@ -415,4 +451,25 @@ static const SurfaceFormatInfo zeta_d24_unorm_s8_uint = {
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
};
static const SurfaceFormatInfo color_r5g6b5_fallback = {
2,
VK_FORMAT_R5G6B5_UNORM_PACK16,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
};
static const SurfaceFormatInfo color_b8g8r8a8_fallback = {
4,
VK_FORMAT_B8G8R8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
};
static const SurfaceFormatInfo color_r8g8b8a8_fallback = {
4,
VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_IMAGE_ASPECT_COLOR_BIT,
};
#endif
+2
View File
@@ -462,6 +462,8 @@ typedef struct PGRAPHVkState {
QSIMPLEQ_HEAD(, QueryReport) report_queue; // FIXME: Statically allocate
SurfaceFormatInfo kelvin_surface_zeta_vk_map[3];
SurfaceFormatInfo
kelvin_surface_color_vk_map[ARRAY_SIZE(kelvin_surface_color_format_vk_map)];
uint32_t clear_parameter;
+57 -10
View File
@@ -1465,7 +1465,7 @@ static void populate_surface_binding_target_sized(NV2AState *d, bool color,
assert(pg->surface_shape.color_format <
ARRAY_SIZE(kelvin_surface_color_format_vk_map));
fmt = kelvin_surface_color_format_map[pg->surface_shape.color_format];
host_fmt = kelvin_surface_color_format_vk_map[pg->surface_shape.color_format];
host_fmt = r->kelvin_surface_color_vk_map[pg->surface_shape.color_format];
if (host_fmt.host_bytes_per_pixel == 0) {
fprintf(stderr, "nv2a: unimplemented color surface format 0x%x\n",
pg->surface_shape.color_format);
@@ -1843,15 +1843,62 @@ void pgraph_vk_init_surfaces(PGRAPHState *pg)
{
PGRAPHVkState *r = pg->vk_renderer_state;
// Make sure all surface format types are supported. We don't expect issue
// with these, and therefore have no fallback mechanism.
bool color_formats_supported = check_surface_internal_formats_supported(
r, kelvin_surface_color_format_vk_map,
ARRAY_SIZE(kelvin_surface_color_format_vk_map));
if (!color_formats_supported) {
fprintf(stderr,
"Warning: Some Vulkan surface color formats are unsupported; "
"continuing with best-effort mapping.\n");
memcpy(r->kelvin_surface_color_vk_map, kelvin_surface_color_format_vk_map,
sizeof(kelvin_surface_color_format_vk_map));
static const struct {
int idx;
const SurfaceFormatInfo *fallback1;
const SurfaceFormatInfo *fallback2;
} color_fallbacks[] = {
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_X1R5G5B5_Z1R5G5B5,
&color_r5g6b5_fallback, &color_b8g8r8a8_fallback },
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_X1R5G5B5_O1R5G5B5,
&color_r5g6b5_fallback, &color_b8g8r8a8_fallback },
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_X8R8G8B8_Z8R8G8B8,
&color_r8g8b8a8_fallback, NULL },
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_X8R8G8B8_O8R8G8B8,
&color_r8g8b8a8_fallback, NULL },
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_X1A7R8G8B8_Z1A7R8G8B8,
&color_r8g8b8a8_fallback, NULL },
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_X1A7R8G8B8_O1A7R8G8B8,
&color_r8g8b8a8_fallback, NULL },
{ NV097_SET_SURFACE_FORMAT_COLOR_LE_A8R8G8B8,
&color_r8g8b8a8_fallback, NULL },
};
for (int i = 0; i < ARRAY_SIZE(color_fallbacks); i++) {
SurfaceFormatInfo *slot =
&r->kelvin_surface_color_vk_map[color_fallbacks[i].idx];
const SurfaceFormatInfo *fallback = NULL;
if (slot->host_bytes_per_pixel == 0) {
continue;
}
if (check_format_and_usage_supported(r, slot->vk_format, slot->usage)) {
continue;
}
if (color_fallbacks[i].fallback1 &&
check_format_and_usage_supported(r,
color_fallbacks[i].fallback1->vk_format,
color_fallbacks[i].fallback1->usage)) {
fallback = color_fallbacks[i].fallback1;
} else if (color_fallbacks[i].fallback2 &&
check_format_and_usage_supported(
r, color_fallbacks[i].fallback2->vk_format,
color_fallbacks[i].fallback2->usage)) {
fallback = color_fallbacks[i].fallback2;
}
if (fallback) {
*slot = *fallback;
} else {
fprintf(stderr,
"Warning: Vulkan color surface format 0x%x has no supported fallback\n",
color_fallbacks[i].idx);
}
}
// Check if the device supports preferred VK_FORMAT_D24_UNORM_S8_UINT