[Vulkan] Add logging to certain error conditions.

[Vulkan] Track both texture block height and texture block vertical pitch.
[Vulkan] Only convert the necessary visible height on texture uploads.
[Vulkan] Fix write watch on texture data so it properly only covers mip 0 data.
This commit is contained in:
gibbed
2018-05-30 19:38:36 -05:00
parent 7068d0a5a9
commit bbebfd49c8
5 changed files with 78 additions and 44 deletions

View File

@@ -425,6 +425,9 @@ void TextureCache::WatchCallback(void* context_ptr, void* data_ptr,
touched_texture->access_watch_handle = 0;
touched_texture->pending_invalidation = true;
/*XELOGI("Invalidating texture @ 0x%.8X!",
touched_texture->texture_info.guest_address);*/
// Add to pending list so Scavenge will clean it up.
self->invalidated_textures_mutex_.lock();
self->invalidated_textures_->insert(touched_texture);
@@ -470,15 +473,17 @@ TextureCache::Texture* TextureCache::DemandResolveTexture(
device_->DbgSetObjectName(
reinterpret_cast<uint64_t>(texture->image),
VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
xe::format_string(
"RT: 0x%.8X - 0x%.8X (%s, %s)", texture_info.guest_address,
texture_info.guest_address + texture_info.GetByteSize(true),
texture_info.format_info()->name,
get_dimension_name(texture_info.dimension)));
xe::format_string("RT: 0x%.8X - 0x%.8X (%s, %s)",
texture_info.guest_address,
texture_info.guest_address +
texture_info.GetMipVisibleByteSize(0, true),
texture_info.format_info()->name,
get_dimension_name(texture_info.dimension)));
// Setup an access watch. If this texture is touched, it is destroyed.
// TODO(gibbed): Setup access watch for mipmap data.
texture->access_watch_handle = memory_->AddPhysicalAccessWatch(
texture_info.guest_address, texture_info.GetByteSize(true),
texture_info.guest_address, texture_info.GetMipVisibleByteSize(0, true),
cpu::MMIOHandler::kWatchWrite, &WatchCallback, this, texture);
textures_[texture_hash] = texture;
@@ -536,8 +541,9 @@ TextureCache::Texture* TextureCache::Demand(const TextureInfo& texture_info,
// Okay. Put a writewatch on it to tell us if it's been modified from the
// guest.
// TODO(gibbed): Setup access watch for mipmap data.
texture->access_watch_handle = memory_->AddPhysicalAccessWatch(
texture_info.guest_address, texture_info.GetByteSize(true),
texture_info.guest_address, texture_info.GetMipVisibleByteSize(0, true),
cpu::MMIOHandler::kWatchWrite, &WatchCallback, this, texture);
if (!UploadTexture(command_buffer, completion_fence, texture, texture_info)) {
@@ -856,8 +862,8 @@ TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
for (auto it = textures_.begin(); it != textures_.end(); ++it) {
const auto& texture_info = it->second->texture_info;
if (guest_address >= texture_info.guest_address &&
guest_address <
texture_info.guest_address + texture_info.GetByteSize(true) &&
guest_address < texture_info.guest_address +
texture_info.GetMipVisibleByteSize(0, true) &&
texture_info.pitch >= width && texture_info.height >= height &&
out_offset) {
auto offset_bytes = guest_address - texture_info.guest_address;
@@ -939,9 +945,9 @@ bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
auto dst_usage = GetMipMemoryUsage(src, mip);
uint32_t src_pitch =
src_usage.block_pitch * src.format_info()->bytes_per_block();
src_usage.block_pitch_h * src.format_info()->bytes_per_block();
uint32_t dst_pitch =
dst_usage.block_pitch * GetFormatInfo(src.format)->bytes_per_block();
dst_usage.block_pitch_h * GetFormatInfo(src.format)->bytes_per_block();
auto copy_block = GetFormatCopyBlock(src.format);
@@ -954,8 +960,8 @@ bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
copy_block(src.endianness, dest + y * dst_pitch,
src_mem + y * src_pitch, dst_pitch);
}
src_mem += src_pitch * src_usage.block_height;
dest += dst_pitch * dst_usage.block_height;
src_mem += src_pitch * src_usage.block_pitch_v;
dest += dst_pitch * dst_usage.block_pitch_v;
}
} else {
// Untile image.
@@ -965,18 +971,18 @@ bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
std::memset(&untile_info, 0, sizeof(untile_info));
untile_info.offset_x = offset_x;
untile_info.offset_y = offset_y;
untile_info.width = dst_usage.block_pitch;
untile_info.width = dst_usage.block_pitch_h;
untile_info.height = dst_usage.block_height;
untile_info.input_pitch = src_usage.block_pitch;
untile_info.output_pitch = dst_usage.block_pitch;
untile_info.input_pitch = src_usage.block_pitch_h;
untile_info.output_pitch = dst_usage.block_pitch_h;
untile_info.input_format_info = src.format_info();
untile_info.output_format_info = GetFormatInfo(src.format);
untile_info.copy_callback = [=](auto o, auto i, auto l) {
copy_block(src.endianness, o, i, l);
};
texture_conversion::Untile(dest, src_mem, &untile_info);
src_mem += src_pitch * src_usage.block_height;
dest += dst_pitch * dst_usage.block_height;
src_mem += src_pitch * src_usage.block_pitch_v;
dest += dst_pitch * dst_usage.block_pitch_v;
}
}
@@ -1195,7 +1201,7 @@ uint32_t TextureCache::ComputeMipStorage(const FormatInfo* format_info,
depth, false, false);
}
uint32_t bytes_per_block = format_info->bytes_per_block();
return usage.blocks() * bytes_per_block;
return usage.all_blocks() * bytes_per_block;
}
uint32_t TextureCache::ComputeMipStorage(const TextureInfo& src, uint32_t mip) {

View File

@@ -822,6 +822,10 @@ bool VulkanCommandProcessor::PopulateVertexBuffers(
assert_true(vertex_bindings.size() <= 32);
auto descriptor_set = buffer_cache_->PrepareVertexSet(
setup_buffer, current_batch_fence_, vertex_bindings);
if (!descriptor_set) {
XELOGW("Failed to prepare vertex set!");
return false;
}
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_cache_->pipeline_layout(), 2, 1,
@@ -843,6 +847,7 @@ bool VulkanCommandProcessor::PopulateSamplers(VkCommandBuffer command_buffer,
pixel_shader ? pixel_shader->texture_bindings() : dummy_bindings);
if (!descriptor_set) {
// Unable to bind set.
XELOGW("Failed to prepare texture set!");
return false;
}
@@ -1023,13 +1028,14 @@ bool VulkanCommandProcessor::IssueCopy() {
// Demand a resolve texture from the texture cache.
TextureInfo texture_info;
TextureInfo::PrepareResolve(copy_dest_base, copy_dest_format, resolve_endian,
copy_dest_pitch, dest_logical_width,
std::max(1u, dest_logical_height), &texture_info);
TextureInfo::PrepareResolve(
copy_dest_base, copy_dest_format, resolve_endian, copy_dest_pitch,
dest_logical_width, std::max(1u, dest_logical_height), 1, &texture_info);
auto texture = texture_cache_->DemandResolveTexture(texture_info);
if (!texture) {
// Out of memory.
XELOGD("Failed to demand resolve texture!");
return false;
}
@@ -1137,6 +1143,7 @@ bool VulkanCommandProcessor::IssueCopy() {
auto view = render_cache_->FindTileView(
edram_base, surface_pitch, surface_msaa, is_color_source, src_format);
if (!view) {
XELOGGPU("Failed to find tile view!");
break;
}