Merge branch 'master' into vk_vfetch

This commit is contained in:
DrChat
2018-02-14 20:31:31 -06:00
19 changed files with 641 additions and 297 deletions

View File

@@ -364,6 +364,22 @@ bool TextureCache::FreeTexture(Texture* texture) {
return true;
}
void TextureCache::WatchCallback(void* context_ptr, void* data_ptr,
uint32_t address) {
auto self = reinterpret_cast<TextureCache*>(context_ptr);
auto touched_texture = reinterpret_cast<Texture*>(data_ptr);
// Clear watch handle first so we don't redundantly
// remove.
assert_not_zero(touched_texture->access_watch_handle);
touched_texture->access_watch_handle = 0;
touched_texture->pending_invalidation = true;
// Add to pending list so Scavenge will clean it up.
self->invalidated_textures_mutex_.lock();
self->invalidated_textures_->push_back(touched_texture);
self->invalidated_textures_mutex_.unlock();
}
TextureCache::Texture* TextureCache::DemandResolveTexture(
const TextureInfo& texture_info) {
auto texture_hash = texture_info.hash();
@@ -411,22 +427,7 @@ TextureCache::Texture* TextureCache::DemandResolveTexture(
// Setup an access watch. If this texture is touched, it is destroyed.
texture->access_watch_handle = memory_->AddPhysicalAccessWatch(
texture_info.guest_address, texture_info.input_length,
cpu::MMIOHandler::kWatchWrite,
[](void* context_ptr, void* data_ptr, uint32_t address) {
auto self = reinterpret_cast<TextureCache*>(context_ptr);
auto touched_texture = reinterpret_cast<Texture*>(data_ptr);
// Clear watch handle first so we don't redundantly
// remove.
assert_not_zero(touched_texture->access_watch_handle);
touched_texture->access_watch_handle = 0;
touched_texture->pending_invalidation = true;
// Add to pending list so Scavenge will clean it up.
self->invalidated_textures_mutex_.lock();
self->invalidated_textures_->push_back(touched_texture);
self->invalidated_textures_mutex_.unlock();
},
this, texture);
cpu::MMIOHandler::kWatchWrite, &WatchCallback, this, texture);
textures_[texture_hash] = texture;
return texture;
@@ -486,21 +487,7 @@ TextureCache::Texture* TextureCache::Demand(const TextureInfo& texture_info,
// guest.
texture->access_watch_handle = memory_->AddPhysicalAccessWatch(
texture_info.guest_address, texture_info.input_length,
cpu::MMIOHandler::kWatchWrite,
[](void* context_ptr, void* data_ptr, uint32_t address) {
auto self = reinterpret_cast<TextureCache*>(context_ptr);
auto touched_texture = reinterpret_cast<Texture*>(data_ptr);
// Clear watch handle first so we don't redundantly
// remove.
assert_not_zero(touched_texture->access_watch_handle);
touched_texture->access_watch_handle = 0;
touched_texture->pending_invalidation = true;
// Add to pending list so Scavenge will clean it up.
self->invalidated_textures_mutex_.lock();
self->invalidated_textures_->push_back(touched_texture);
self->invalidated_textures_mutex_.unlock();
},
this, texture);
cpu::MMIOHandler::kWatchWrite, &WatchCallback, this, texture);
if (!UploadTexture(command_buffer, completion_fence, texture, texture_info)) {
FreeTexture(texture);
@@ -1306,6 +1293,7 @@ void TextureCache::HashTextureBindings(
// We've covered this binding.
continue;
}
fetch_mask |= fetch_bit;
auto& regs = *register_file_;
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + binding.fetch_constant * 6;
@@ -1329,8 +1317,7 @@ VkDescriptorSet TextureCache::PrepareTextureSet(
HashTextureBindings(&hash_state, fetch_mask, vertex_bindings);
HashTextureBindings(&hash_state, fetch_mask, pixel_bindings);
uint64_t hash = XXH64_digest(&hash_state);
for (auto it = texture_bindings_.find(hash); it != texture_bindings_.end();
++it) {
for (auto it = texture_sets_.find(hash); it != texture_sets_.end(); ++it) {
// TODO(DrChat): We need to compare the bindings and ensure they're equal.
return it->second;
}
@@ -1378,7 +1365,7 @@ VkDescriptorSet TextureCache::PrepareTextureSet(
update_set_info->image_writes, 0, nullptr);
}
texture_bindings_[hash] = descriptor_set;
texture_sets_[hash] = descriptor_set;
return descriptor_set;
}
@@ -1515,7 +1502,7 @@ void TextureCache::Scavenge() {
// Free unused descriptor sets
// TODO(DrChat): These sets could persist across frames, we just need a smart
// way to detect if they're unused and free them.
texture_bindings_.clear();
texture_sets_.clear();
descriptor_pool_->Scavenge();
staging_buffer_.Scavenge();

View File

@@ -134,6 +134,9 @@ class TextureCache {
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
bool FreeTexture(Texture* texture);
static void WatchCallback(void* context_ptr, void* data_ptr,
uint32_t address);
// Demands a texture. If command_buffer is null and the texture hasn't been
// uploaded to graphics memory already, we will return null and bail.
Texture* Demand(const TextureInfo& texture_info,
@@ -188,7 +191,7 @@ class TextureCache {
std::unique_ptr<xe::ui::vulkan::CommandBufferPool> wb_command_pool_ = nullptr;
std::unique_ptr<xe::ui::vulkan::DescriptorPool> descriptor_pool_ = nullptr;
std::unordered_map<uint64_t, VkDescriptorSet> texture_bindings_;
std::unordered_map<uint64_t, VkDescriptorSet> texture_sets_;
VkDescriptorSetLayout texture_descriptor_set_layout_ = nullptr;
VmaAllocator mem_allocator_ = nullptr;