Vulkan: Do near-exact lookups for the frontbuffer texture (may break everything).
This commit is contained in:
parent
ff1a3aaa67
commit
f8edc761fc
|
@ -672,6 +672,58 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextureFormatIsSimilar(TextureFormat left, TextureFormat right) {
|
||||||
|
#define COMPARE_FORMAT(x, y) \
|
||||||
|
if ((left == TextureFormat::x && right == TextureFormat::y) || \
|
||||||
|
(left == TextureFormat::y && right == TextureFormat::x)) { \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
if (left == right) return true;
|
||||||
|
COMPARE_FORMAT(k_2_10_10_10, k_2_10_10_10_AS_16_16_16_16);
|
||||||
|
return false;
|
||||||
|
#undef COMPARE_FORMAT
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureCache::Texture* TextureCache::Lookup(const TextureInfo& texture_info) {
|
||||||
|
auto texture_hash = texture_info.hash();
|
||||||
|
for (auto it = textures_.find(texture_hash); it != textures_.end(); ++it) {
|
||||||
|
if (it->second->texture_info == texture_info) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// slow path
|
||||||
|
for (auto it = textures_.begin(); it != textures_.end(); ++it) {
|
||||||
|
const auto& other_texture_info = it->second->texture_info;
|
||||||
|
#define COMPARE_FIELD(x) \
|
||||||
|
if (texture_info.x != other_texture_info.x) continue
|
||||||
|
COMPARE_FIELD(guest_address);
|
||||||
|
COMPARE_FIELD(dimension);
|
||||||
|
COMPARE_FIELD(width);
|
||||||
|
COMPARE_FIELD(height);
|
||||||
|
COMPARE_FIELD(depth);
|
||||||
|
COMPARE_FIELD(endianness);
|
||||||
|
COMPARE_FIELD(is_tiled);
|
||||||
|
COMPARE_FIELD(has_packed_mips);
|
||||||
|
COMPARE_FIELD(input_length);
|
||||||
|
#undef COMPARE_FIELD
|
||||||
|
if (!TextureFormatIsSimilar(texture_info.texture_format,
|
||||||
|
other_texture_info.texture_format)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*const auto format_info = texture_info.format_info();
|
||||||
|
const auto other_format_info = other_texture_info.format_info();
|
||||||
|
#define COMPARE_FIELD(x) if (format_info->x != other_format_info->x) continue
|
||||||
|
COMPARE_FIELD(type);
|
||||||
|
COMPARE_FIELD(block_width);
|
||||||
|
COMPARE_FIELD(block_height);
|
||||||
|
COMPARE_FIELD(bits_per_pixel);
|
||||||
|
#undef COMPARE_FIELD*/
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
|
TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
|
||||||
uint32_t width,
|
uint32_t width,
|
||||||
uint32_t height,
|
uint32_t height,
|
||||||
|
|
|
@ -92,6 +92,8 @@ class TextureCache {
|
||||||
|
|
||||||
// TODO(benvanik): ReadTexture.
|
// TODO(benvanik): ReadTexture.
|
||||||
|
|
||||||
|
Texture* Lookup(const TextureInfo& texture_info);
|
||||||
|
|
||||||
// Looks for a texture either containing or matching these parameters.
|
// Looks for a texture either containing or matching these parameters.
|
||||||
// Caller is responsible for checking if the texture returned is an exact
|
// Caller is responsible for checking if the texture returned is an exact
|
||||||
// match or just contains the texture given by the parameters.
|
// match or just contains the texture given by the parameters.
|
||||||
|
|
|
@ -395,10 +395,19 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
}
|
}
|
||||||
auto swap_fb = reinterpret_cast<VkImage>(swap_state_.front_buffer_texture);
|
auto swap_fb = reinterpret_cast<VkImage>(swap_state_.front_buffer_texture);
|
||||||
|
|
||||||
|
auto& regs = *register_file_;
|
||||||
|
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0;
|
||||||
|
auto group =
|
||||||
|
reinterpret_cast<const xenos::xe_gpu_fetch_group_t*>(®s.values[r]);
|
||||||
|
auto& fetch = group->texture_fetch;
|
||||||
|
|
||||||
|
TextureInfo texture_info;
|
||||||
|
if (!TextureInfo::Prepare(group->texture_fetch, &texture_info)) {
|
||||||
|
assert_always();
|
||||||
|
}
|
||||||
|
|
||||||
// Issue the commands to copy the game's frontbuffer to our backbuffer.
|
// Issue the commands to copy the game's frontbuffer to our backbuffer.
|
||||||
auto texture = texture_cache_->LookupAddress(
|
auto texture = texture_cache_->Lookup(texture_info);
|
||||||
frontbuffer_ptr, xe::round_up(frontbuffer_width, 32),
|
|
||||||
/*xe::round_up(*/ frontbuffer_height /*, 32)*/, TextureFormat::k_8_8_8_8);
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
texture->in_flight_fence = current_batch_fence_;
|
texture->in_flight_fence = current_batch_fence_;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue