[Vulkan] Propagate setup_buffer down to DemandRegion

This commit is contained in:
DrChat 2017-12-23 21:33:28 -06:00
parent f44e8acccb
commit 24c49dc63f
3 changed files with 33 additions and 27 deletions

View File

@ -473,7 +473,7 @@ TextureCache::Texture* TextureCache::DemandResolveTexture(
TextureCache::TextureRegion* TextureCache::DemandRegion(
const TextureInfo& texture_info, VkCommandBuffer command_buffer,
VkFence completion_fence) {
VkCommandBuffer setup_buffer, VkFence completion_fence) {
// Run a tight loop to scan for an exact match existing texture.
auto texture_hash = texture_info.hash();
for (auto it = textures_.find(texture_hash); it != textures_.end(); ++it) {
@ -491,12 +491,6 @@ TextureCache::TextureRegion* TextureCache::DemandRegion(
}
}
if (!command_buffer) {
// Texture not found and no command buffer was passed, preventing us from
// uploading a new one.
return nullptr;
}
// If we didn't find an exact match, see if we can find a subregion of an
// existing texture to use.
VkOffset2D offset;
@ -530,7 +524,7 @@ TextureCache::TextureRegion* TextureCache::DemandRegion(
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
}
if (!region->region_contents_valid) {
if (command_buffer && !region->region_contents_valid) {
// Region content is out-of-date, recreate it by blitting from the base
// region.
@ -1448,7 +1442,8 @@ void TextureCache::HashTextureBindings(
}
VkDescriptorSet TextureCache::PrepareTextureSet(
VkCommandBuffer command_buffer, VkFence completion_fence,
VkCommandBuffer command_buffer, VkCommandBuffer setup_buffer,
VkFence completion_fence,
const std::vector<Shader::TextureBinding>& vertex_bindings,
const std::vector<Shader::TextureBinding>& pixel_bindings) {
XXH64_state_t hash_state;
@ -1475,12 +1470,14 @@ VkDescriptorSet TextureCache::PrepareTextureSet(
// This does things lazily and de-dupes fetch constants reused in both
// shaders.
bool any_failed = false;
any_failed = !SetupTextureBindings(command_buffer, completion_fence,
update_set_info, vertex_bindings) ||
any_failed;
any_failed = !SetupTextureBindings(command_buffer, completion_fence,
update_set_info, pixel_bindings) ||
any_failed;
any_failed =
!SetupTextureBindings(command_buffer, setup_buffer, completion_fence,
update_set_info, vertex_bindings) ||
any_failed;
any_failed =
!SetupTextureBindings(command_buffer, setup_buffer, completion_fence,
update_set_info, pixel_bindings) ||
any_failed;
if (any_failed) {
XELOGW("Failed to setup one or more texture bindings");
// TODO(benvanik): actually bail out here?
@ -1512,17 +1509,18 @@ VkDescriptorSet TextureCache::PrepareTextureSet(
}
bool TextureCache::SetupTextureBindings(
VkCommandBuffer command_buffer, VkFence completion_fence,
UpdateSetInfo* update_set_info,
VkCommandBuffer command_buffer, VkCommandBuffer setup_buffer,
VkFence completion_fence, UpdateSetInfo* update_set_info,
const std::vector<Shader::TextureBinding>& bindings) {
bool any_failed = false;
for (auto& binding : bindings) {
uint32_t fetch_bit = 1 << binding.fetch_constant;
if ((update_set_info->has_setup_fetch_mask & fetch_bit) == 0) {
// Needs setup.
any_failed = !SetupTextureBinding(command_buffer, completion_fence,
update_set_info, binding) ||
any_failed;
any_failed =
!SetupTextureBinding(command_buffer, setup_buffer, completion_fence,
update_set_info, binding) ||
any_failed;
update_set_info->has_setup_fetch_mask |= fetch_bit;
}
}
@ -1530,6 +1528,7 @@ bool TextureCache::SetupTextureBindings(
}
bool TextureCache::SetupTextureBinding(VkCommandBuffer command_buffer,
VkCommandBuffer setup_buffer,
VkFence completion_fence,
UpdateSetInfo* update_set_info,
const Shader::TextureBinding& binding) {
@ -1563,8 +1562,8 @@ bool TextureCache::SetupTextureBinding(VkCommandBuffer command_buffer,
// Search via the base format.
texture_info.texture_format = GetBaseFormat(texture_info.texture_format);
auto texture_region =
DemandRegion(texture_info, command_buffer, completion_fence);
auto texture_region = DemandRegion(texture_info, command_buffer, setup_buffer,
completion_fence);
auto sampler = Demand(sampler_info);
if (texture_region == nullptr || sampler == nullptr) {
return false;

View File

@ -109,8 +109,12 @@ class TextureCache {
// bindings. The textures will be uploaded/converted/etc as needed.
// Requires a fence to be provided that will be signaled when finished
// using the returned descriptor set.
// The setup buffer may be flushed to the device if we run out of space.
// The command buffer may be transitioned out of a render pass if an
// upload is performed to fill a dirty texture region.
VkDescriptorSet PrepareTextureSet(
VkCommandBuffer setup_command_buffer, VkFence completion_fence,
VkCommandBuffer command_buffer, VkCommandBuffer setup_buffer,
VkFence completion_fence,
const std::vector<Shader::TextureBinding>& vertex_bindings,
const std::vector<Shader::TextureBinding>& pixel_bindings);
@ -162,7 +166,8 @@ class TextureCache {
// 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.
TextureRegion* DemandRegion(const TextureInfo& texture_info,
VkCommandBuffer command_buffer = nullptr,
VkCommandBuffer command_buffer,
VkCommandBuffer setup_buffer,
VkFence completion_fence = nullptr);
Sampler* Demand(const SamplerInfo& sampler_info);
@ -193,10 +198,11 @@ class TextureCache {
void HashTextureBindings(XXH64_state_t* hash_state, uint32_t& fetch_mask,
const std::vector<Shader::TextureBinding>& bindings);
bool SetupTextureBindings(
VkCommandBuffer command_buffer, VkFence completion_fence,
UpdateSetInfo* update_set_info,
VkCommandBuffer command_buffer, VkCommandBuffer setup_buffer,
VkFence completion_fence, UpdateSetInfo* update_set_info,
const std::vector<Shader::TextureBinding>& bindings);
bool SetupTextureBinding(VkCommandBuffer command_buffer,
VkCommandBuffer setup_buffer,
VkFence completion_fence,
UpdateSetInfo* update_set_info,
const Shader::TextureBinding& binding);

View File

@ -827,7 +827,8 @@ bool VulkanCommandProcessor::PopulateSamplers(VkCommandBuffer command_buffer,
std::vector<xe::gpu::Shader::TextureBinding> dummy_bindings;
auto descriptor_set = texture_cache_->PrepareTextureSet(
command_buffer, current_batch_fence_, vertex_shader->texture_bindings(),
command_buffer, setup_buffer, current_batch_fence_,
vertex_shader->texture_bindings(),
pixel_shader ? pixel_shader->texture_bindings() : dummy_bindings);
if (!descriptor_set) {
// Unable to bind set.