mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Re-apply Vulkan zeta surface texture correctness fix
Track VkImageLayout on SurfaceBinding and transition correctly between DEPTH_STENCIL_ATTACHMENT_OPTIMAL and DEPTH_STENCIL_READ_ONLY_OPTIMAL when depth surfaces are used as textures. - renderer.h: Add image_layout to SurfaceBinding; tex_surface_direct_layout[] to PGRAPHVkState - image.c: Add DEPTH_STENCIL_READ_ONLY_OPTIMAL transition cases for TRANSFER_SRC/DST - surface.c: Replace hardcoded layouts with image_layout tracking throughout - draw.c: Barrier in begin_render_pass to restore zeta from READ_ONLY to ATTACHMENT - shaders.c: Use tex_surface_direct_layout[] instead of hardcoded GENERAL - texture.c: Add bind_zeta_surface_as_texture(); use image_layout in all s2t paths; direct-bind depth surfaces without stencil in DEPTH_STENCIL_READ_ONLY_OPTIMAL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
997c8d0b30
commit
e71284cfbf
@@ -1243,6 +1243,36 @@ static void begin_render_pass(PGRAPHState *pg)
|
||||
|
||||
assert(r->framebuffer_index > 0);
|
||||
|
||||
if (r->zeta_binding &&
|
||||
r->zeta_binding->image_layout !=
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
|
||||
VkImageMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.oldLayout = r->zeta_binding->image_layout,
|
||||
.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = r->zeta_binding->image,
|
||||
.subresourceRange = {
|
||||
.aspectMask = r->zeta_binding->host_fmt.aspect,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.srcAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
};
|
||||
vkCmdPipelineBarrier(
|
||||
r->command_buffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
0, 0, NULL, 0, NULL, 1, &barrier);
|
||||
r->zeta_binding->image_layout =
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
|
||||
VkRenderPassBeginInfo render_pass_begin_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = r->render_pass,
|
||||
|
||||
@@ -202,6 +202,15 @@ void pgraph_vk_transition_image_layout(PGRAPHState *pg, VkCommandBuffer cmd,
|
||||
sourceStage = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
|
||||
// Depth Read-Only -> Src
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
|
||||
sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
|
||||
// Depth -> Dst
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
@@ -210,6 +219,14 @@ void pgraph_vk_transition_image_layout(PGRAPHState *pg, VkCommandBuffer cmd,
|
||||
sourceStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
|
||||
// Depth Read-Only -> Dst
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
sourceStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
|
||||
// Src -> Color
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
|
||||
@@ -226,6 +243,22 @@ void pgraph_vk_transition_image_layout(PGRAPHState *pg, VkCommandBuffer cmd,
|
||||
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
|
||||
// Src -> Depth Read-Only
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
|
||||
// Dst -> Depth Read-Only
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
|
||||
// Src -> Dst
|
||||
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL &&
|
||||
newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
|
||||
|
||||
@@ -136,6 +136,7 @@ typedef struct SurfaceBinding {
|
||||
|
||||
VkImage image;
|
||||
VkImageView image_view;
|
||||
VkImageLayout image_layout;
|
||||
VmaAllocation allocation;
|
||||
|
||||
// Used for scaling
|
||||
@@ -402,6 +403,7 @@ typedef struct PGRAPHVkState {
|
||||
TextureBinding *texture_bindings[NV2A_MAX_TEXTURES];
|
||||
bool tex_surface_direct[NV2A_MAX_TEXTURES];
|
||||
VkImageView tex_surface_direct_views[NV2A_MAX_TEXTURES];
|
||||
VkImageLayout tex_surface_direct_layout[NV2A_MAX_TEXTURES];
|
||||
TextureBinding dummy_texture;
|
||||
bool texture_bindings_changed;
|
||||
VkFormatProperties *texture_format_properties;
|
||||
|
||||
@@ -209,7 +209,7 @@ void pgraph_vk_update_descriptor_sets(PGRAPHState *pg)
|
||||
for (int i = 0; i < NV2A_MAX_TEXTURES; i++) {
|
||||
image_infos[i] = (VkDescriptorImageInfo){
|
||||
.imageLayout = r->tex_surface_direct[i]
|
||||
? VK_IMAGE_LAYOUT_GENERAL
|
||||
? r->tex_surface_direct_layout[i]
|
||||
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
.imageView = r->tex_surface_direct[i]
|
||||
? r->tex_surface_direct_views[i]
|
||||
|
||||
@@ -207,9 +207,9 @@ static void download_surface_to_buffer(NV2AState *d, SurfaceBinding *surface,
|
||||
|
||||
pgraph_vk_transition_image_layout(
|
||||
pg, cmd, surface->image, surface->host_fmt.vk_format,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
surface->image_layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
surface->image_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
|
||||
int num_copy_regions = 1;
|
||||
VkBufferImageCopy copy_regions[2];
|
||||
@@ -319,6 +319,9 @@ static void download_surface_to_buffer(NV2AState *d, SurfaceBinding *surface,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
surface->image_layout =
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
// FIXME: Verify output of depth stencil conversion
|
||||
// FIXME: Track current layout and only transition when required
|
||||
@@ -889,6 +892,9 @@ static void create_surface_image(PGRAPHState *pg, SurfaceBinding *surface)
|
||||
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
surface->image_layout =
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
nv2a_profile_inc_counter(NV2A_PROF_QUEUE_SUBMIT_3);
|
||||
pgraph_vk_end_debug_marker(r, cmd);
|
||||
@@ -900,6 +906,7 @@ static void migrate_surface_image(SurfaceBinding *dst, SurfaceBinding *src)
|
||||
{
|
||||
dst->image = src->image;
|
||||
dst->image_view = src->image_view;
|
||||
dst->image_layout = src->image_layout;
|
||||
dst->allocation = src->allocation;
|
||||
dst->image_scratch = src->image_scratch;
|
||||
dst->image_scratch_current_layout = src->image_scratch_current_layout;
|
||||
@@ -907,6 +914,7 @@ static void migrate_surface_image(SurfaceBinding *dst, SurfaceBinding *src)
|
||||
|
||||
src->image = VK_NULL_HANDLE;
|
||||
src->image_view = VK_NULL_HANDLE;
|
||||
src->image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
src->allocation = VK_NULL_HANDLE;
|
||||
src->image_scratch = VK_NULL_HANDLE;
|
||||
src->image_scratch_current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
@@ -1286,9 +1294,9 @@ void pgraph_vk_upload_surface_data(NV2AState *d, SurfaceBinding *surface,
|
||||
|
||||
pgraph_vk_transition_image_layout(
|
||||
pg, cmd, surface->image, surface->host_fmt.vk_format,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
surface->image_layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
surface->image_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
||||
bool upscale = pg->surface_scale_factor > 1 &&
|
||||
!use_compute_to_convert_depth_stencil_format;
|
||||
@@ -1341,6 +1349,9 @@ void pgraph_vk_upload_surface_data(NV2AState *d, SurfaceBinding *surface,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
surface->image_layout =
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
nv2a_profile_inc_counter(NV2A_PROF_QUEUE_SUBMIT_2);
|
||||
pgraph_vk_end_debug_marker(r, cmd);
|
||||
@@ -1443,6 +1454,7 @@ static void populate_surface_binding_target_sized(NV2AState *d, bool color,
|
||||
target->frame_time = pg->frame_time;
|
||||
target->draw_time = pg->draw_time;
|
||||
target->cleared = false;
|
||||
target->image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
target->initialized = false;
|
||||
}
|
||||
|
||||
@@ -756,19 +756,15 @@ static void copy_zeta_surface_to_texture(PGRAPHState *pg, SurfaceBinding *surfac
|
||||
|
||||
pgraph_vk_transition_image_layout(
|
||||
pg, cmd, surface->image, surface->host_fmt.vk_format,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
surface->image_layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
surface->image_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
|
||||
vkCmdCopyImageToBuffer(
|
||||
cmd, surface->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dst_storage_buffer->buffer,
|
||||
num_regions, regions);
|
||||
|
||||
pgraph_vk_transition_image_layout(
|
||||
pg, cmd, surface->image, surface->host_fmt.vk_format,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
|
||||
VkBuffer texture_source_buffer;
|
||||
|
||||
if (use_compute_to_convert_depth_stencil) {
|
||||
@@ -887,6 +883,12 @@ static void copy_zeta_surface_to_texture(PGRAPHState *pg, SurfaceBinding *surfac
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
texture->current_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
pgraph_vk_transition_image_layout(
|
||||
pg, cmd, surface->image, surface->host_fmt.vk_format,
|
||||
surface->image_layout,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
surface->image_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
pgraph_vk_end_debug_marker(r, cmd);
|
||||
pgraph_vk_end_nondraw_commands(pg, cmd);
|
||||
|
||||
@@ -976,6 +978,46 @@ static void bind_surface_as_texture(PGRAPHState *pg, SurfaceBinding *surface,
|
||||
texture->draw_time = surface->draw_time;
|
||||
}
|
||||
|
||||
static void bind_zeta_surface_as_texture(PGRAPHState *pg, SurfaceBinding *surface,
|
||||
TextureBinding *texture)
|
||||
{
|
||||
assert(!surface->color);
|
||||
assert(!(surface->host_fmt.aspect & VK_IMAGE_ASPECT_STENCIL_BIT));
|
||||
|
||||
nv2a_profile_inc_counter(NV2A_PROF_SURF_TO_TEX);
|
||||
|
||||
if (surface->image_layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
|
||||
VkCommandBuffer cmd = pgraph_vk_begin_nondraw_commands(pg);
|
||||
|
||||
VkImageMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.oldLayout = surface->image_layout,
|
||||
.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = surface->image,
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
};
|
||||
vkCmdPipelineBarrier(
|
||||
cmd, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
0, 0, NULL, 0, NULL, 1, &barrier);
|
||||
|
||||
pgraph_vk_end_nondraw_commands(pg, cmd);
|
||||
surface->image_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
texture->draw_time = surface->draw_time;
|
||||
}
|
||||
|
||||
static void copy_surface_to_texture(PGRAPHState *pg, SurfaceBinding *surface,
|
||||
TextureBinding *texture)
|
||||
{
|
||||
@@ -998,9 +1040,9 @@ static void copy_surface_to_texture(PGRAPHState *pg, SurfaceBinding *surface,
|
||||
|
||||
pgraph_vk_transition_image_layout(
|
||||
pg, cmd, surface->image, surface->host_fmt.vk_format,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
surface->image_layout,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
surface->image_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
|
||||
pgraph_vk_transition_image_layout(pg, cmd, texture->image, vkf.vk_format,
|
||||
texture->current_layout,
|
||||
@@ -1027,6 +1069,9 @@ static void copy_surface_to_texture(PGRAPHState *pg, SurfaceBinding *surface,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
surface->image_layout =
|
||||
surface->color ? VK_IMAGE_LAYOUT_GENERAL :
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
pgraph_vk_transition_image_layout(pg, cmd, texture->image, vkf.vk_format,
|
||||
texture->current_layout,
|
||||
@@ -1291,6 +1336,8 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
|
||||
bool surface_to_texture = false;
|
||||
r->tex_surface_direct[texture_idx] = false;
|
||||
r->tex_surface_direct_views[texture_idx] = VK_NULL_HANDLE;
|
||||
r->tex_surface_direct_layout[texture_idx] =
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
// Check active surfaces to see if this texture was a render target
|
||||
SurfaceBinding *surface = pgraph_vk_surface_get(d, texture_vram_offset);
|
||||
@@ -1399,12 +1446,29 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
|
||||
r->tex_surface_direct[texture_idx] = true;
|
||||
r->tex_surface_direct_views[texture_idx] =
|
||||
get_surface_direct_texture_view(r, surface, snode);
|
||||
r->tex_surface_direct_layout[texture_idx] = VK_IMAGE_LAYOUT_GENERAL;
|
||||
} else {
|
||||
r->tex_surface_direct[texture_idx] = false;
|
||||
r->tex_surface_direct_views[texture_idx] = VK_NULL_HANDLE;
|
||||
r->tex_surface_direct_layout[texture_idx] =
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
} else {
|
||||
bool can_direct_bind =
|
||||
!(surface->host_fmt.aspect & VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
if (can_direct_bind) {
|
||||
if (surface->draw_time != snode->draw_time ||
|
||||
surface->image_layout !=
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) {
|
||||
bind_zeta_surface_as_texture(pg, surface, snode);
|
||||
}
|
||||
r->tex_surface_direct[texture_idx] = true;
|
||||
r->tex_surface_direct_views[texture_idx] = surface->image_view;
|
||||
r->tex_surface_direct_layout[texture_idx] =
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
} else if (surface->draw_time != snode->draw_time) {
|
||||
copy_surface_to_texture(pg, surface, snode);
|
||||
}
|
||||
} else if (surface->draw_time != snode->draw_time) {
|
||||
copy_surface_to_texture(pg, surface, snode);
|
||||
}
|
||||
} else {
|
||||
if (possibly_dirty && content_hash != snode->hash) {
|
||||
@@ -1619,12 +1683,25 @@ static void create_texture(PGRAPHState *pg, int texture_idx)
|
||||
r->tex_surface_direct[texture_idx] = true;
|
||||
r->tex_surface_direct_views[texture_idx] =
|
||||
get_surface_direct_texture_view(r, surface, snode);
|
||||
r->tex_surface_direct_layout[texture_idx] = VK_IMAGE_LAYOUT_GENERAL;
|
||||
} else {
|
||||
r->tex_surface_direct[texture_idx] = false;
|
||||
r->tex_surface_direct_views[texture_idx] = VK_NULL_HANDLE;
|
||||
r->tex_surface_direct_layout[texture_idx] =
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
} else {
|
||||
copy_surface_to_texture(pg, surface, snode);
|
||||
bool can_direct_bind =
|
||||
!(surface->host_fmt.aspect & VK_IMAGE_ASPECT_STENCIL_BIT);
|
||||
if (can_direct_bind) {
|
||||
bind_zeta_surface_as_texture(pg, surface, snode);
|
||||
r->tex_surface_direct[texture_idx] = true;
|
||||
r->tex_surface_direct_views[texture_idx] = surface->image_view;
|
||||
r->tex_surface_direct_layout[texture_idx] =
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
||||
} else {
|
||||
copy_surface_to_texture(pg, surface, snode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
upload_texture_image(pg, texture_idx, snode);
|
||||
@@ -1687,6 +1764,8 @@ void pgraph_vk_bind_textures(NV2AState *d)
|
||||
}
|
||||
r->tex_surface_direct[i] = false;
|
||||
r->tex_surface_direct_views[i] = VK_NULL_HANDLE;
|
||||
r->tex_surface_direct_layout[i] =
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
pg->texture_dirty[i] = false;
|
||||
continue;
|
||||
}
|
||||
@@ -1701,12 +1780,14 @@ void pgraph_vk_bind_textures(NV2AState *d)
|
||||
TextureBinding *prev_binding = r->texture_bindings[i];
|
||||
bool prev_direct = r->tex_surface_direct[i];
|
||||
VkImageView prev_direct_view = r->tex_surface_direct_views[i];
|
||||
VkImageLayout prev_direct_layout = r->tex_surface_direct_layout[i];
|
||||
create_texture(pg, i);
|
||||
|
||||
pg->texture_dirty[i] = false; // FIXME: Move to renderer?
|
||||
if (r->texture_bindings[i] != prev_binding ||
|
||||
r->tex_surface_direct[i] != prev_direct ||
|
||||
r->tex_surface_direct_views[i] != prev_direct_view) {
|
||||
r->tex_surface_direct_views[i] != prev_direct_view ||
|
||||
r->tex_surface_direct_layout[i] != prev_direct_layout) {
|
||||
r->texture_bindings_changed = true;
|
||||
}
|
||||
}
|
||||
@@ -1845,6 +1926,8 @@ void pgraph_vk_finalize_textures(PGRAPHState *pg)
|
||||
r->texture_bindings[i] = NULL;
|
||||
r->tex_surface_direct[i] = false;
|
||||
r->tex_surface_direct_views[i] = VK_NULL_HANDLE;
|
||||
r->tex_surface_direct_layout[i] =
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
destroy_dummy_texture(r);
|
||||
|
||||
Reference in New Issue
Block a user