Merge branch 'vulkan'

This commit is contained in:
Dr. Chat
2016-06-11 19:23:23 -05:00
164 changed files with 51895 additions and 4707 deletions

View File

@@ -1410,7 +1410,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::PopulateVertexBuffers() {
// as we copy and only if it differs from the previous value committing
// it (and if it matches just discard and reuse).
xe::copy_and_swap_32_aligned(
reinterpret_cast<uint32_t*>(allocation.host_ptr),
allocation.host_ptr,
memory_->TranslatePhysical<const uint32_t*>(fetch->address << 2),
valid_range / 4);

View File

@@ -7,8 +7,8 @@
******************************************************************************
*/
#ifndef XENIA_GPU_GL4_COMMAND_PROCESSOR_H_
#define XENIA_GPU_GL4_COMMAND_PROCESSOR_H_
#ifndef XENIA_GPU_GL4_GL4_COMMAND_PROCESSOR_H_
#define XENIA_GPU_GL4_GL4_COMMAND_PROCESSOR_H_
#include <atomic>
#include <cstring>
@@ -234,4 +234,4 @@ class GL4CommandProcessor : public CommandProcessor {
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_GL4_COMMAND_PROCESSOR_H_
#endif // XENIA_GPU_GL4_GL4_COMMAND_PROCESSOR_H_

View File

@@ -427,7 +427,7 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture(
// Not found, create.
auto entry = std::make_unique<TextureEntry>();
entry->texture_info = texture_info;
entry->write_watch_handle = 0;
entry->access_watch_handle = 0;
entry->pending_invalidation = false;
entry->handle = 0;
@@ -442,6 +442,7 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture(
// Found! Acquire the handle and remove the readbuffer entry.
read_buffer_textures_.erase(it);
entry->handle = read_buffer_entry->handle;
entry->access_watch_handle = read_buffer_entry->access_watch_handle;
delete read_buffer_entry;
// TODO(benvanik): set more texture properties? swizzle/etc?
auto entry_ptr = entry.get();
@@ -495,14 +496,15 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture(
// Add a write watch. If any data in the given range is touched we'll get a
// callback and evict the texture. We could reuse the storage, though the
// driver is likely in a better position to pool that kind of stuff.
entry->write_watch_handle = memory_->AddPhysicalWriteWatch(
entry->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_entry = reinterpret_cast<TextureEntry*>(data_ptr);
// Clear watch handle first so we don't redundantly
// remove.
touched_entry->write_watch_handle = 0;
touched_entry->access_watch_handle = 0;
touched_entry->pending_invalidation = true;
// Add to pending list so Scavenge will clean it up.
self->invalidated_textures_mutex_.lock();
@@ -574,14 +576,27 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
dest_rect, GL_LINEAR, swap_channels);
}
// HACK: remove texture from write watch list so readback won't kill us.
// Not needed now, as readback is disabled.
/*
if (texture_entry->write_watch_handle) {
memory_->CancelWriteWatch(texture_entry->write_watch_handle);
texture_entry->write_watch_handle = 0;
// Setup a read/write access watch. If the game tries to touch the memory
// we were supposed to populate with this texture, then we'll actually
// populate it.
if (texture_entry->access_watch_handle) {
memory_->CancelAccessWatch(texture_entry->access_watch_handle);
texture_entry->access_watch_handle = 0;
}
//*/
texture_entry->access_watch_handle = memory_->AddPhysicalAccessWatch(
guest_address, texture_entry->texture_info.input_length,
cpu::MMIOHandler::kWatchReadWrite,
[](void* context, void* data, uint32_t address) {
auto touched_entry = reinterpret_cast<TextureEntry*>(data);
touched_entry->access_watch_handle = 0;
// This happens. RDR resolves to a texture then upsizes it, BF1943
// writes to a resolved texture.
// TODO (for Vulkan): Copy this texture back into system memory.
// assert_always();
},
nullptr, texture_entry);
return texture_entry->handle;
}
@@ -618,6 +633,20 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
entry->block_height = block_height;
entry->format = format;
entry->access_watch_handle = memory_->AddPhysicalAccessWatch(
guest_address, block_height * block_width * 4,
cpu::MMIOHandler::kWatchReadWrite,
[](void* context, void* data, uint32_t address) {
auto entry = reinterpret_cast<ReadBufferTexture*>(data);
entry->access_watch_handle = 0;
// This happens. RDR resolves to a texture then upsizes it, BF1943
// writes to a resolved texture.
// TODO (for Vulkan): Copy this texture back into system memory.
// assert_always();
},
nullptr, entry.get());
glCreateTextures(GL_TEXTURE_2D, 1, &entry->handle);
glTextureParameteri(entry->handle, GL_TEXTURE_BASE_LEVEL, 0);
glTextureParameteri(entry->handle, GL_TEXTURE_MAX_LEVEL, 1);
@@ -636,9 +665,9 @@ GLuint TextureCache::ConvertTexture(Blitter* blitter, uint32_t guest_address,
}
void TextureCache::EvictTexture(TextureEntry* entry) {
if (entry->write_watch_handle) {
memory_->CancelWriteWatch(entry->write_watch_handle);
entry->write_watch_handle = 0;
if (entry->access_watch_handle) {
memory_->CancelAccessWatch(entry->access_watch_handle);
entry->access_watch_handle = 0;
}
for (auto& view : entry->views) {
@@ -662,19 +691,13 @@ void TextureSwap(Endian endianness, void* dest, const void* src,
size_t length) {
switch (endianness) {
case Endian::k8in16:
xe::copy_and_swap_16_aligned(reinterpret_cast<uint16_t*>(dest),
reinterpret_cast<const uint16_t*>(src),
length / 2);
xe::copy_and_swap_16_aligned(dest, src, length / 2);
break;
case Endian::k8in32:
xe::copy_and_swap_32_aligned(reinterpret_cast<uint32_t*>(dest),
reinterpret_cast<const uint32_t*>(src),
length / 4);
xe::copy_and_swap_32_aligned(dest, src, length / 4);
break;
case Endian::k16in32: // Swap high and low 16 bits within a 32 bit word
xe::copy_and_swap_16_in_32_aligned(reinterpret_cast<uint32_t*>(dest),
reinterpret_cast<const uint32_t*>(src),
length);
xe::copy_and_swap_16_in_32_aligned(dest, src, length);
break;
default:
case Endian::kUnspecified:

View File

@@ -44,7 +44,7 @@ class TextureCache {
};
struct TextureEntry {
TextureInfo texture_info;
uintptr_t write_watch_handle;
uintptr_t access_watch_handle;
GLuint handle;
bool pending_invalidation;
std::vector<std::unique_ptr<TextureEntryView>> views;
@@ -74,8 +74,12 @@ class TextureCache {
TextureFormat format, bool swap_channels,
GLuint src_texture, Rect2D src_rect, Rect2D dest_rect);
TextureEntry* LookupAddress(uint32_t guest_address, uint32_t width,
uint32_t height, TextureFormat format);
private:
struct ReadBufferTexture {
uintptr_t access_watch_handle;
uint32_t guest_address;
uint32_t logical_width;
uint32_t logical_height;
@@ -90,8 +94,6 @@ class TextureCache {
void EvictSampler(SamplerEntry* entry);
TextureEntry* LookupOrInsertTexture(const TextureInfo& texture_info,
uint64_t opt_hash = 0);
TextureEntry* LookupAddress(uint32_t guest_address, uint32_t width,
uint32_t height, TextureFormat format);
void EvictTexture(TextureEntry* entry);
bool UploadTexture2D(GLuint texture, const TextureInfo& texture_info);