mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Add Vulkan color surface fallbacks for Adreno
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user