Merge branch 'master' into vk_vfetch
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user