Merge pull request #18339 from hrydgard/delete-vertex-cache

Remove the vertex cache option
This commit is contained in:
Henrik Rydgård 2023-10-11 10:02:30 +02:00 committed by GitHub
commit bdff93374b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 25 additions and 1397 deletions

View File

@ -35,127 +35,6 @@ using namespace PPSSPP_VK;
// Always keep around push buffers at least this long (seconds). // Always keep around push buffers at least this long (seconds).
static const double PUSH_GARBAGE_COLLECTION_DELAY = 10.0; static const double PUSH_GARBAGE_COLLECTION_DELAY = 10.0;
VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, const char *name, size_t size, VkBufferUsageFlags usage)
: vulkan_(vulkan), name_(name), size_(size), usage_(usage) {
RegisterGPUMemoryManager(this);
bool res = AddBuffer();
_assert_(res);
}
VulkanPushBuffer::~VulkanPushBuffer() {
UnregisterGPUMemoryManager(this);
_dbg_assert_(!writePtr_);
_assert_(buffers_.empty());
}
bool VulkanPushBuffer::AddBuffer() {
BufInfo info;
VkDevice device = vulkan_->GetDevice();
VkBufferCreateInfo b{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
b.size = size_;
b.flags = 0;
b.usage = usage_;
b.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
b.queueFamilyIndexCount = 0;
b.pQueueFamilyIndices = nullptr;
VmaAllocationCreateInfo allocCreateInfo{};
allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
VmaAllocationInfo allocInfo{};
VkResult res = vmaCreateBuffer(vulkan_->Allocator(), &b, &allocCreateInfo, &info.buffer, &info.allocation, &allocInfo);
if (VK_SUCCESS != res) {
_assert_msg_(false, "vkCreateBuffer failed! result=%d", (int)res);
return false;
}
vulkan_->SetDebugName(info.buffer, VK_OBJECT_TYPE_BUFFER, name_);
buffers_.push_back(info);
buf_ = buffers_.size() - 1;
return true;
}
void VulkanPushBuffer::Destroy(VulkanContext *vulkan) {
_dbg_assert_(!writePtr_);
for (BufInfo &info : buffers_) {
vulkan->Delete().QueueDeleteBufferAllocation(info.buffer, info.allocation);
}
buffers_.clear();
}
void VulkanPushBuffer::NextBuffer(size_t minSize) {
// First, unmap the current memory.
Unmap();
buf_++;
if (buf_ >= buffers_.size() || minSize > size_) {
// Before creating the buffer, adjust to the new size_ if necessary.
while (size_ < minSize) {
size_ <<= 1;
}
bool res = AddBuffer();
_assert_(res);
if (!res) {
// Let's try not to crash at least?
buf_ = 0;
}
}
// Now, move to the next buffer and map it.
offset_ = 0;
Map();
}
void VulkanPushBuffer::Defragment(VulkanContext *vulkan) {
if (buffers_.size() <= 1) {
return;
}
// Okay, we have more than one. Destroy them all and start over with a larger one.
size_t newSize = size_ * buffers_.size();
Destroy(vulkan);
size_ = newSize;
bool res = AddBuffer();
_assert_(res);
}
size_t VulkanPushBuffer::GetTotalSize() const {
size_t sum = 0;
if (buffers_.size() > 1)
sum += size_ * (buffers_.size() - 1);
sum += offset_;
return sum;
}
void VulkanPushBuffer::GetDebugString(char *buffer, size_t bufSize) const {
size_t sum = 0;
if (buffers_.size() > 1)
sum += size_ * (buffers_.size() - 1);
sum += offset_;
size_t capacity = size_ * buffers_.size();
snprintf(buffer, bufSize, "Push %s: %s / %s", name_, NiceSizeFormat(sum).c_str(), NiceSizeFormat(capacity).c_str());
}
void VulkanPushBuffer::Map() {
_dbg_assert_(!writePtr_);
VkResult res = vmaMapMemory(vulkan_->Allocator(), buffers_[buf_].allocation, (void **)(&writePtr_));
_dbg_assert_(writePtr_);
_assert_(VK_SUCCESS == res);
}
void VulkanPushBuffer::Unmap() {
_dbg_assert_msg_(writePtr_ != nullptr, "VulkanPushBuffer::Unmap: writePtr_ null here means we have a bug (map/unmap mismatch)");
if (!writePtr_)
return;
vmaUnmapMemory(vulkan_->Allocator(), buffers_[buf_].allocation);
writePtr_ = nullptr;
}
VulkanPushPool::VulkanPushPool(VulkanContext *vulkan, const char *name, size_t originalBlockSize, VkBufferUsageFlags usage) VulkanPushPool::VulkanPushPool(VulkanContext *vulkan, const char *name, size_t originalBlockSize, VkBufferUsageFlags usage)
: vulkan_(vulkan), name_(name), originalBlockSize_(originalBlockSize), usage_(usage) { : vulkan_(vulkan), name_(name), originalBlockSize_(originalBlockSize), usage_(usage) {
RegisterGPUMemoryManager(this); RegisterGPUMemoryManager(this);

View File

@ -16,88 +16,6 @@ VK_DEFINE_HANDLE(VmaAllocation);
// //
// Vulkan memory management utils. // Vulkan memory management utils.
// VulkanPushBuffer
// Simple incrementing allocator.
// Use these to push vertex, index and uniform data. Generally you'll have two or three of these
// and alternate on each frame. Make sure not to reset until the fence from the last time you used it
// has completed.
// NOTE: This has now been replaced with VulkanPushPool for all uses except the vertex cache.
class VulkanPushBuffer : public GPUMemoryManager {
struct BufInfo {
VkBuffer buffer;
VmaAllocation allocation;
};
public:
// NOTE: If you create a push buffer with PushBufferType::GPU_ONLY,
// then you can't use any of the push functions as pointers will not be reachable from the CPU.
// You must in this case use Allocate() only, and pass the returned offset and the VkBuffer to Vulkan APIs.
VulkanPushBuffer(VulkanContext *vulkan, const char *name, size_t size, VkBufferUsageFlags usage);
~VulkanPushBuffer();
void Destroy(VulkanContext *vulkan);
void Reset() { offset_ = 0; }
void GetDebugString(char *buffer, size_t bufSize) const override;
const char *Name() const override {
return name_;
}
// Needs context in case of defragment.
void Begin(VulkanContext *vulkan) {
buf_ = 0;
offset_ = 0;
// Note: we must defrag because some buffers may be smaller than size_.
Defragment(vulkan);
Map();
}
void BeginNoReset() { Map(); }
void End() { Unmap(); }
void Map();
void Unmap();
// When using the returned memory, make sure to bind the returned vkbuf.
uint8_t *Allocate(VkDeviceSize numBytes, VkDeviceSize alignment, VkBuffer *vkbuf, uint32_t *bindOffset) {
size_t offset = (offset_ + alignment - 1) & ~(alignment - 1);
if (offset + numBytes > size_) {
NextBuffer(numBytes);
offset = offset_;
}
offset_ = offset + numBytes;
*bindOffset = (uint32_t)offset;
*vkbuf = buffers_[buf_].buffer;
return writePtr_ + offset;
}
VkDeviceSize Push(const void *data, VkDeviceSize numBytes, int alignment, VkBuffer *vkbuf) {
uint32_t bindOffset;
uint8_t *ptr = Allocate(numBytes, alignment, vkbuf, &bindOffset);
memcpy(ptr, data, numBytes);
return bindOffset;
}
size_t GetOffset() const { return offset_; }
size_t GetTotalSize() const;
private:
bool AddBuffer();
void NextBuffer(size_t minSize);
void Defragment(VulkanContext *vulkan);
VulkanContext *vulkan_;
std::vector<BufInfo> buffers_;
size_t buf_ = 0;
size_t offset_ = 0;
size_t size_ = 0;
uint8_t *writePtr_ = nullptr;
VkBufferUsageFlags usage_;
const char *name_;
};
// Simple memory pushbuffer pool that can share blocks between the "frames", to reduce the impact of push memory spikes - // Simple memory pushbuffer pool that can share blocks between the "frames", to reduce the impact of push memory spikes -
// a later frame can gobble up redundant buffers from an earlier frame even if they don't share frame index. // a later frame can gobble up redundant buffers from an earlier frame even if they don't share frame index.
// NOT thread safe! Can only be used from one thread (our main thread). // NOT thread safe! Can only be used from one thread (our main thread).

View File

@ -590,7 +590,6 @@ static const ConfigSetting graphicsSettings[] = {
ConfigSetting("AnisotropyLevel", &g_Config.iAnisotropyLevel, 4, CfgFlag::PER_GAME), ConfigSetting("AnisotropyLevel", &g_Config.iAnisotropyLevel, 4, CfgFlag::PER_GAME),
ConfigSetting("MultiSampleLevel", &g_Config.iMultiSampleLevel, 0, CfgFlag::PER_GAME), // Number of samples is 1 << iMultiSampleLevel ConfigSetting("MultiSampleLevel", &g_Config.iMultiSampleLevel, 0, CfgFlag::PER_GAME), // Number of samples is 1 << iMultiSampleLevel
ConfigSetting("VertexDecCache", &g_Config.bVertexCache, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("TextureBackoffCache", &g_Config.bTextureBackoffCache, false, CfgFlag::PER_GAME | CfgFlag::REPORT), ConfigSetting("TextureBackoffCache", &g_Config.bTextureBackoffCache, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("VertexDecJit", &g_Config.bVertexDecoderJit, &DefaultCodeGen, CfgFlag::DONT_SAVE | CfgFlag::REPORT), ConfigSetting("VertexDecJit", &g_Config.bVertexDecoderJit, &DefaultCodeGen, CfgFlag::DONT_SAVE | CfgFlag::REPORT),

View File

@ -176,7 +176,6 @@ public:
float fUITint; float fUITint;
float fUISaturation; float fUISaturation;
bool bVertexCache;
bool bTextureBackoffCache; bool bTextureBackoffCache;
bool bVertexDecoderJit; bool bVertexDecoderJit;
bool bFullScreen; bool bFullScreen;

View File

@ -575,80 +575,6 @@ void DrawEngineCommon::ApplyFramebufferRead(FBOTexState *fboTexState) {
gstate_c.Dirty(DIRTY_SHADERBLEND); gstate_c.Dirty(DIRTY_SHADERBLEND);
} }
inline u32 ComputeMiniHashRange(const void *ptr, size_t sz) {
// Switch to u32 units, and round up to avoid unaligned accesses.
// Probably doesn't matter if we skip the first few bytes in some cases.
const u32 *p = (const u32 *)(((uintptr_t)ptr + 3) & ~3);
sz >>= 2;
if (sz > 100) {
size_t step = sz / 4;
u32 hash = 0;
for (size_t i = 0; i < sz; i += step) {
hash += XXH3_64bits(p + i, 100);
}
return hash;
} else {
return p[0] + p[sz - 1];
}
}
u32 DrawEngineCommon::ComputeMiniHash() {
u32 fullhash = 0;
const int vertexSize = dec_->GetDecVtxFmt().stride;
const int indexSize = IndexSize(dec_->VertexType());
int step;
if (numDrawVerts_ < 3) {
step = 1;
} else if (numDrawVerts_ < 8) {
step = 4;
} else {
step = numDrawVerts_ / 8;
}
for (int i = 0; i < numDrawVerts_; i += step) {
const DeferredVerts &dc = drawVerts_[i];
fullhash += ComputeMiniHashRange((const u8 *)dc.verts + vertexSize * dc.indexLowerBound, vertexSize * (dc.indexUpperBound - dc.indexLowerBound));
}
for (int i = 0; i < numDrawInds_; i += step) {
const DeferredInds &di = drawInds_[i];
if (di.indexType != 0) {
fullhash += ComputeMiniHashRange(di.inds, indexSize * di.vertexCount);
}
}
return fullhash;
}
// Cheap bit scrambler from https://nullprogram.com/blog/2018/07/31/
inline uint32_t lowbias32_r(uint32_t x) {
x ^= x >> 16;
x *= 0x43021123U;
x ^= x >> 15 ^ x >> 30;
x *= 0x1d69e2a5U;
x ^= x >> 16;
return x;
}
uint32_t DrawEngineCommon::ComputeDrawcallsHash() const {
uint32_t dcid = 0;
for (int i = 0; i < numDrawVerts_; i++) {
u32 dhash = dcid;
dhash = __rotl(dhash ^ (u32)(uintptr_t)drawVerts_[i].verts, 13);
dhash = __rotl(dhash ^ (u32)drawInds_[i].vertexCount, 11);
dcid = lowbias32_r(dhash ^ (u32)drawInds_[i].prim);
}
for (int i = 0; i < numDrawInds_; i++) {
const DeferredInds &di = drawInds_[i];
u32 dhash = dcid;
if (di.indexType) {
dhash = __rotl(dhash ^ (u32)(uintptr_t)di.inds, 19);
dcid = lowbias32_r(__rotl(dhash ^ (u32)di.indexType, 7));
}
}
return dcid;
}
int DrawEngineCommon::ComputeNumVertsToDecode() const { int DrawEngineCommon::ComputeNumVertsToDecode() const {
int sum = 0; int sum = 0;
for (int i = 0; i < numDrawVerts_; i++) { for (int i = 0; i < numDrawVerts_; i++) {
@ -657,32 +583,6 @@ int DrawEngineCommon::ComputeNumVertsToDecode() const {
return sum; return sum;
} }
uint64_t DrawEngineCommon::ComputeHash() {
uint64_t fullhash = 0;
const int vertexSize = dec_->GetDecVtxFmt().stride;
// TODO: Add some caps both for numDrawCalls_ and num verts to check?
// It is really very expensive to check all the vertex data so often.
for (int i = 0; i < numDrawVerts_; i++) {
const DeferredVerts &dv = drawVerts_[i];
int indexLowerBound = dv.indexLowerBound, indexUpperBound = dv.indexUpperBound;
fullhash += XXH3_64bits((const char *)dv.verts + vertexSize * indexLowerBound, vertexSize * (indexUpperBound - indexLowerBound));
}
for (int i = 0; i < numDrawInds_; i++) {
const DeferredInds &di = drawInds_[i];
if (di.indexType != 0) {
int indexSize = IndexSize(di.indexType << GE_VTYPE_IDX_SHIFT);
// Hm, we will miss some indices when combining above, but meh, it should be fine.
fullhash += XXH3_64bits((const char *)di.inds, indexSize * di.vertexCount);
}
}
// this looks utterly broken??
// fullhash += XXH3_64bits(&drawCalls_[0].uvScale, sizeof(drawCalls_[0].uvScale) * numDrawCalls_);
return fullhash;
}
int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *stall, u32 vertTypeID, bool clockwise, int *bytesRead, bool isTriangle) { int DrawEngineCommon::ExtendNonIndexedPrim(const uint32_t *cmd, const uint32_t *stall, u32 vertTypeID, bool clockwise, int *bytesRead, bool isTriangle) {
const uint32_t *start = cmd; const uint32_t *start = cmd;
int prevDrawVerts = numDrawVerts_ - 1; int prevDrawVerts = numDrawVerts_ - 1;

View File

@ -159,10 +159,6 @@ protected:
// Preprocessing for spline/bezier // Preprocessing for spline/bezier
u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize = nullptr); u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType, int *vertexSize = nullptr);
// Utility for vertex caching
u32 ComputeMiniHash();
uint64_t ComputeHash();
int ComputeNumVertsToDecode() const; int ComputeNumVertsToDecode() const;
void ApplyFramebufferRead(FBOTexState *fboTexState); void ApplyFramebufferRead(FBOTexState *fboTexState);
@ -271,7 +267,6 @@ protected:
int numDrawInds_ = 0; int numDrawInds_ = 0;
int vertexCountInDrawCalls_ = 0; int vertexCountInDrawCalls_ = 0;
int decimationCounter_ = 0;
int decodeVertsCounter_ = 0; int decodeVertsCounter_ = 0;
int decodeIndsCounter_ = 0; int decodeIndsCounter_ = 0;

View File

@ -53,9 +53,6 @@ const D3D11_PRIMITIVE_TOPOLOGY d3d11prim[8] = {
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // Need expansion - though we could do it with geom shaders in most cases D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // Need expansion - though we could do it with geom shaders in most cases
}; };
#define VERTEXCACHE_DECIMATION_INTERVAL 17
enum { VAI_KILL_AGE = 120, VAI_UNRELIABLE_KILL_AGE = 240, VAI_UNRELIABLE_KILL_MAX = 4 };
enum { enum {
VERTEX_PUSH_SIZE = 1024 * 1024 * 16, VERTEX_PUSH_SIZE = 1024 * 1024 * 16,
INDEX_PUSH_SIZE = 1024 * 1024 * 4, INDEX_PUSH_SIZE = 1024 * 1024 * 4,
@ -73,7 +70,6 @@ DrawEngineD3D11::DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device,
: draw_(draw), : draw_(draw),
device_(device), device_(device),
context_(context), context_(context),
vai_(256),
inputLayoutMap_(32), inputLayoutMap_(32),
blendCache_(32), blendCache_(32),
blendCache1_(32), blendCache1_(32),
@ -84,7 +80,6 @@ DrawEngineD3D11::DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device,
decOptions_.expandAllWeightsToFloat = true; decOptions_.expandAllWeightsToFloat = true;
decOptions_.expand8BitNormalsToFloat = true; decOptions_.expand8BitNormalsToFloat = true;
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
// Allocate nicely aligned memory. Maybe graphics drivers will // Allocate nicely aligned memory. Maybe graphics drivers will
// appreciate it. // appreciate it.
// All this is a LOT of memory, need to see if we can cut down somehow. // All this is a LOT of memory, need to see if we can cut down somehow.
@ -111,13 +106,6 @@ void DrawEngineD3D11::InitDeviceObjects() {
draw_->SetInvalidationCallback(std::bind(&DrawEngineD3D11::Invalidate, this, std::placeholders::_1)); draw_->SetInvalidationCallback(std::bind(&DrawEngineD3D11::Invalidate, this, std::placeholders::_1));
} }
void DrawEngineD3D11::ClearTrackedVertexArrays() {
vai_.Iterate([&](uint32_t hash, VertexArrayInfoD3D11 *vai){
delete vai;
});
vai_.Clear();
}
void DrawEngineD3D11::ClearInputLayoutMap() { void DrawEngineD3D11::ClearInputLayoutMap() {
inputLayoutMap_.Iterate([&](const InputLayoutKey &key, ID3D11InputLayout *il) { inputLayoutMap_.Iterate([&](const InputLayoutKey &key, ID3D11InputLayout *il) {
if (il) if (il)
@ -259,69 +247,13 @@ ID3D11InputLayout *DrawEngineD3D11::SetupDecFmtForDraw(D3D11VertexShader *vshade
} }
} }
void DrawEngineD3D11::MarkUnreliable(VertexArrayInfoD3D11 *vai) {
vai->status = VertexArrayInfoD3D11::VAI_UNRELIABLE;
if (vai->vbo) {
vai->vbo->Release();
vai->vbo = nullptr;
}
if (vai->ebo) {
vai->ebo->Release();
vai->ebo = nullptr;
}
}
void DrawEngineD3D11::BeginFrame() { void DrawEngineD3D11::BeginFrame() {
pushVerts_->Reset(); pushVerts_->Reset();
pushInds_->Reset(); pushInds_->Reset();
gpuStats.numTrackedVertexArrays = (int)vai_.size();
if (--decimationCounter_ <= 0) {
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
} else {
return;
}
const int threshold = gpuStats.numFlips - VAI_KILL_AGE;
const int unreliableThreshold = gpuStats.numFlips - VAI_UNRELIABLE_KILL_AGE;
int unreliableLeft = VAI_UNRELIABLE_KILL_MAX;
vai_.Iterate([&](uint32_t hash, VertexArrayInfoD3D11 *vai){
bool kill;
if (vai->status == VertexArrayInfoD3D11::VAI_UNRELIABLE) {
// We limit killing unreliable so we don't rehash too often.
kill = vai->lastFrame < unreliableThreshold && --unreliableLeft >= 0;
} else {
kill = vai->lastFrame < threshold;
}
if (kill) {
delete vai;
vai_.Remove(hash);
}
});
vai_.Maintain();
// Enable if you want to see vertex decoders in the log output. Need a better way.
#if 0
char buffer[16384];
for (std::map<u32, VertexDecoder*>::iterator dec = decoderMap_.begin(); dec != decoderMap_.end(); ++dec) {
char *ptr = buffer;
ptr += dec->second->ToString(ptr);
// *ptr++ = '\n';
NOTICE_LOG(G3D, buffer);
}
#endif
lastRenderStepId_ = -1; lastRenderStepId_ = -1;
} }
VertexArrayInfoD3D11::~VertexArrayInfoD3D11() {
if (vbo)
vbo->Release();
if (ebo)
ebo->Release();
}
// In D3D, we're synchronous and state carries over so all we reset here on a new step is the viewport/scissor. // In D3D, we're synchronous and state carries over so all we reset here on a new step is the viewport/scissor.
void DrawEngineD3D11::Invalidate(InvalidationCallbackFlags flags) { void DrawEngineD3D11::Invalidate(InvalidationCallbackFlags flags) {
if (flags & InvalidationCallbackFlags::RENDER_PASS_STATE) { if (flags & InvalidationCallbackFlags::RENDER_PASS_STATE) {
@ -354,175 +286,16 @@ void DrawEngineD3D11::DoFlush() {
ID3D11Buffer *vb_ = nullptr; ID3D11Buffer *vb_ = nullptr;
ID3D11Buffer *ib_ = nullptr; ID3D11Buffer *ib_ = nullptr;
int vertexCount = 0;
int maxIndex = 0;
bool useElements = true;
// Cannot cache vertex data with morph enabled.
bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK);
// Also avoid caching when software skinning.
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK))
useCache = false;
if (useCache) {
// getUVGenMode can have an effect on which UV decoder we need to use! And hence what the decoded data will look like. See #9263
u32 dcid = ComputeDrawcallsHash() ^ gstate.getUVGenMode();
VertexArrayInfoD3D11 *vai;
if (!vai_.Get(dcid, &vai)) {
vai = new VertexArrayInfoD3D11();
vai_.Insert(dcid, vai);
}
switch (vai->status) {
case VertexArrayInfoD3D11::VAI_NEW:
{
// Haven't seen this one before.
uint64_t dataHash = ComputeHash();
vai->hash = dataHash;
vai->minihash = ComputeMiniHash();
vai->status = VertexArrayInfoD3D11::VAI_HASHING;
vai->drawsUntilNextFullHash = 0;
DecodeVerts(decoded_); // writes to indexGen
DecodeInds();
vai->numVerts = indexGen.VertexCount();
vai->prim = indexGen.Prim();
vai->maxIndex = MaxIndex();
vai->flags = gstate_c.vertexFullAlpha ? VAI11_FLAG_VERTEXFULLALPHA : 0;
goto rotateVBO;
}
// Hashing - still gaining confidence about the buffer.
// But if we get this far it's likely to be worth creating a vertex buffer.
case VertexArrayInfoD3D11::VAI_HASHING:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
if (vai->drawsUntilNextFullHash == 0) {
// Let's try to skip a full hash if mini would fail.
const u32 newMiniHash = ComputeMiniHash();
uint64_t newHash = vai->hash;
if (newMiniHash == vai->minihash) {
newHash = ComputeHash();
}
if (newMiniHash != vai->minihash || newHash != vai->hash) {
MarkUnreliable(vai);
DecodeVerts(decoded_); DecodeVerts(decoded_);
DecodeInds(); DecodeInds();
goto rotateVBO;
}
if (vai->numVerts > 64) {
// exponential backoff up to 16 draws, then every 24
vai->drawsUntilNextFullHash = std::min(24, vai->numFrames);
} else {
// Lower numbers seem much more likely to change.
vai->drawsUntilNextFullHash = 0;
}
// TODO: tweak
//if (vai->numFrames > 1000) {
// vai->status = VertexArrayInfo::VAI_RELIABLE;
//}
} else {
vai->drawsUntilNextFullHash--;
u32 newMiniHash = ComputeMiniHash();
if (newMiniHash != vai->minihash) {
MarkUnreliable(vai);
DecodeVerts(decoded_);
DecodeInds();
goto rotateVBO;
}
}
if (vai->vbo == 0) {
DecodeVerts(decoded_);
DecodeInds();
vai->numVerts = indexGen.VertexCount();
vai->prim = indexGen.Prim();
vai->maxIndex = MaxIndex();
vai->flags = gstate_c.vertexFullAlpha ? VAI11_FLAG_VERTEXFULLALPHA : 0;
useElements = !indexGen.SeenOnlyPurePrims() || prim == GE_PRIM_TRIANGLE_FAN;
if (!useElements && indexGen.PureCount()) {
vai->numVerts = indexGen.PureCount();
}
_dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching.");
// TODO: Combine these two into one buffer?
u32 size = dec_->GetDecVtxFmt().stride * MaxIndex();
D3D11_BUFFER_DESC desc{ size, D3D11_USAGE_IMMUTABLE, D3D11_BIND_VERTEX_BUFFER, 0 };
D3D11_SUBRESOURCE_DATA data{ decoded_ };
ASSERT_SUCCESS(device_->CreateBuffer(&desc, &data, &vai->vbo));
if (useElements) {
u32 size = sizeof(short) * indexGen.VertexCount();
D3D11_BUFFER_DESC desc{ size, D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0 };
D3D11_SUBRESOURCE_DATA data{ decIndex_ };
ASSERT_SUCCESS(device_->CreateBuffer(&desc, &data, &vai->ebo));
} else {
vai->ebo = 0;
}
} else {
gpuStats.numCachedDrawCalls++;
useElements = vai->ebo ? true : false;
gpuStats.numCachedVertsDrawn += vai->numVerts;
gstate_c.vertexFullAlpha = vai->flags & VAI11_FLAG_VERTEXFULLALPHA;
}
vb_ = vai->vbo;
ib_ = vai->ebo;
vertexCount = vai->numVerts;
maxIndex = vai->maxIndex;
prim = static_cast<GEPrimitiveType>(vai->prim);
break;
}
// Reliable - we don't even bother hashing anymore. Right now we don't go here until after a very long time.
case VertexArrayInfoD3D11::VAI_RELIABLE:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
gpuStats.numCachedDrawCalls++;
gpuStats.numCachedVertsDrawn += vai->numVerts;
vb_ = vai->vbo;
ib_ = vai->ebo;
vertexCount = vai->numVerts;
maxIndex = vai->maxIndex;
prim = static_cast<GEPrimitiveType>(vai->prim);
gstate_c.vertexFullAlpha = vai->flags & VAI11_FLAG_VERTEXFULLALPHA;
break;
}
case VertexArrayInfoD3D11::VAI_UNRELIABLE:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
DecodeVerts(decoded_);
DecodeInds();
goto rotateVBO;
}
}
vai->lastFrame = gpuStats.numFlips;
} else {
DecodeVerts(decoded_);
DecodeInds();
rotateVBO:
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
useElements = !indexGen.SeenOnlyPurePrims() || prim == GE_PRIM_TRIANGLE_FAN; bool useElements = !indexGen.SeenOnlyPurePrims() || prim == GE_PRIM_TRIANGLE_FAN;
vertexCount = indexGen.VertexCount(); int vertexCount = indexGen.VertexCount();
maxIndex = MaxIndex(); int maxIndex = MaxIndex();
if (!useElements && indexGen.PureCount()) { if (!useElements && indexGen.PureCount()) {
vertexCount = indexGen.PureCount(); vertexCount = indexGen.PureCount();
} }
prim = indexGen.Prim(); prim = indexGen.Prim();
}
bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE; bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE;
if (gstate.isModeThrough()) { if (gstate.isModeThrough()) {

View File

@ -38,65 +38,6 @@ class ShaderManagerD3D11;
class TextureCacheD3D11; class TextureCacheD3D11;
class FramebufferManagerD3D11; class FramebufferManagerD3D11;
// States transitions:
// On creation: DRAWN_NEW
// DRAWN_NEW -> DRAWN_HASHING
// DRAWN_HASHING -> DRAWN_RELIABLE
// DRAWN_HASHING -> DRAWN_UNRELIABLE
// DRAWN_ONCE -> UNRELIABLE
// DRAWN_RELIABLE -> DRAWN_SAFE
// UNRELIABLE -> death
// DRAWN_ONCE -> death
// DRAWN_RELIABLE -> death
enum {
VAI11_FLAG_VERTEXFULLALPHA = 1,
};
// Try to keep this POD.
class VertexArrayInfoD3D11 {
public:
VertexArrayInfoD3D11() {
status = VAI_NEW;
vbo = 0;
ebo = 0;
prim = GE_PRIM_INVALID;
numDraws = 0;
numFrames = 0;
lastFrame = gpuStats.numFlips;
numVerts = 0;
drawsUntilNextFullHash = 0;
flags = 0;
}
~VertexArrayInfoD3D11();
enum Status : uint8_t {
VAI_NEW,
VAI_HASHING,
VAI_RELIABLE, // cache, don't hash
VAI_UNRELIABLE, // never cache
};
uint64_t hash;
u32 minihash;
ID3D11Buffer *vbo;
ID3D11Buffer *ebo;
// Precalculated parameter for drawRangeElements
u16 numVerts;
u16 maxIndex;
s8 prim;
Status status;
// ID information
int numDraws;
int numFrames;
int lastFrame; // So that we can forget.
u16 drawsUntilNextFullHash;
u8 flags;
};
class TessellationDataTransferD3D11 : public TessellationDataTransfer { class TessellationDataTransferD3D11 : public TessellationDataTransfer {
private: private:
ID3D11DeviceContext *context_; ID3D11DeviceContext *context_;
@ -155,8 +96,6 @@ public:
Flush(); Flush();
} }
void ClearTrackedVertexArrays() override;
void NotifyConfigChanged() override; void NotifyConfigChanged() override;
void ClearInputLayoutMap(); void ClearInputLayoutMap();
@ -171,16 +110,12 @@ private:
ID3D11InputLayout *SetupDecFmtForDraw(D3D11VertexShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt); ID3D11InputLayout *SetupDecFmtForDraw(D3D11VertexShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
void MarkUnreliable(VertexArrayInfoD3D11 *vai);
Draw::DrawContext *draw_; // Used for framebuffer related things exclusively. Draw::DrawContext *draw_; // Used for framebuffer related things exclusively.
ID3D11Device *device_; ID3D11Device *device_;
ID3D11Device1 *device1_; ID3D11Device1 *device1_;
ID3D11DeviceContext *context_; ID3D11DeviceContext *context_;
ID3D11DeviceContext1 *context1_; ID3D11DeviceContext1 *context1_;
PrehashMap<VertexArrayInfoD3D11 *> vai_;
struct InputLayoutKey { struct InputLayoutKey {
D3D11VertexShader *vshader; D3D11VertexShader *vshader;
u32 decFmtId; u32 decFmtId;

View File

@ -72,10 +72,6 @@ enum {
TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex) TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex)
}; };
#define VERTEXCACHE_DECIMATION_INTERVAL 17
enum { VAI_KILL_AGE = 120, VAI_UNRELIABLE_KILL_AGE = 240, VAI_UNRELIABLE_KILL_MAX = 4 };
static const D3DVERTEXELEMENT9 TransformedVertexElements[] = { static const D3DVERTEXELEMENT9 TransformedVertexElements[] = {
{ 0, offsetof(TransformedVertex, pos), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, offsetof(TransformedVertex, pos), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, offsetof(TransformedVertex, uv), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, offsetof(TransformedVertex, uv), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
@ -85,13 +81,11 @@ static const D3DVERTEXELEMENT9 TransformedVertexElements[] = {
D3DDECL_END() D3DDECL_END()
}; };
DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : draw_(draw), vai_(256), vertexDeclMap_(64) { DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : draw_(draw), vertexDeclMap_(64) {
device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE); device_ = (LPDIRECT3DDEVICE9)draw->GetNativeObject(Draw::NativeObject::DEVICE);
decOptions_.expandAllWeightsToFloat = true; decOptions_.expandAllWeightsToFloat = true;
decOptions_.expand8BitNormalsToFloat = true; decOptions_.expand8BitNormalsToFloat = true;
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
indexGen.Setup(decIndex_); indexGen.Setup(decIndex_);
InitDeviceObjects(); InitDeviceObjects();
@ -227,80 +221,11 @@ IDirect3DVertexDeclaration9 *DrawEngineDX9::SetupDecFmtForDraw(const DecVtxForma
} }
} }
void DrawEngineDX9::MarkUnreliable(VertexArrayInfoDX9 *vai) {
vai->status = VertexArrayInfoDX9::VAI_UNRELIABLE;
if (vai->vbo) {
vai->vbo->Release();
vai->vbo = nullptr;
}
if (vai->ebo) {
vai->ebo->Release();
vai->ebo = nullptr;
}
}
void DrawEngineDX9::ClearTrackedVertexArrays() {
vai_.Iterate([&](uint32_t hash, VertexArrayInfoDX9 *vai) {
delete vai;
});
vai_.Clear();
}
void DrawEngineDX9::DecimateTrackedVertexArrays() {
if (--decimationCounter_ <= 0) {
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
} else {
return;
}
const int threshold = gpuStats.numFlips - VAI_KILL_AGE;
const int unreliableThreshold = gpuStats.numFlips - VAI_UNRELIABLE_KILL_AGE;
int unreliableLeft = VAI_UNRELIABLE_KILL_MAX;
vai_.Iterate([&](uint32_t hash, VertexArrayInfoDX9 *vai) {
bool kill;
if (vai->status == VertexArrayInfoDX9::VAI_UNRELIABLE) {
// We limit killing unreliable so we don't rehash too often.
kill = vai->lastFrame < unreliableThreshold && --unreliableLeft >= 0;
} else {
kill = vai->lastFrame < threshold;
}
if (kill) {
delete vai;
vai_.Remove(hash);
}
});
vai_.Maintain();
// Enable if you want to see vertex decoders in the log output. Need a better way.
#if 0
char buffer[16384];
for (std::map<u32, VertexDecoder*>::iterator dec = decoderMap_.begin(); dec != decoderMap_.end(); ++dec) {
char *ptr = buffer;
ptr += dec->second->ToString(ptr);
// *ptr++ = '\n';
NOTICE_LOG(G3D, buffer);
}
#endif
}
VertexArrayInfoDX9::~VertexArrayInfoDX9() {
if (vbo) {
vbo->Release();
}
if (ebo) {
ebo->Release();
}
}
static uint32_t SwapRB(uint32_t c) { static uint32_t SwapRB(uint32_t c) {
return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000); return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000);
} }
void DrawEngineDX9::BeginFrame() { void DrawEngineDX9::BeginFrame() {
gpuStats.numTrackedVertexArrays = (int)vai_.size();
DecimateTrackedVertexArrays();
lastRenderStepId_ = -1; lastRenderStepId_ = -1;
} }
@ -336,166 +261,9 @@ void DrawEngineDX9::DoFlush() {
int vertexCount = 0; int vertexCount = 0;
int maxIndex = 0; int maxIndex = 0;
bool useElements = true; bool useElements = true;
// Cannot cache vertex data with morph enabled.
bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK);
// Also avoid caching when software skinning.
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK))
useCache = false;
if (useCache) {
// getUVGenMode can have an effect on which UV decoder we need to use! And hence what the decoded data will look like. See #9263
u32 dcid = ComputeDrawcallsHash() ^ gstate.getUVGenMode();
VertexArrayInfoDX9 *vai;
if (!vai_.Get(dcid, &vai)) {
vai = new VertexArrayInfoDX9();
vai_.Insert(dcid, vai);
}
switch (vai->status) {
case VertexArrayInfoDX9::VAI_NEW:
{ {
// Haven't seen this one before.
uint64_t dataHash = ComputeHash();
vai->hash = dataHash;
vai->minihash = ComputeMiniHash();
vai->status = VertexArrayInfoDX9::VAI_HASHING;
vai->drawsUntilNextFullHash = 0;
DecodeVerts(decoded_); // writes to indexGen
DecodeInds();
vai->numVerts = indexGen.VertexCount();
vai->prim = indexGen.Prim();
vai->maxIndex = MaxIndex();
vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0;
goto rotateVBO;
}
// Hashing - still gaining confidence about the buffer.
// But if we get this far it's likely to be worth creating a vertex buffer.
case VertexArrayInfoDX9::VAI_HASHING:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
if (vai->drawsUntilNextFullHash == 0) {
// Let's try to skip a full hash if mini would fail.
const u32 newMiniHash = ComputeMiniHash();
uint64_t newHash = vai->hash;
if (newMiniHash == vai->minihash) {
newHash = ComputeHash();
}
if (newMiniHash != vai->minihash || newHash != vai->hash) {
MarkUnreliable(vai);
DecodeVerts(decoded_); DecodeVerts(decoded_);
DecodeInds(); DecodeInds();
goto rotateVBO;
}
if (vai->numVerts > 64) {
// exponential backoff up to 16 draws, then every 24
vai->drawsUntilNextFullHash = std::min(24, vai->numFrames);
} else {
// Lower numbers seem much more likely to change.
vai->drawsUntilNextFullHash = 0;
}
// TODO: tweak
//if (vai->numFrames > 1000) {
// vai->status = VertexArrayInfo::VAI_RELIABLE;
//}
} else {
vai->drawsUntilNextFullHash--;
u32 newMiniHash = ComputeMiniHash();
if (newMiniHash != vai->minihash) {
MarkUnreliable(vai);
DecodeVerts(decoded_);
DecodeInds();
goto rotateVBO;
}
}
if (vai->vbo == 0) {
DecodeVerts(decoded_);
DecodeInds();
vai->numVerts = indexGen.VertexCount();
vai->prim = indexGen.Prim();
vai->maxIndex = MaxIndex();
vai->flags = gstate_c.vertexFullAlpha ? VAI_FLAG_VERTEXFULLALPHA : 0;
useElements = !indexGen.SeenOnlyPurePrims();
if (!useElements && indexGen.PureCount()) {
vai->numVerts = indexGen.PureCount();
}
_dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching.");
void * pVb;
u32 size = dec_->GetDecVtxFmt().stride * MaxIndex();
device_->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &vai->vbo, NULL);
vai->vbo->Lock(0, size, &pVb, 0);
memcpy(pVb, decoded_, size);
vai->vbo->Unlock();
if (useElements) {
void * pIb;
u32 size = sizeof(short) * indexGen.VertexCount();
device_->CreateIndexBuffer(size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &vai->ebo, NULL);
vai->ebo->Lock(0, size, &pIb, 0);
memcpy(pIb, decIndex_, size);
vai->ebo->Unlock();
} else {
vai->ebo = 0;
}
} else {
gpuStats.numCachedDrawCalls++;
useElements = vai->ebo ? true : false;
gpuStats.numCachedVertsDrawn += vai->numVerts;
gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA;
}
vb_ = vai->vbo;
ib_ = vai->ebo;
vertexCount = vai->numVerts;
maxIndex = vai->maxIndex;
prim = static_cast<GEPrimitiveType>(vai->prim);
break;
}
// Reliable - we don't even bother hashing anymore. Right now we don't go here until after a very long time.
case VertexArrayInfoDX9::VAI_RELIABLE:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
gpuStats.numCachedDrawCalls++;
gpuStats.numCachedVertsDrawn += vai->numVerts;
vb_ = vai->vbo;
ib_ = vai->ebo;
vertexCount = vai->numVerts;
maxIndex = vai->maxIndex;
prim = static_cast<GEPrimitiveType>(vai->prim);
gstate_c.vertexFullAlpha = vai->flags & VAI_FLAG_VERTEXFULLALPHA;
break;
}
case VertexArrayInfoDX9::VAI_UNRELIABLE:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
DecodeVerts(decoded_);
DecodeInds();
goto rotateVBO;
}
}
vai->lastFrame = gpuStats.numFlips;
} else {
DecodeVerts(decoded_);
DecodeInds();
rotateVBO:
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
useElements = !indexGen.SeenOnlyPurePrims(); useElements = !indexGen.SeenOnlyPurePrims();
vertexCount = indexGen.VertexCount(); vertexCount = indexGen.VertexCount();

View File

@ -35,65 +35,6 @@ class ShaderManagerDX9;
class TextureCacheDX9; class TextureCacheDX9;
class FramebufferManagerDX9; class FramebufferManagerDX9;
// States transitions:
// On creation: DRAWN_NEW
// DRAWN_NEW -> DRAWN_HASHING
// DRAWN_HASHING -> DRAWN_RELIABLE
// DRAWN_HASHING -> DRAWN_UNRELIABLE
// DRAWN_ONCE -> UNRELIABLE
// DRAWN_RELIABLE -> DRAWN_SAFE
// UNRELIABLE -> death
// DRAWN_ONCE -> death
// DRAWN_RELIABLE -> death
enum {
VAI_FLAG_VERTEXFULLALPHA = 1,
};
// Try to keep this POD.
class VertexArrayInfoDX9 {
public:
VertexArrayInfoDX9() {
status = VAI_NEW;
vbo = 0;
ebo = 0;
prim = GE_PRIM_INVALID;
numDraws = 0;
numFrames = 0;
lastFrame = gpuStats.numFlips;
numVerts = 0;
drawsUntilNextFullHash = 0;
flags = 0;
}
~VertexArrayInfoDX9();
enum Status : uint8_t {
VAI_NEW,
VAI_HASHING,
VAI_RELIABLE, // cache, don't hash
VAI_UNRELIABLE, // never cache
};
uint64_t hash;
u32 minihash;
LPDIRECT3DVERTEXBUFFER9 vbo;
LPDIRECT3DINDEXBUFFER9 ebo;
// Precalculated parameter for drawRangeElements
u16 numVerts;
u16 maxIndex;
s8 prim;
Status status;
// ID information
int numDraws;
int numFrames;
int lastFrame; // So that we can forget.
u16 drawsUntilNextFullHash;
u8 flags;
};
class TessellationDataTransferDX9 : public TessellationDataTransfer { class TessellationDataTransferDX9 : public TessellationDataTransfer {
public: public:
TessellationDataTransferDX9() {} TessellationDataTransferDX9() {}
@ -122,8 +63,6 @@ public:
void InitDeviceObjects(); void InitDeviceObjects();
void DestroyDeviceObjects(); void DestroyDeviceObjects();
void ClearTrackedVertexArrays() override;
void BeginFrame(); void BeginFrame();
// So that this can be inlined // So that this can be inlined
@ -148,7 +87,6 @@ public:
protected: protected:
// Not currently supported. // Not currently supported.
bool UpdateUseHWTessellation(bool enable) const override { return false; } bool UpdateUseHWTessellation(bool enable) const override { return false; }
void DecimateTrackedVertexArrays();
private: private:
void Invalidate(InvalidationCallbackFlags flags); void Invalidate(InvalidationCallbackFlags flags);
@ -159,12 +97,9 @@ private:
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt); IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt);
void MarkUnreliable(VertexArrayInfoDX9 *vai);
LPDIRECT3DDEVICE9 device_ = nullptr; LPDIRECT3DDEVICE9 device_ = nullptr;
Draw::DrawContext *draw_; Draw::DrawContext *draw_;
PrehashMap<VertexArrayInfoDX9 *> vai_;
DenseHashMap<u32, IDirect3DVertexDeclaration9 *> vertexDeclMap_; DenseHashMap<u32, IDirect3DVertexDeclaration9 *> vertexDeclMap_;
// SimpleVertex // SimpleVertex

View File

@ -44,7 +44,7 @@
#include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/ShaderManagerGLES.h"
#include "GPU/GLES/GPU_GLES.h" #include "GPU/GLES/GPU_GLES.h"
const GLuint glprim[8] = { static const GLuint glprim[8] = {
// Points, which are expanded to triangles. // Points, which are expanded to triangles.
GL_TRIANGLES, GL_TRIANGLES,
// Lines and line strips, which are also expanded to triangles. // Lines and line strips, which are also expanded to triangles.
@ -149,8 +149,6 @@ void DrawEngineGLES::ClearInputLayoutMap() {
} }
void DrawEngineGLES::BeginFrame() { void DrawEngineGLES::BeginFrame() {
gpuStats.numTrackedVertexArrays = 0;
FrameData &frameData = frameData_[render_->GetCurFrame()]; FrameData &frameData = frameData_[render_->GetCurFrame()];
render_->BeginPushBuffer(frameData.pushIndex); render_->BeginPushBuffer(frameData.pushIndex);
render_->BeginPushBuffer(frameData.pushVertex); render_->BeginPushBuffer(frameData.pushVertex);

View File

@ -78,11 +78,8 @@ struct GPUStatistics {
numVertexDecodes = 0; numVertexDecodes = 0;
numDrawSyncs = 0; numDrawSyncs = 0;
numListSyncs = 0; numListSyncs = 0;
numCachedDrawCalls = 0;
numVertsSubmitted = 0; numVertsSubmitted = 0;
numCachedVertsDrawn = 0;
numUncachedVertsDrawn = 0; numUncachedVertsDrawn = 0;
numTrackedVertexArrays = 0;
numTextureInvalidations = 0; numTextureInvalidations = 0;
numTextureInvalidationsByFramebuffer = 0; numTextureInvalidationsByFramebuffer = 0;
numTexturesHashed = 0; numTexturesHashed = 0;
@ -115,14 +112,11 @@ struct GPUStatistics {
int numVertexDecodes; int numVertexDecodes;
int numDrawSyncs; int numDrawSyncs;
int numListSyncs; int numListSyncs;
int numCachedDrawCalls;
int numFlushes; int numFlushes;
int numBBOXJumps; int numBBOXJumps;
int numPlaneUpdates; int numPlaneUpdates;
int numVertsSubmitted; int numVertsSubmitted;
int numCachedVertsDrawn;
int numUncachedVertsDrawn; int numUncachedVertsDrawn;
int numTrackedVertexArrays;
int numTextureInvalidations; int numTextureInvalidations;
int numTextureInvalidationsByFramebuffer; int numTextureInvalidationsByFramebuffer;
int numTexturesHashed; int numTexturesHashed;

View File

@ -1685,8 +1685,7 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) {
return snprintf(buffer, size, return snprintf(buffer, size,
"DL processing time: %0.2f ms, %d drawsync, %d listsync\n" "DL processing time: %0.2f ms, %d drawsync, %d listsync\n"
"Draw: %d (%d dec), flushes %d, clears %d, bbox jumps %d (%d updates)\n" "Draw: %d (%d dec), flushes %d, clears %d, bbox jumps %d (%d updates)\n"
"Cached draws: %d (tracked: %d)\n" "Vertices: %d drawn: %d\n"
"Vertices: %d cached: %d uncached: %d\n"
"FBOs active: %d (evaluations: %d)\n" "FBOs active: %d (evaluations: %d)\n"
"Textures: %d, dec: %d, invalidated: %d, hashed: %d kB\n" "Textures: %d, dec: %d, invalidated: %d, hashed: %d kB\n"
"readbacks %d (%d non-block), uploads %d, depal %d\n" "readbacks %d (%d non-block), uploads %d, depal %d\n"
@ -1703,10 +1702,7 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) {
gpuStats.numClears, gpuStats.numClears,
gpuStats.numBBOXJumps, gpuStats.numBBOXJumps,
gpuStats.numPlaneUpdates, gpuStats.numPlaneUpdates,
gpuStats.numCachedDrawCalls,
gpuStats.numTrackedVertexArrays,
gpuStats.numVertsSubmitted, gpuStats.numVertsSubmitted,
gpuStats.numCachedVertsDrawn,
gpuStats.numUncachedVertsDrawn, gpuStats.numUncachedVertsDrawn,
(int)framebufferManager_->NumVFBs(), (int)framebufferManager_->NumVFBs(),
gpuStats.numFramebufferEvaluations, gpuStats.numFramebufferEvaluations,

View File

@ -54,20 +54,12 @@
using namespace PPSSPP_VK; using namespace PPSSPP_VK;
enum {
VERTEX_CACHE_SIZE = 8192 * 1024
};
#define VERTEXCACHE_DECIMATION_INTERVAL 17
enum { VAI_KILL_AGE = 120, VAI_UNRELIABLE_KILL_AGE = 240, VAI_UNRELIABLE_KILL_MAX = 4 };
enum { enum {
TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex) TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex)
}; };
DrawEngineVulkan::DrawEngineVulkan(Draw::DrawContext *draw) DrawEngineVulkan::DrawEngineVulkan(Draw::DrawContext *draw)
: draw_(draw), vai_(1024) { : draw_(draw) {
decOptions_.expandAllWeightsToFloat = false; decOptions_.expandAllWeightsToFloat = false;
decOptions_.expand8BitNormalsToFloat = false; decOptions_.expand8BitNormalsToFloat = false;
#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS) #if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
@ -117,8 +109,6 @@ void DrawEngineVulkan::InitDeviceObjects() {
res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); res = vkCreateSampler(device, &samp, nullptr, &nullSampler_);
_dbg_assert_(VK_SUCCESS == res); _dbg_assert_(VK_SUCCESS == res);
vertexCache_ = new VulkanPushBuffer(vulkan, "pushVertexCache", VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan); tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan);
tessDataTransfer = tessDataTransferVulkan; tessDataTransfer = tessDataTransferVulkan;
@ -163,18 +153,8 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
vulkan->Delete().QueueDeleteSampler(samplerSecondaryLinear_); vulkan->Delete().QueueDeleteSampler(samplerSecondaryLinear_);
if (nullSampler_ != VK_NULL_HANDLE) if (nullSampler_ != VK_NULL_HANDLE)
vulkan->Delete().QueueDeleteSampler(nullSampler_); vulkan->Delete().QueueDeleteSampler(nullSampler_);
renderManager->DestroyPipelineLayout(pipelineLayout_);
if (vertexCache_) {
vertexCache_->Destroy(vulkan);
delete vertexCache_;
vertexCache_ = nullptr;
}
// Need to clear this to get rid of all remaining references to the dead buffers. renderManager->DestroyPipelineLayout(pipelineLayout_);
vai_.Iterate([](uint32_t hash, VertexArrayInfoVulkan *vai) {
delete vai;
});
vai_.Clear();
} }
void DrawEngineVulkan::DeviceLost() { void DrawEngineVulkan::DeviceLost() {
@ -189,8 +169,6 @@ void DrawEngineVulkan::DeviceRestore(Draw::DrawContext *draw) {
} }
void DrawEngineVulkan::BeginFrame() { void DrawEngineVulkan::BeginFrame() {
gpuStats.numTrackedVertexArrays = (int)vai_.size();
lastPipeline_ = nullptr; lastPipeline_ = nullptr;
// pushUBO is the thin3d push pool, don't need to BeginFrame again. // pushUBO is the thin3d push pool, don't need to BeginFrame again.
@ -200,65 +178,11 @@ void DrawEngineVulkan::BeginFrame() {
tessDataTransferVulkan->SetPushPool(pushUBO_); tessDataTransferVulkan->SetPushPool(pushUBO_);
DirtyAllUBOs(); DirtyAllUBOs();
// First reset all buffers, then begin. This is so that Reset can free memory and Begin can allocate it,
// if growing the buffer is needed. Doing it this way will reduce fragmentation if more than one buffer
// needs to grow in the same frame. The state where many buffers are reset can also be used to
// defragment memory.
VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT);
// Wipe the vertex cache if it's grown too large.
if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) {
vertexCache_->Destroy(vulkan);
delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame.
vertexCache_ = new VulkanPushBuffer(vulkan, "vertexCacheR", VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) {
delete vai;
});
vai_.Clear();
}
vertexCache_->BeginNoReset();
if (--decimationCounter_ <= 0) {
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
const int threshold = gpuStats.numFlips - VAI_KILL_AGE;
const int unreliableThreshold = gpuStats.numFlips - VAI_UNRELIABLE_KILL_AGE;
int unreliableLeft = VAI_UNRELIABLE_KILL_MAX;
vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) {
bool kill;
if (vai->status == VertexArrayInfoVulkan::VAI_UNRELIABLE) {
// We limit killing unreliable so we don't rehash too often.
kill = vai->lastFrame < unreliableThreshold && --unreliableLeft >= 0;
} else {
kill = vai->lastFrame < threshold;
}
if (kill) {
// This is actually quite safe.
vai_.Remove(hash);
delete vai;
}
});
}
vai_.Maintain();
} }
void DrawEngineVulkan::EndFrame() { void DrawEngineVulkan::EndFrame() {
stats_.pushVertexSpaceUsed = (int)pushVertex_->GetUsedThisFrame(); stats_.pushVertexSpaceUsed = (int)pushVertex_->GetUsedThisFrame();
stats_.pushIndexSpaceUsed = (int)pushIndex_->GetUsedThisFrame(); stats_.pushIndexSpaceUsed = (int)pushIndex_->GetUsedThisFrame();
vertexCache_->End();
}
void DrawEngineVulkan::DecodeVertsToPushBuffer(VulkanPushBuffer *push, uint32_t *bindOffset, VkBuffer *vkbuf) {
u8 *dest = decoded_;
// Figure out how much pushbuffer space we need to allocate.
if (push) {
int vertsToDecode = ComputeNumVertsToDecode();
dest = (u8 *)push->Allocate(vertsToDecode * dec_->GetDecVtxFmt().stride, 4, vkbuf, bindOffset);
}
DecodeVerts(dest);
} }
void DrawEngineVulkan::DecodeVertsToPushPool(VulkanPushPool *push, uint32_t *bindOffset, VkBuffer *vkbuf) { void DrawEngineVulkan::DecodeVertsToPushPool(VulkanPushPool *push, uint32_t *bindOffset, VkBuffer *vkbuf) {
@ -285,12 +209,6 @@ void DrawEngineVulkan::DirtyAllUBOs() {
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE); gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);
} }
void MarkUnreliable(VertexArrayInfoVulkan *vai) {
vai->status = VertexArrayInfoVulkan::VAI_UNRELIABLE;
// TODO: If we change to a real allocator, free the data here.
// For now we just leave it in the pushbuffer.
}
void DrawEngineVulkan::Invalidate(InvalidationCallbackFlags flags) { void DrawEngineVulkan::Invalidate(InvalidationCallbackFlags flags) {
if (flags & InvalidationCallbackFlags::COMMAND_BUFFER_STATE) { if (flags & InvalidationCallbackFlags::COMMAND_BUFFER_STATE) {
// Nothing here anymore (removed the "frame descriptor set" // Nothing here anymore (removed the "frame descriptor set"
@ -305,158 +223,6 @@ void DrawEngineVulkan::Invalidate(InvalidationCallbackFlags flags) {
} }
} }
bool DrawEngineVulkan::VertexCacheLookup(int &vertexCount, GEPrimitiveType &prim, VkBuffer &vbuf, uint32_t &vbOffset, VkBuffer &ibuf, uint32_t &ibOffset, bool &useElements, bool forceIndexed) {
// getUVGenMode can have an effect on which UV decoder we need to use! And hence what the decoded data will look like. See #9263
// u32 dcid = (u32)XXH3_64bits(&drawCalls_, sizeof(DeferredDrawCall) * numDrawCalls_) ^ gstate.getUVGenMode();
u32 dcid = ComputeDrawcallsHash() ^ gstate.getUVGenMode();
PROFILE_THIS_SCOPE("vcache");
VertexArrayInfoVulkan *vai;
if (!vai_.Get(dcid, &vai)) {
vai = new VertexArrayInfoVulkan();
vai_.Insert(dcid, vai);
}
switch (vai->status) {
case VertexArrayInfoVulkan::VAI_NEW:
{
// Haven't seen this one before. We don't actually upload the vertex data yet.
uint64_t dataHash = ComputeHash();
vai->hash = dataHash;
vai->minihash = ComputeMiniHash();
vai->status = VertexArrayInfoVulkan::VAI_HASHING;
vai->drawsUntilNextFullHash = 0;
DecodeVertsToPushPool(pushVertex_, &vbOffset, &vbuf);
DecodeInds();
vai->numVerts = indexGen.VertexCount();
vai->prim = indexGen.Prim();
vai->maxIndex = MaxIndex();
vai->flags = gstate_c.vertexFullAlpha ? VAIVULKAN_FLAG_VERTEXFULLALPHA : 0;
return true;
}
// Hashing - still gaining confidence about the buffer.
// But if we get this far it's likely to be worth uploading the data.
case VertexArrayInfoVulkan::VAI_HASHING:
{
PROFILE_THIS_SCOPE("vcachehash");
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
if (vai->drawsUntilNextFullHash == 0) {
// Let's try to skip a full hash if mini would fail.
const u32 newMiniHash = ComputeMiniHash();
uint64_t newHash = vai->hash;
if (newMiniHash == vai->minihash) {
newHash = ComputeHash();
}
if (newMiniHash != vai->minihash || newHash != vai->hash) {
MarkUnreliable(vai);
DecodeVertsToPushPool(pushVertex_, &vbOffset, &vbuf);
DecodeInds();
return true;
}
if (vai->numVerts > 64) {
// exponential backoff up to 16 draws, then every 24
vai->drawsUntilNextFullHash = std::min(24, vai->numFrames);
} else {
// Lower numbers seem much more likely to change.
vai->drawsUntilNextFullHash = 0;
}
// TODO: tweak
//if (vai->numFrames > 1000) {
// vai->status = VertexArrayInfo::VAI_RELIABLE;
//}
} else {
vai->drawsUntilNextFullHash--;
u32 newMiniHash = ComputeMiniHash();
if (newMiniHash != vai->minihash) {
MarkUnreliable(vai);
DecodeVertsToPushPool(pushVertex_, &vbOffset, &vbuf);
DecodeInds();
return true;
}
}
if (!vai->vb) {
// Directly push to the vertex cache.
DecodeVertsToPushBuffer(vertexCache_, &vai->vbOffset, &vai->vb);
DecodeInds();
_dbg_assert_msg_(gstate_c.vertBounds.minV >= gstate_c.vertBounds.maxV, "Should not have checked UVs when caching.");
vai->numVerts = indexGen.VertexCount();
vai->maxIndex = MaxIndex();
vai->flags = gstate_c.vertexFullAlpha ? VAIVULKAN_FLAG_VERTEXFULLALPHA : 0;
if (forceIndexed) {
vai->prim = indexGen.GeneralPrim();
useElements = true;
} else {
vai->prim = indexGen.Prim();
useElements = !indexGen.SeenOnlyPurePrims();
if (!useElements && indexGen.PureCount()) {
vai->numVerts = indexGen.PureCount();
}
}
if (useElements) {
u32 size = sizeof(uint16_t) * indexGen.VertexCount();
void *dest = vertexCache_->Allocate(size, 4, &vai->ib, &vai->ibOffset);
memcpy(dest, decIndex_, size);
} else {
vai->ib = VK_NULL_HANDLE;
vai->ibOffset = 0;
}
} else {
gpuStats.numCachedDrawCalls++;
useElements = vai->ib ? true : false;
gpuStats.numCachedVertsDrawn += vai->numVerts;
gstate_c.vertexFullAlpha = vai->flags & VAIVULKAN_FLAG_VERTEXFULLALPHA;
}
vbuf = vai->vb;
ibuf = vai->ib;
vbOffset = vai->vbOffset;
ibOffset = vai->ibOffset;
vertexCount = vai->numVerts;
prim = static_cast<GEPrimitiveType>(vai->prim);
break;
}
// Reliable - we don't even bother hashing anymore. Right now we don't go here until after a very long time.
case VertexArrayInfoVulkan::VAI_RELIABLE:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
gpuStats.numCachedDrawCalls++;
gpuStats.numCachedVertsDrawn += vai->numVerts;
vbuf = vai->vb;
ibuf = vai->ib;
vbOffset = vai->vbOffset;
ibOffset = vai->ibOffset;
vertexCount = vai->numVerts;
prim = static_cast<GEPrimitiveType>(vai->prim);
gstate_c.vertexFullAlpha = vai->flags & VAIVULKAN_FLAG_VERTEXFULLALPHA;
break;
}
case VertexArrayInfoVulkan::VAI_UNRELIABLE:
{
vai->numDraws++;
if (vai->lastFrame != gpuStats.numFlips) {
vai->numFrames++;
}
DecodeVertsToPushPool(pushVertex_, &vbOffset, &vbuf);
DecodeInds();
return true;
}
default:
break;
}
return false;
}
// The inline wrapper in the header checks for numDrawCalls_ == 0 // The inline wrapper in the header checks for numDrawCalls_ == 0
void DrawEngineVulkan::DoFlush() { void DrawEngineVulkan::DoFlush() {
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
@ -490,19 +256,9 @@ void DrawEngineVulkan::DoFlush() {
if (useHWTransform) { if (useHWTransform) {
int vertexCount = 0; int vertexCount = 0;
bool useElements = true; bool useElements = true;
// Cannot cache vertex data with morph enabled.
bool useCache = g_Config.bVertexCache && !(lastVType_ & GE_VTYPE_MORPHCOUNT_MASK);
// Also avoid caching when software skinning.
VkBuffer vbuf = VK_NULL_HANDLE; VkBuffer vbuf = VK_NULL_HANDLE;
VkBuffer ibuf = VK_NULL_HANDLE; VkBuffer ibuf = VK_NULL_HANDLE;
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
useCache = false;
}
bool useIndexGen = true; bool useIndexGen = true;
if (useCache) {
useIndexGen = VertexCacheLookup(vertexCount, prim, vbuf, vbOffset, ibuf, ibOffset, useElements, forceIndexed);
} else {
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) { if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
// If software skinning, we're predecoding into "decoded". So make sure we're done, then push that content. // If software skinning, we're predecoding into "decoded". So make sure we're done, then push that content.
DecodeVerts(decoded_); DecodeVerts(decoded_);
@ -515,7 +271,6 @@ void DrawEngineVulkan::DoFlush() {
} }
DecodeInds(); DecodeInds();
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount(); gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
}
if (useIndexGen) { if (useIndexGen) {
vertexCount = indexGen.VertexCount(); vertexCount = indexGen.VertexCount();

View File

@ -61,7 +61,6 @@ class TextureCacheVulkan;
class FramebufferManagerVulkan; class FramebufferManagerVulkan;
class VulkanContext; class VulkanContext;
class VulkanPushBuffer;
class VulkanPushPool; class VulkanPushPool;
struct VulkanPipeline; struct VulkanPipeline;
@ -70,49 +69,6 @@ struct DrawEngineVulkanStats {
int pushIndexSpaceUsed; int pushIndexSpaceUsed;
}; };
enum {
VAIVULKAN_FLAG_VERTEXFULLALPHA = 1,
};
// Try to keep this POD.
class VertexArrayInfoVulkan {
public:
VertexArrayInfoVulkan() {
lastFrame = gpuStats.numFlips;
}
// No destructor needed - we always fully wipe.
enum VAIStatus : uint8_t {
VAI_NEW,
VAI_HASHING,
VAI_RELIABLE, // cache, don't hash
VAI_UNRELIABLE, // never cache
};
uint64_t hash = 0;
u32 minihash = 0;
// These will probably always be the same, but whatever.
VkBuffer vb = VK_NULL_HANDLE;
VkBuffer ib = VK_NULL_HANDLE;
// Offsets into the cache buffer.
uint32_t vbOffset = 0;
uint32_t ibOffset = 0;
// Precalculated parameter for vkDrawIndexed
u16 numVerts = 0;
u16 maxIndex = 0;
s8 prim = GE_PRIM_INVALID;
VAIStatus status = VAI_NEW;
// ID information
int numDraws = 0;
int numFrames = 0;
int lastFrame; // So that we can forget.
u16 drawsUntilNextFullHash = 0;
u8 flags = 0;
};
class VulkanRenderManager; class VulkanRenderManager;
class TessellationDataTransferVulkan : public TessellationDataTransfer { class TessellationDataTransferVulkan : public TessellationDataTransfer {
@ -228,10 +184,7 @@ private:
void DestroyDeviceObjects(); void DestroyDeviceObjects();
bool VertexCacheLookup(int &vertexCount, GEPrimitiveType &prim, VkBuffer &vbuf, uint32_t &vbOffset, VkBuffer &ibuf, uint32_t &ibOffset, bool &useElements, bool forceIndexed);
void DecodeVertsToPushPool(VulkanPushPool *push, uint32_t *bindOffset, VkBuffer *vkbuf); void DecodeVertsToPushPool(VulkanPushPool *push, uint32_t *bindOffset, VkBuffer *vkbuf);
void DecodeVertsToPushBuffer(VulkanPushBuffer *push, uint32_t *bindOffset, VkBuffer *vkbuf);
void DoFlush(); void DoFlush();
void UpdateUBOs(); void UpdateUBOs();
@ -254,9 +207,6 @@ private:
VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE; VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE;
VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE; VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE;
PrehashMap<VertexArrayInfoVulkan *> vai_;
VulkanPushBuffer *vertexCache_;
struct DescriptorSetKey { struct DescriptorSetKey {
VkImageView imageView_; VkImageView imageView_;
VkImageView secondaryImageView_; VkImageView secondaryImageView_;

View File

@ -33,7 +33,6 @@ class DrawEngineVulkan;
class VulkanContext; class VulkanContext;
class VulkanTexture; class VulkanTexture;
class VulkanPushBuffer;
class SamplerCache { class SamplerCache {
public: public:

View File

@ -650,8 +650,6 @@ void MainWindow::createMenus()
gameSettingsMenu->add(new MenuAction(this, SLOT(transformAct()), QT_TR_NOOP("&Hardware transform"))) gameSettingsMenu->add(new MenuAction(this, SLOT(transformAct()), QT_TR_NOOP("&Hardware transform")))
->addEventChecked(&g_Config.bHardwareTransform); ->addEventChecked(&g_Config.bHardwareTransform);
gameSettingsMenu->add(new MenuAction(this, SLOT(vertexCacheAct()), QT_TR_NOOP("&Vertex cache")))
->addEventChecked(&g_Config.bVertexCache);
gameSettingsMenu->addSeparator(); gameSettingsMenu->addSeparator();
gameSettingsMenu->add(new MenuAction(this, SLOT(audioAct()), QT_TR_NOOP("Enable s&ound"))) gameSettingsMenu->add(new MenuAction(this, SLOT(audioAct()), QT_TR_NOOP("Enable s&ound")))
->addEventChecked(&g_Config.bEnableSound); ->addEventChecked(&g_Config.bEnableSound);

View File

@ -157,7 +157,6 @@ private slots:
g_Config.bHardwareTransform = !g_Config.bHardwareTransform; g_Config.bHardwareTransform = !g_Config.bHardwareTransform;
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED); System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
} }
void vertexCacheAct() { g_Config.bVertexCache = !g_Config.bVertexCache; }
void frameskipAct() { g_Config.iFrameSkip = !g_Config.iFrameSkip; } void frameskipAct() { g_Config.iFrameSkip = !g_Config.iFrameSkip; }
void frameskipTypeAct() { g_Config.iFrameSkipType = !g_Config.iFrameSkipType; } void frameskipTypeAct() { g_Config.iFrameSkipType = !g_Config.iFrameSkipType; }

View File

@ -401,15 +401,6 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
CheckBox *skipGPUReadbacks = graphicsSettings->Add(new CheckBox(&g_Config.bSkipGPUReadbacks, gr->T("Skip GPU Readbacks"))); CheckBox *skipGPUReadbacks = graphicsSettings->Add(new CheckBox(&g_Config.bSkipGPUReadbacks, gr->T("Skip GPU Readbacks")));
skipGPUReadbacks->SetDisabledPtr(&g_Config.bSoftwareRendering); skipGPUReadbacks->SetDisabledPtr(&g_Config.bSoftwareRendering);
CheckBox *vtxCache = graphicsSettings->Add(new CheckBox(&g_Config.bVertexCache, gr->T("Vertex Cache")));
vtxCache->OnClick.Add([=](EventParams &e) {
settingInfo_->Show(gr->T("VertexCache Tip", "Faster, but may cause temporary flicker"), e.v);
return UI::EVENT_CONTINUE;
});
vtxCache->SetEnabledFunc([] {
return !g_Config.bSoftwareRendering && g_Config.bHardwareTransform && g_Config.iGPUBackend != (int)GPUBackend::OPENGL;
});
CheckBox *texBackoff = graphicsSettings->Add(new CheckBox(&g_Config.bTextureBackoffCache, gr->T("Lazy texture caching", "Lazy texture caching (speedup)"))); CheckBox *texBackoff = graphicsSettings->Add(new CheckBox(&g_Config.bTextureBackoffCache, gr->T("Lazy texture caching", "Lazy texture caching (speedup)")));
texBackoff->SetDisabledPtr(&g_Config.bSoftwareRendering); texBackoff->SetDisabledPtr(&g_Config.bSoftwareRendering);
texBackoff->OnClick.Add([=](EventParams& e) { texBackoff->OnClick.Add([=](EventParams& e) {

View File

@ -290,7 +290,6 @@ namespace MainWindow {
TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID_BICUBIC); TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID_BICUBIC);
TranslateMenuItem(menu, ID_TEXTURESCALING_DEPOSTERIZE); TranslateMenuItem(menu, ID_TEXTURESCALING_DEPOSTERIZE);
TranslateMenuItem(menu, ID_OPTIONS_HARDWARETRANSFORM); TranslateMenuItem(menu, ID_OPTIONS_HARDWARETRANSFORM);
TranslateMenuItem(menu, ID_OPTIONS_VERTEXCACHE);
TranslateMenuItem(menu, ID_EMULATION_SOUND); TranslateMenuItem(menu, ID_EMULATION_SOUND);
TranslateMenuItem(menu, ID_EMULATION_CHEATS, g_Config.bSystemControls ? L"\tCtrl+T" : L""); TranslateMenuItem(menu, ID_EMULATION_CHEATS, g_Config.bSystemControls ? L"\tCtrl+T" : L"");
TranslateMenuItem(menu, ID_EMULATION_CHAT, g_Config.bSystemControls ? L"\tCtrl+C" : L""); TranslateMenuItem(menu, ID_EMULATION_CHAT, g_Config.bSystemControls ? L"\tCtrl+C" : L"");
@ -859,9 +858,6 @@ namespace MainWindow {
SendToggleFullscreen(!g_Config.UseFullScreen()); SendToggleFullscreen(!g_Config.UseFullScreen());
break; break;
case ID_OPTIONS_VERTEXCACHE:
g_Config.bVertexCache = !g_Config.bVertexCache;
break;
case ID_OPTIONS_TEXTUREFILTERING_AUTO: g_Config.iTexFiltering = TEX_FILTER_AUTO; break; case ID_OPTIONS_TEXTUREFILTERING_AUTO: g_Config.iTexFiltering = TEX_FILTER_AUTO; break;
case ID_OPTIONS_NEARESTFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_NEAREST; break; case ID_OPTIONS_NEARESTFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_NEAREST; break;
case ID_OPTIONS_LINEARFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_LINEAR; break; case ID_OPTIONS_LINEARFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_LINEAR; break;
@ -954,7 +950,6 @@ namespace MainWindow {
CHECKITEM(ID_DEBUG_SHOWDEBUGSTATISTICS, (DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS); CHECKITEM(ID_DEBUG_SHOWDEBUGSTATISTICS, (DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS);
CHECKITEM(ID_OPTIONS_HARDWARETRANSFORM, g_Config.bHardwareTransform); CHECKITEM(ID_OPTIONS_HARDWARETRANSFORM, g_Config.bHardwareTransform);
CHECKITEM(ID_DEBUG_BREAKONLOAD, !g_Config.bAutoRun); CHECKITEM(ID_DEBUG_BREAKONLOAD, !g_Config.bAutoRun);
CHECKITEM(ID_OPTIONS_VERTEXCACHE, g_Config.bVertexCache);
CHECKITEM(ID_OPTIONS_FRAMESKIP_AUTO, g_Config.bAutoFrameSkip); CHECKITEM(ID_OPTIONS_FRAMESKIP_AUTO, g_Config.bAutoFrameSkip);
CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != FRAMESKIP_OFF); CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != FRAMESKIP_OFF);
CHECKITEM(ID_OPTIONS_FRAMESKIPTYPE_COUNT, g_Config.iFrameSkipType == FRAMESKIPTYPE_COUNT); CHECKITEM(ID_OPTIONS_FRAMESKIPTYPE_COUNT, g_Config.iFrameSkipType == FRAMESKIPTYPE_COUNT);
@ -988,13 +983,6 @@ namespace MainWindow {
CheckMenuItem(menu, displayrotationitems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iInternalScreenRotation ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, displayrotationitems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iInternalScreenRotation ? MF_CHECKED : MF_UNCHECKED));
} }
// Disable Vertex Cache when HW T&L is disabled.
if (!g_Config.bHardwareTransform) {
EnableMenuItem(menu, ID_OPTIONS_VERTEXCACHE, MF_GRAYED);
} else {
EnableMenuItem(menu, ID_OPTIONS_VERTEXCACHE, MF_ENABLED);
}
static const int zoomitems[11] = { static const int zoomitems[11] = {
ID_OPTIONS_SCREENAUTO, ID_OPTIONS_SCREENAUTO,
ID_OPTIONS_SCREEN1X, ID_OPTIONS_SCREEN1X,

View File

@ -685,7 +685,6 @@ BEGIN
MENUITEM "Deposterize", ID_TEXTURESCALING_DEPOSTERIZE MENUITEM "Deposterize", ID_TEXTURESCALING_DEPOSTERIZE
END END
MENUITEM "Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM MENUITEM "Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM
MENUITEM "Vertex Cache", ID_OPTIONS_VERTEXCACHE
MENUITEM "", 0, MFT_SEPARATOR MENUITEM "", 0, MFT_SEPARATOR
MENUITEM "Enable Sound", ID_EMULATION_SOUND MENUITEM "Enable Sound", ID_EMULATION_SOUND
MENUITEM "", 0, MFT_SEPARATOR MENUITEM "", 0, MFT_SEPARATOR

View File

@ -169,7 +169,6 @@
#define ID_OPTIONS_CONTROLS 40038 #define ID_OPTIONS_CONTROLS 40038
#define ID_DEBUG_BREAKONLOAD 40039 #define ID_DEBUG_BREAKONLOAD 40039
#define ID_DEBUG_DUMPNEXTFRAME 40040 #define ID_DEBUG_DUMPNEXTFRAME 40040
#define ID_OPTIONS_VERTEXCACHE 40041
#define ID_OPTIONS_FRAMESKIP 40044 #define ID_OPTIONS_FRAMESKIP 40044
#define IDC_MEMCHECK 40045 #define IDC_MEMCHECK 40045
#define ID_FILE_MEMSTICK 40046 #define ID_FILE_MEMSTICK 40046

View File

@ -276,7 +276,6 @@ Texture Filtering = Te&xture filtering
Texture Scaling = &تكبير الرسوم Texture Scaling = &تكبير الرسوم
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &مخزن الفريتكس
VSync = VS&ync VSync = VS&ync
Vulkan = ‎فولكان Vulkan = ‎فولكان
Window Size = &حجم النافذة Window Size = &حجم النافذة
@ -669,8 +668,6 @@ Upscale Level = ‎مستوي التكبير
Upscale Type = ‎نوع التكبير Upscale Type = ‎نوع التكبير
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex cache
VertexCache Tip = ‎أسرع, لكن ربما يسبب تميع مؤقت
VSync = VSync VSync = VSync
Vulkan = ‎فولكان Vulkan = ‎فولكان
Window Size = ‎حجم النافذة Window Size = ‎حجم النافذة

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
Texture Scaling = &Texture Scaling Texture Scaling = &Texture Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window Size Window Size = &Window Size
@ -661,8 +660,6 @@ Upscale Level = Upscale level
Upscale Type = Upscale type Upscale Type = Upscale type
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex Keş
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -268,7 +268,6 @@ Texture Filtering = Текстурно филтриране
Texture Scaling = Текстурно мащабиране Texture Scaling = Текстурно мащабиране
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Размер на прозореца Window Size = &Размер на прозореца
@ -661,8 +660,6 @@ Upscale Level = Upscale level
Upscale Type = Upscale type Upscale Type = Upscale type
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex cache
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Размер на прозореца Window Size = Размер на прозореца

View File

@ -268,7 +268,6 @@ Texture Filtering = Filtrat de te&xtura
Texture Scaling = Escalat de &textura Texture Scaling = Escalat de &textura
Use Lossless Video Codec (FFV1) = Fes servir còdec de vídeo sense pèrdua (FFV1) Use Lossless Video Codec (FFV1) = Fes servir còdec de vídeo sense pèrdua (FFV1)
Use output buffer for video = Utilitzar sortida de búfer per a vídeo Use output buffer for video = Utilitzar sortida de búfer per a vídeo
Vertex Cache = &Memòria cau de vèrtexs
VSync = Sincronització vertical (VS&ync) VSync = Sincronització vertical (VS&ync)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Mida de la &finestra Window Size = Mida de la &finestra
@ -661,8 +660,6 @@ Upscale Level = Nivell d'escalat
Upscale Type = Tipus d'escalat Upscale Type = Tipus d'escalat
UpscaleLevel Tip = Exigeix consum de CPU, alguns escalats es poden retardar per evitar estrebades. UpscaleLevel Tip = Exigeix consum de CPU, alguns escalats es poden retardar per evitar estrebades.
Use all displays = Usar totes les pantalles Use all displays = Usar totes les pantalles
Vertex Cache = Memòria cau de vèrtexs
VertexCache Tip = Ràpid, però pot causar parpelleig temporal.
VSync = Sincronització vertical (VSync) VSync = Sincronització vertical (VSync)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Mida de la finestra Window Size = Mida de la finestra

View File

@ -268,7 +268,6 @@ Texture Filtering = &Filtrování textur
Texture Scaling = &Změna velikosti textur Texture Scaling = &Změna velikosti textur
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Mezipaměť verte&xů
VSync = Vertikální S&ynchronizace VSync = Vertikální S&ynchronizace
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Velikost okna Window Size = &Velikost okna
@ -661,8 +660,6 @@ Upscale Level = Úroveň zvětšení
Upscale Type = Typ zvětšení Upscale Type = Typ zvětšení
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Mezipaměť vertexů
VertexCache Tip = Faster, but may cause temporary flicker
VSync = Vertikální synchronizace VSync = Vertikální synchronizace
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Velikost okna Window Size = Velikost okna

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xturfilter
Texture Scaling = &Texturskalering Texture Scaling = &Texturskalering
Use Lossless Video Codec (FFV1) = Brug Tabsfri Video Codec (FFV1) Use Lossless Video Codec (FFV1) = Brug Tabsfri Video Codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertexcache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Vinduesstørrelse Window Size = &Vinduesstørrelse
@ -661,8 +660,6 @@ Upscale Level = Opskaleringsniveau
Upscale Type = Opskaleringstype Upscale Type = Opskaleringstype
UpscaleLevel Tip = CPU tung - noget skallering kan belive forsinket for at undgå flimmer UpscaleLevel Tip = CPU tung - noget skallering kan belive forsinket for at undgå flimmer
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertexcache
VertexCache Tip = Hurtigere, men kan medføre midlertidig flimmer
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Vinduesstørrelse Window Size = Vinduesstørrelse

View File

@ -268,7 +268,6 @@ Texture Filtering = Texturfilter
Texture Scaling = Texturskalierung Texture Scaling = Texturskalierung
Use Lossless Video Codec (FFV1) = Benutze verlustfreien Videocodec (FFV1) Use Lossless Video Codec (FFV1) = Benutze verlustfreien Videocodec (FFV1)
Use output buffer for video = Benutze Ausgabepuffer für Video Use output buffer for video = Benutze Ausgabepuffer für Video
Vertex Cache = Vertex-Cache
VSync = V-Sync VSync = V-Sync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Fenstergröße Window Size = Fenstergröße
@ -661,8 +660,6 @@ Upscale Level = Skalierungsgrad
Upscale Type = Skalierungsart Upscale Type = Skalierungsart
UpscaleLevel Tip = CPU-lastig - einige Skalierungen könnten verzögert sein um Stottern zu vermeiden UpscaleLevel Tip = CPU-lastig - einige Skalierungen könnten verzögert sein um Stottern zu vermeiden
Use all displays = Benutze alle Bildschirme Use all displays = Benutze alle Bildschirme
Vertex Cache = Vertex-Cache
VertexCache Tip = Schneller, kann temporäres Flackern verursachen
VSync = V-Sync VSync = V-Sync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Fenstergröße Window Size = Fenstergröße

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
Texture Scaling = &Texture Scaling Texture Scaling = &Texture Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window Size Window Size = &Window Size
@ -661,8 +660,6 @@ Upscale Level = Patonggoi skala
Upscale Type = Skala apa mane? Upscale Type = Skala apa mane?
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Pangnganna Vertex
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -292,7 +292,6 @@ Texture Filtering = Te&xture filtering
Texture Scaling = &Texture scaling Texture Scaling = &Texture scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window size Window Size = &Window size
@ -686,8 +685,6 @@ Upscale Level = Upscale level
Upscale Type = Upscale type Upscale Type = Upscale type
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex cache
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -268,7 +268,6 @@ Texture Filtering = &Filtrado de texturas
Texture Scaling = &Escalado de texturas Texture Scaling = &Escalado de texturas
Use Lossless Video Codec (FFV1) = Usar códec de vídeo sin pérdida (&FFV1) Use Lossless Video Codec (FFV1) = Usar códec de vídeo sin pérdida (&FFV1)
Use output buffer for video = Usar salida de búfer para vídeo Use output buffer for video = Usar salida de búfer para vídeo
Vertex Cache = &Caché de vértices
VSync = Sincronización &vertical VSync = Sincronización &vertical
Vulkan = &Vulkan Vulkan = &Vulkan
Window Size = &Tamaño de ventana Window Size = &Tamaño de ventana
@ -661,8 +660,6 @@ Upscale Level = Nivel de escalado
Upscale Type = Tipo de escalado Upscale Type = Tipo de escalado
UpscaleLevel Tip = Exige consumo de CPU, algunos escalados se pueden retrasar para evitar tirones. UpscaleLevel Tip = Exige consumo de CPU, algunos escalados se pueden retrasar para evitar tirones.
Use all displays = Usar todas las pantallas Use all displays = Usar todas las pantallas
Vertex Cache = Caché de vértices
VertexCache Tip = Rápido, pero puede causar parpadeo temporal.
VSync = Sincronía vertical (VSync) VSync = Sincronía vertical (VSync)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Tamaño de ventana Window Size = Tamaño de ventana

View File

@ -268,7 +268,6 @@ Texture Filtering = &Filtrado de texturas
Texture Scaling = &Escalado de texturas Texture Scaling = &Escalado de texturas
Use Lossless Video Codec (FFV1) = Usar codec de vídeo sin pérdida (&FFV1) Use Lossless Video Codec (FFV1) = Usar codec de vídeo sin pérdida (&FFV1)
Use output buffer for video = Usar salida de búfer para vídeo Use output buffer for video = Usar salida de búfer para vídeo
Vertex Cache = &Caché de vértices
VSync = Sincronización &vertical VSync = Sincronización &vertical
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Tamaño de ventana Window Size = &Tamaño de ventana
@ -661,8 +660,6 @@ Upscale Level = Nivel de escalado
Upscale Type = Tipo de escalado Upscale Type = Tipo de escalado
UpscaleLevel Tip = Consume tanta CPU. Cierto escalado se retrasa para evitar caídas de frames. UpscaleLevel Tip = Consume tanta CPU. Cierto escalado se retrasa para evitar caídas de frames.
Use all displays = Usar todas las muestras Use all displays = Usar todas las muestras
Vertex Cache = Caché con Vértices
VertexCache Tip = Acelera, pero puede causar parpadeos en ocasiones.
VSync = Sincronía vertical (VSync) VSync = Sincronía vertical (VSync)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Tamaño de ventana Window Size = Tamaño de ventana

View File

@ -268,7 +268,6 @@ Texture Filtering = ‎فیلتر تکسچر
Texture Scaling = ‎تغییر سایز تکسچر Texture Scaling = ‎تغییر سایز تکسچر
Use Lossless Video Codec (FFV1) = (FFV1) استفاده از کدک بدون دستکاری Use Lossless Video Codec (FFV1) = (FFV1) استفاده از کدک بدون دستکاری
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Vertex کش کردن
VSync = VS&ync VSync = VS&ync
Vulkan = والکمن Vulkan = والکمن
Window Size = ‎سایز پنجره Window Size = ‎سایز پنجره
@ -661,8 +660,6 @@ Upscale Level = ‎میزان افزایش سایز
Upscale Type = ‎نوع افزایش سایز Upscale Type = ‎نوع افزایش سایز
UpscaleLevel Tip = ‎زیاد کار میکشد CPU از UpscaleLevel Tip = ‎زیاد کار میکشد CPU از
Use all displays = ‎استفاده از همه نمایشگر ها Use all displays = ‎استفاده از همه نمایشگر ها
Vertex Cache = Vertex کش
VertexCache Tip = ‎سریع تر، اما ممکن است باعث لرزش موقتی شود
VSync = VSync VSync = VSync
Vulkan = والکمن Vulkan = والکمن
Window Size = ‎سایز پنجره Window Size = ‎سایز پنجره

View File

@ -268,7 +268,6 @@ Texture Filtering = &Tekstuurien suodatus
Texture Scaling = &Tekstuurien skaalaus Texture Scaling = &Tekstuurien skaalaus
Use Lossless Video Codec (FFV1) = Käytä häviötöntä &videokoodekkia (FFV1) Use Lossless Video Codec (FFV1) = Käytä häviötöntä &videokoodekkia (FFV1)
Use output buffer for video = Käytä ulostulopuskuria videolle Use output buffer for video = Käytä ulostulopuskuria videolle
Vertex Cache = &Vertex-välimuisti
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Ikkunan koko Window Size = &Ikkunan koko
@ -661,8 +660,6 @@ Upscale Level = Ylösskaalauksen taso
Upscale Type = Ylösskaalauksen tapa Upscale Type = Ylösskaalauksen tapa
UpscaleLevel Tip = Prosessorille raskas - joillekkin skaalauksille voidaan antaa viivettä nykimisen välttämiseksi UpscaleLevel Tip = Prosessorille raskas - joillekkin skaalauksille voidaan antaa viivettä nykimisen välttämiseksi
Use all displays = Käytä kaikkia näyttöjä Use all displays = Käytä kaikkia näyttöjä
Vertex Cache = Verteksivälimuisti
VertexCache Tip = Nopeampi, mutta voi välillä aiheuttaa vilkkumista
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Ikkunan koko Window Size = Ikkunan koko

View File

@ -268,7 +268,6 @@ Texture Filtering = &Filtrage des textures
Texture Scaling = Mise à l'échelle des &textures Texture Scaling = Mise à l'échelle des &textures
Use Lossless Video Codec (FFV1) = Utiliser un &codec vidéo sans perte (FFV1) Use Lossless Video Codec (FFV1) = Utiliser un &codec vidéo sans perte (FFV1)
Use output buffer for video = Utiliser une mémoire tampon pour la vidéo Use output buffer for video = Utiliser une mémoire tampon pour la vidéo
Vertex Cache = &Cache vertex
VSync = Synchronisation &verticale VSync = Synchronisation &verticale
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Ta&ille de la fenêtre Window Size = Ta&ille de la fenêtre
@ -661,8 +660,6 @@ Upscale Level = Niveau de mise à l'échelle
Upscale Type = Type de mise à l'échelle Upscale Type = Type de mise à l'échelle
UpscaleLevel Tip = Lourd pour le CPU, certaines mises à l'échelle peuvent être différées pour éviter les saccades UpscaleLevel Tip = Lourd pour le CPU, certaines mises à l'échelle peuvent être différées pour éviter les saccades
Use all displays = Utiliser tous les écrans Use all displays = Utiliser tous les écrans
Vertex Cache = Cache vertex
VertexCache Tip = Plus rapide, mais peut causer des scintillements temporaires
VSync = Synchronisation verticale VSync = Synchronisation verticale
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Taille de la fenêtre Window Size = Taille de la fenêtre

View File

@ -268,7 +268,6 @@ Texture Filtering = &Filtrado de texturas
Texture Scaling = &Escalado de texturas Texture Scaling = &Escalado de texturas
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Caché de vértices
VSync = Sincronización &vertical VSync = Sincronización &vertical
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Tamaño de ventá Window Size = &Tamaño de ventá
@ -661,8 +660,6 @@ Upscale Level = Nivel de escalado
Upscale Type = Tipo de escalado Upscale Type = Tipo de escalado
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Caché de vértices
VertexCache Tip = Faster, but may cause temporary flicker
VSync = Sincronización vertical VSync = Sincronización vertical
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Tamaño de ventana Window Size = Tamaño de ventana

View File

@ -268,7 +268,6 @@ Texture Filtering = Φιλτράρισμα Υφών
Texture Scaling = Κλιμάκωση Υφών Texture Scaling = Κλιμάκωση Υφών
Use Lossless Video Codec (FFV1) = Χρήση μη απολεστικού κωδικοποιητή (FFV1) Use Lossless Video Codec (FFV1) = Χρήση μη απολεστικού κωδικοποιητή (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Π&ροσωρινή Μνήμη Κορυφών
VSync = Κά&θετος Συγχρονισμός VSync = Κά&θετος Συγχρονισμός
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Μέγεθος Παραθύρου Window Size = Μέγεθος Παραθύρου
@ -661,8 +660,6 @@ Upscale Level = Επίπεδο Κλιμάκωσης
Upscale Type = Τύπος Κλιμάκωσης Upscale Type = Τύπος Κλιμάκωσης
UpscaleLevel Tip = Βαρύ για τον επεξεργαστή - κάποια κλιμάκωση μπορεί να καθυστερήσει για να αποφευχθούν κολλήματα UpscaleLevel Tip = Βαρύ για τον επεξεργαστή - κάποια κλιμάκωση μπορεί να καθυστερήσει για να αποφευχθούν κολλήματα
Use all displays = Χρησιμοποιήστε όλες τις οθόνες Use all displays = Χρησιμοποιήστε όλες τις οθόνες
Vertex Cache = Προσωρινή Μνήμη Κορυφών
VertexCache Tip = Πιο γρήγορα, αλλά μπορεί να προκαλέσει προσωρινό τρεμόπαιγμα
VSync = Κάθετος Συγχρονισμός VSync = Κάθετος Συγχρονισμός
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Μέγεθος Παραθύρου Window Size = Μέγεθος Παραθύρου

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
Texture Scaling = &Texture Scaling Texture Scaling = &Texture Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window Size Window Size = &Window Size
@ -661,8 +660,6 @@ Upscale Level = רמה יוקרתית
Upscale Type = סוג יוקרתי Upscale Type = סוג יוקרתי
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex מטמון
VertexCache Tip = Faster, but may cause temporary flicker
VSync = סנכרון אנכי VSync = סנכרון אנכי
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
Texture Scaling = &Texture Scaling Texture Scaling = &Texture Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window Size Window Size = &Window Size
@ -661,8 +660,6 @@ Upscale Level = תיתרקוי המר
Upscale Type = יתרקוי גוס Upscale Type = יתרקוי גוס
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex ןומטמ
VertexCache Tip = Faster, but may cause temporary flicker
VSync = יכנא ןורכנס VSync = יכנא ןורכנס
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -268,7 +268,6 @@ Texture Filtering = Fi&ltriranje teksturi
Texture Scaling = &Skaliranje teksturi Texture Scaling = &Skaliranje teksturi
Use Lossless Video Codec (FFV1) = &Koristite lossless video protokol (FFV1) Use Lossless Video Codec (FFV1) = &Koristite lossless video protokol (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Veličina prozora Window Size = &Veličina prozora
@ -661,8 +660,6 @@ Upscale Level = Nadograđivanje razine
Upscale Type = Vrsta nadograđivanja Upscale Type = Vrsta nadograđivanja
UpscaleLevel Tip = CPU težak - neke nadogradnje mogu biti usporene da izbjegnu mucanje UpscaleLevel Tip = CPU težak - neke nadogradnje mogu biti usporene da izbjegnu mucanje
Use all displays = Koristi sve prikaze Use all displays = Koristi sve prikaze
Vertex Cache = Predmemorija tjemena
VertexCache Tip = Brže, ali može izazvati privremeno treperenje
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Veličina prozora Window Size = Veličina prozora

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xtúra szűrés
Texture Scaling = &Textúra nagyítás Texture Scaling = &Textúra nagyítás
Use Lossless Video Codec (FFV1) = &Veszteségmentes videó codec használata (FFV1) Use Lossless Video Codec (FFV1) = &Veszteségmentes videó codec használata (FFV1)
Use output buffer for video = Kimeneti &buffer alkalmazása rögzítéskor Use output buffer for video = Kimeneti &buffer alkalmazása rögzítéskor
Vertex Cache = &Vertex gyorsítótár
VSync = VS&ync VSync = VS&ync
Vulkan = &Vulkan Vulkan = &Vulkan
Window Size = &Ablak méret Window Size = &Ablak méret
@ -661,8 +660,6 @@ Upscale Level = Nagyítási szint
Upscale Type = Nagyítás típusa Upscale Type = Nagyítás típusa
UpscaleLevel Tip = CPU intenzív - akadozások elkerülése végett olykor késleltetve nagyít. UpscaleLevel Tip = CPU intenzív - akadozások elkerülése végett olykor késleltetve nagyít.
Use all displays = Minden megjelenítő használata Use all displays = Minden megjelenítő használata
Vertex Cache = Vertex gyorsítótár
VertexCache Tip = Gyorsabb, de néha villódzást okoz
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Ablak méret Window Size = Ablak méret

View File

@ -268,7 +268,6 @@ Texture Filtering = Pemfilteran tekstur
Texture Scaling = Penskala &tekstur Texture Scaling = Penskala &tekstur
Use Lossless Video Codec (FFV1) = Gunakan kompresi video (FFV1) Use Lossless Video Codec (FFV1) = Gunakan kompresi video (FFV1)
Use output buffer for video = Gunakan penyangga keluaran untuk video Use output buffer for video = Gunakan penyangga keluaran untuk video
Vertex Cache = Tembolok &vertex
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Ukuran window Window Size = Ukuran window
@ -661,8 +660,6 @@ Upscale Level = Tingkat skala-atas
Upscale Type = Jenis skala-atas Upscale Type = Jenis skala-atas
UpscaleLevel Tip = Berat di CPU - beberapa penskala mungkin tertunda untuk menghindari kegagapan UpscaleLevel Tip = Berat di CPU - beberapa penskala mungkin tertunda untuk menghindari kegagapan
Use all displays = Gunakan semua tampilan Use all displays = Gunakan semua tampilan
Vertex Cache = Tembolok vertex
VertexCache Tip = Lebih cepat, namun dapat menyebabkan kedipan sementara
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Ukuran Window Window Size = Ukuran Window

View File

@ -268,7 +268,6 @@ Texture Filtering = Filtro Texture
Texture Scaling = Scalatura Texture Texture Scaling = Scalatura Texture
Use Lossless Video Codec (FFV1) = Usa Codec Video senza perdite (FFV1) Use Lossless Video Codec (FFV1) = Usa Codec Video senza perdite (FFV1)
Use output buffer for video = Usa il buffer per il video Use output buffer for video = Usa il buffer per il video
Vertex Cache = Cache dei Vertici
VSync = Sincronizzazione Verticale VSync = Sincronizzazione Verticale
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Dimensioni Finestra Window Size = Dimensioni Finestra
@ -662,8 +661,6 @@ Upscale Level = Livello Ottimizzazione
Upscale Type = Tipo Ottimizzazione Upscale Type = Tipo Ottimizzazione
UpscaleLevel Tip = Pesante per le CPU - alcune scalature posso essere ritardate per evitare scatti UpscaleLevel Tip = Pesante per le CPU - alcune scalature posso essere ritardate per evitare scatti
Use all displays = Usa tutti i display Use all displays = Usa tutti i display
Vertex Cache = Cache dei Vertici
VertexCache Tip = Più veloce, ma potrebbe causare dei flicker temporanei
VSync = Sincronizzazione Verticale VSync = Sincronizzazione Verticale
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Dimensioni Finestra Window Size = Dimensioni Finestra

View File

@ -268,7 +268,6 @@ Texture Filtering = テクスチャフィルタリング(&X)
Texture Scaling = テクスチャスケーリング(&T) Texture Scaling = テクスチャスケーリング(&T)
Use Lossless Video Codec (FFV1) = ロスレスビデオコーデックを使う (FFV1)(&U) Use Lossless Video Codec (FFV1) = ロスレスビデオコーデックを使う (FFV1)(&U)
Use output buffer for video = ビデオに出力バッファを使う Use output buffer for video = ビデオに出力バッファを使う
Vertex Cache = 頂点キャッシュ(&V)
VSync = VSync(&Y) VSync = VSync(&Y)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = ウィンドウサイズ(&W) Window Size = ウィンドウサイズ(&W)
@ -661,8 +660,6 @@ Upscale Level = アップスケールのレベル
Upscale Type = アップスケールのタイプ Upscale Type = アップスケールのタイプ
UpscaleLevel Tip = CPUに重い負荷 - カクつきを避けるためタイプによっては遅延するスケーリングがあるかもしれません UpscaleLevel Tip = CPUに重い負荷 - カクつきを避けるためタイプによっては遅延するスケーリングがあるかもしれません
Use all displays = 全てのディスプレイを使う Use all displays = 全てのディスプレイを使う
Vertex Cache = 頂点キャッシュ
VertexCache Tip = 高速ですがフリッカーが生じるかもしれません
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = ウィンドウサイズ Window Size = ウィンドウサイズ

View File

@ -268,7 +268,6 @@ Texture Filtering = Tektur Nyaring
Texture Scaling = Tektur njongko Texture Scaling = Tektur njongko
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Penyimpenan Vertex
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Ukuran Window Window Size = &Ukuran Window
@ -661,8 +660,6 @@ Upscale Level = Tingkatan Penaikan-skala
Upscale Type = Jenis Penaikan-skala Upscale Type = Jenis Penaikan-skala
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Penyimpenan Vertex
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Ukuran window Window Size = Ukuran window

View File

@ -268,7 +268,6 @@ Texture Filtering = 텍스처 필터링(&X)
Texture Scaling = 텍스처 크기 조절(&T) Texture Scaling = 텍스처 크기 조절(&T)
Use Lossless Video Codec (FFV1) = 무손실 비디오 코덱 사용 (FFV1)(&U) Use Lossless Video Codec (FFV1) = 무손실 비디오 코덱 사용 (FFV1)(&U)
Use output buffer for video = 비디오에 출력 버퍼 사용 Use output buffer for video = 비디오에 출력 버퍼 사용
Vertex Cache = 정점 캐시(&V)
VSync = 수직 동기화(&Y) VSync = 수직 동기화(&Y)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = 창 크기(&W) Window Size = 창 크기(&W)
@ -661,8 +660,6 @@ Upscale Level = 업스케일 레벨
Upscale Type = 업스케일 유형 Upscale Type = 업스케일 유형
UpscaleLevel Tip = CPU 사용률 높음 - 버벅거림을 방지하기 위해 일부 확장이 지연될 수 있음 UpscaleLevel Tip = CPU 사용률 높음 - 버벅거림을 방지하기 위해 일부 확장이 지연될 수 있음
Use all displays = 모든 화면 사용 Use all displays = 모든 화면 사용
Vertex Cache = 정점 캐시
VertexCache Tip = 더 빠르지만 일시적인 깜박임이 발생할 수 있습니다.
VSync = 수직 동기화 VSync = 수직 동기화
Vulkan = Vulkan Vulkan = Vulkan
Window Size = 창 크기 Window Size = 창 크기

View File

@ -268,7 +268,6 @@ Texture Filtering = &ຕອງພື້ນຜິວ
Texture Scaling = &ປັບພື້ນຜິວ Texture Scaling = &ປັບພື້ນຜິວ
Use Lossless Video Codec (FFV1) = Use Lossless Video Codec (FFV1) Use Lossless Video Codec (FFV1) = Use Lossless Video Codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex ແຄດ
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &ຂະໜາດໜ້າຈໍ Window Size = &ຂະໜາດໜ້າຈໍ
@ -661,8 +660,6 @@ Upscale Level = ການເພີ່ມລະດັບສເກລພາບ
Upscale Type = ຮູບແບບການເພີ່ມສເກລພາບ Upscale Type = ຮູບແບບການເພີ່ມສເກລພາບ
UpscaleLevel Tip = ຊີພີຢູເຮັດວຽກໜັກຂຶ້ນ - ບາງສເກລພາບອາດເກີດອາການໜ່ວງຈົນເຖິງຂັ້ນບໍ່ສະແດງ UpscaleLevel Tip = ຊີພີຢູເຮັດວຽກໜັກຂຶ້ນ - ບາງສເກລພາບອາດເກີດອາການໜ່ວງຈົນເຖິງຂັ້ນບໍ່ສະແດງ
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex Cache
VertexCache Tip = ໄວຂຶ້ນ, ແຕ່ອາດເກີດມີອາການພາບກະພິບໃນບາງເທື່ອ
VSync = ຄວບຄຸມລະດັບເຟຣມເຣດໃຫ້ຄົງທີ່ VSync = ຄວບຄຸມລະດັບເຟຣມເຣດໃຫ້ຄົງທີ່
Vulkan = Vulkan Vulkan = Vulkan
Window Size = ຂະໜາດໜ້າຈໍ Window Size = ຂະໜາດໜ້າຈໍ

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&kstūrų filtravimas
Texture Scaling = &Tekstūrų Scaling Texture Scaling = &Tekstūrų Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = "VS&ync" VSync = "VS&ync"
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Lango dydis Window Size = &Lango dydis
@ -661,8 +660,6 @@ Upscale Level = "Pakėlimo" lygis
Upscale Type = "Pakėlimo" tipas Upscale Type = "Pakėlimo" tipas
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = "Tikra" spartinamoji atmintis
VertexCache Tip = Faster, but may cause temporary flicker
VSync = Kadrų per sekundę sinchrovizavimas su monitoriumi VSync = Kadrų per sekundę sinchrovizavimas su monitoriumi
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Lango dydis Window Size = Lango dydis

View File

@ -268,7 +268,6 @@ Texture Filtering = Penapisan Te&kstur
Texture Scaling = &Penskalaan Tekstur Texture Scaling = &Penskalaan Tekstur
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Kuki Vertek
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Saiz tetingkap Window Size = &Saiz tetingkap
@ -661,8 +660,6 @@ Upscale Level = Tahap penskalaan
Upscale Type = Jenis penskalaan Upscale Type = Jenis penskalaan
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Kuki Vertek
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Saiz tetingkap Window Size = Saiz tetingkap

View File

@ -268,7 +268,6 @@ Texture Filtering = &Texturefilter
Texture Scaling = Te&xtures schalen Texture Scaling = Te&xtures schalen
Use Lossless Video Codec (FFV1) = Lossless videocodec gebruiken (FFV1) Use Lossless Video Codec (FFV1) = Lossless videocodec gebruiken (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Vertex &Cache
VSync = Ve&rticale Synchronisatie VSync = Ve&rticale Synchronisatie
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Venster&grootte Window Size = Venster&grootte
@ -661,8 +660,6 @@ Upscale Level = Upscaleniveau
Upscale Type = Upscaletype Upscale Type = Upscaletype
UpscaleLevel Tip = CPU-belastend - schalen kan vertraagd worden om haperingen te voorkomen UpscaleLevel Tip = CPU-belastend - schalen kan vertraagd worden om haperingen te voorkomen
Use all displays = Alle beeldschermen gebruiken Use all displays = Alle beeldschermen gebruiken
Vertex Cache = Vertexcache
VertexCache Tip = Sneller, maar kan tijdelijk flikkeringen veroorzaken
VSync = Verticale synchronisatie VSync = Verticale synchronisatie
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Venstergrootte Window Size = Venstergrootte

View File

@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
Texture Scaling = &Texture Scaling Texture Scaling = &Texture Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window Size Window Size = &Window Size
@ -661,8 +660,6 @@ Upscale Level = Oppskaler nivå
Upscale Type = Oppskaler type Upscale Type = Oppskaler type
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex buffer
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -268,7 +268,6 @@ Texture Filtering = Filtrowanie tekstur
Texture Scaling = Skalowanie tekstur Texture Scaling = Skalowanie tekstur
Use Lossless Video Codec (FFV1) = &Używaj stratnego kodeka wideo (FFV1) Use Lossless Video Codec (FFV1) = &Używaj stratnego kodeka wideo (FFV1)
Use output buffer for video = Używaj buforu wyjścia dla wideo Use output buffer for video = Używaj buforu wyjścia dla wideo
Vertex Cache = Pamięć podręczna wierzchołków
VSync = Limit klatek VSync = Limit klatek
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Rozmiar okna Window Size = Rozmiar okna
@ -666,8 +665,6 @@ Upscale Level = Poziom skalowania
Upscale Type = Rodzaj skalowania Upscale Type = Rodzaj skalowania
UpscaleLevel Tip = Obciąża CPU - skalowanie może zostać opóźnione by zapobiec spadkom płynności UpscaleLevel Tip = Obciąża CPU - skalowanie może zostać opóźnione by zapobiec spadkom płynności
Use all displays = Używaj wszystkich monitorów Use all displays = Używaj wszystkich monitorów
Vertex Cache = Pamięć podręczna wierzchołków
VertexCache Tip = Szybsze, jednak może powodować krótkotrwałe migotanie
VSync = Synchronizacja pionowa VSync = Synchronizacja pionowa
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Rozmiar okna Window Size = Rozmiar okna

View File

@ -292,7 +292,6 @@ Texture Filtering = Fi&ltragem das texturas
Texture Scaling = &Dimensionamento das texturas Texture Scaling = &Dimensionamento das texturas
Use Lossless Video Codec (FFV1) = &Usar codec de vídeo sem perdas (FFV1) Use Lossless Video Codec (FFV1) = &Usar codec de vídeo sem perdas (FFV1)
Use output buffer for video = Usar buffer de saída pro vídeo Use output buffer for video = Usar buffer de saída pro vídeo
Vertex Cache = &Cache do vértice
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Tamanho da janela Window Size = &Tamanho da janela
@ -686,8 +685,6 @@ Upscale Level = Nível da ampliação
Upscale Type = Tipo de ampliação Upscale Type = Tipo de ampliação
UpscaleLevel Tip = Pesado pra CPU - alguns dimensionamentos podem ser atrasados pra evitar travamentos UpscaleLevel Tip = Pesado pra CPU - alguns dimensionamentos podem ser atrasados pra evitar travamentos
Use all displays = Usar todas as telas Use all displays = Usar todas as telas
Vertex Cache = Cache do vértice
VertexCache Tip = Mais rápido mas pode causar tremulação temporária
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Tamanho da janela Window Size = Tamanho da janela

View File

@ -292,7 +292,6 @@ Texture Filtering = Fi&ltragem das texturas
Texture Scaling = &Dimensionamento das texturas Texture Scaling = &Dimensionamento das texturas
Use Lossless Video Codec (FFV1) = &Usar Codec de Vídeo sem perdas (FFV1) Use Lossless Video Codec (FFV1) = &Usar Codec de Vídeo sem perdas (FFV1)
Use output buffer for video = Usar buffer de saída para o vídeo Use output buffer for video = Usar buffer de saída para o vídeo
Vertex Cache = &Cache do vértice
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Tamanho da Janela Window Size = &Tamanho da Janela
@ -685,8 +684,6 @@ Upscale Level = Nível de ampliação
Upscale Type = Tipo de ampliação Upscale Type = Tipo de ampliação
UpscaleLevel Tip = Pesado para a CPU - alguns dimensionamentos poderão atrasados para evitar travamentos UpscaleLevel Tip = Pesado para a CPU - alguns dimensionamentos poderão atrasados para evitar travamentos
Use all displays = Usar todas as telas Use all displays = Usar todas as telas
Vertex Cache = Cache do vértice
VertexCache Tip = Mais rápido, mas pode causar tremulação temporária
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Tamanho da janela Window Size = Tamanho da janela

View File

@ -269,7 +269,6 @@ Texture Filtering = Te&xture Filtering
Texture Scaling = &Texture Scaling Texture Scaling = &Texture Scaling
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = &Vertex Cache
VSync = VS&ync VSync = VS&ync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Window Size Window Size = &Window Size
@ -662,8 +661,6 @@ Upscale Level = Nivel Suprascalare
Upscale Type = Tip Suprascalare Upscale Type = Tip Suprascalare
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Stocare vertecși
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Mărime ecran Window Size = Mărime ecran

View File

@ -268,7 +268,6 @@ Texture Filtering = &Фильтрация текстур
Texture Scaling = &Масштабирование текстур Texture Scaling = &Масштабирование текстур
Use Lossless Video Codec (FFV1) = Использовать видеокодек без потерь (FFV1) Use Lossless Video Codec (FFV1) = Использовать видеокодек без потерь (FFV1)
Use output buffer for video = Использовать выходной буфер для видео Use output buffer for video = Использовать выходной буфер для видео
Vertex Cache = &Вершинный кэш
VSync = Вертикальная син&хронизация VSync = Вертикальная син&хронизация
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Размер &окна Window Size = Размер &окна
@ -661,8 +660,6 @@ Upscale Level = Уровень масштабирования
Upscale Type = Тип масштабирования Upscale Type = Тип масштабирования
UpscaleLevel Tip = Нагружает ЦП. Масштабирование может происходить с задержкой для предотвращения заиканий UpscaleLevel Tip = Нагружает ЦП. Масштабирование может происходить с задержкой для предотвращения заиканий
Use all displays = Задействовать все экраны Use all displays = Задействовать все экраны
Vertex Cache = Вершинный кэш
VertexCache Tip = Быстрее, но может вызывать мерцание
VSync = Вертикальная синхронизация VSync = Вертикальная синхронизация
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Размер окна Window Size = Размер окна

View File

@ -268,7 +268,6 @@ Texture Filtering = Texturfiltrering
Texture Scaling = Texturskalning Texture Scaling = Texturskalning
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Vertexcache
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Fönsterstorlek Window Size = Fönsterstorlek
@ -662,8 +661,6 @@ Upscale Level = Uppskalningsnivå
Upscale Type = Uppskalningstyp Upscale Type = Uppskalningstyp
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Använd alla displayer Use all displays = Använd alla displayer
Vertex Cache = Vertexcache
VertexCache Tip = Faster, but may cause temporary flicker
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Fönsterstorlek Window Size = Fönsterstorlek

View File

@ -268,7 +268,6 @@ Texture Filtering = Texture Filtering
Texture Scaling = Texture Scaling Texture Scaling = Texture Scaling
Use Lossless Video Codec (FFV1) = Use lossless video codec (FFV1) Use Lossless Video Codec (FFV1) = Use lossless video codec (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Vertex Cache
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window Size Window Size = Window Size
@ -661,8 +660,6 @@ Upscale Level = Antas ng upscale
Upscale Type = Uri ng upscale Upscale Type = Uri ng upscale
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
Use all displays = Use all displays Use all displays = Use all displays
Vertex Cache = Vertex Cache
VertexCache Tip = Mabilis, pero mag kaka flicker ng temporary
VSync = VSync VSync = VSync
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Window size Window Size = Window size

View File

@ -268,7 +268,6 @@ Texture Filtering = การกรองพื้นผิว
Texture Scaling = การปรับพื้นผิว Texture Scaling = การปรับพื้นผิว
Use Lossless Video Codec (FFV1) = ใช้โค้ด FFV1 บันทึกวีดีโอ เพื่อรักษาความคมชัด Use Lossless Video Codec (FFV1) = ใช้โค้ด FFV1 บันทึกวีดีโอ เพื่อรักษาความคมชัด
Use output buffer for video = ใช้การส่งออกบัฟเฟอร์ในการบันทึกวีดีโอ Use output buffer for video = ใช้การส่งออกบัฟเฟอร์ในการบันทึกวีดีโอ
Vertex Cache = เวอร์เท็กซ์ แคช
VSync = ควบคุมช่วงของเฟรมเรทให้คงที่ VSync = ควบคุมช่วงของเฟรมเรทให้คงที่
Vulkan = วัลแคน Vulkan = วัลแคน
Window Size = ขนาดของหน้าจอ Window Size = ขนาดของหน้าจอ
@ -661,8 +660,6 @@ Upscale Level = เพิ่มระดับสเกลภาพ
Upscale Type = รูปแบบการเพิ่มสเกลภาพ Upscale Type = รูปแบบการเพิ่มสเกลภาพ
UpscaleLevel Tip = ซีพียูทำงานหนักขึ้น บางสเกลภาพอาจเกิดอาการหน่วงจนถึงขั้นไม่แสดงผล UpscaleLevel Tip = ซีพียูทำงานหนักขึ้น บางสเกลภาพอาจเกิดอาการหน่วงจนถึงขั้นไม่แสดงผล
Use all displays = ใช้กับหน้าจอการแสดงผลทั้งหมด Use all displays = ใช้กับหน้าจอการแสดงผลทั้งหมด
Vertex Cache = เวอร์เท็ค แคช
VertexCache Tip = เร็วขึ้น แต่อาจทำให้เกิดอาการภาพกระพริบชั่วครั้งชั่วคราว
VSync = ควบคุมช่วงของเฟรมเรทให้คงที่ VSync = ควบคุมช่วงของเฟรมเรทให้คงที่
Vulkan = วัลแคน Vulkan = วัลแคน
Window Size = ขนาดของหน้าจอ Window Size = ขนาดของหน้าจอ

View File

@ -270,7 +270,6 @@ Texture Filtering = Doku Filtreleme
Texture Scaling = &Doku Ölçekleme Texture Scaling = &Doku Ölçekleme
Use Lossless Video Codec (FFV1) = &Kayıpsız video kodek'i kullan (FFV1) Use Lossless Video Codec (FFV1) = &Kayıpsız video kodek'i kullan (FFV1)
Use output buffer for video = Video için çıkış arabelleğini kullan Use output buffer for video = Video için çıkış arabelleğini kullan
Vertex Cache = &Vertex Önbellek
VSync = Dikey Eşleme (VSync) VSync = Dikey Eşleme (VSync)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = &Pencere Boyutu Window Size = &Pencere Boyutu
@ -663,8 +662,6 @@ Upscale Level = Ölçeklendirme seviyesi
Upscale Type = Ölçeklendirme türü Upscale Type = Ölçeklendirme türü
UpscaleLevel Tip = CPU ağır - takılmayı önlemek için bazı yeniden ölçeklendirmeler gecikebilir UpscaleLevel Tip = CPU ağır - takılmayı önlemek için bazı yeniden ölçeklendirmeler gecikebilir
Use all displays = Tüm ekranları kullan Use all displays = Tüm ekranları kullan
Vertex Cache = Vertex önbellek
VertexCache Tip = Daha hızlıdır, ancak geçici ekran titremesine neden olabilir
VSync = Dikey eşleme (Vsync) VSync = Dikey eşleme (Vsync)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Pencere boyutu Window Size = Pencere boyutu

View File

@ -268,7 +268,6 @@ Texture Filtering = &Фільтрація текстур
Texture Scaling = &Масштабування текстур Texture Scaling = &Масштабування текстур
Use Lossless Video Codec (FFV1) = &Використовувати відеокодек без втрат (FFV1) Use Lossless Video Codec (FFV1) = &Використовувати відеокодек без втрат (FFV1)
Use output buffer for video = Використовувати вихідний буфер для відео Use output buffer for video = Використовувати вихідний буфер для відео
Vertex Cache = &Вершинний кеш
VSync = Вертикальна син&хронізація VSync = Вертикальна син&хронізація
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Розмір &вікна Window Size = Розмір &вікна
@ -661,8 +660,6 @@ Upscale Level = Рівень масштабування
Upscale Type = Тип масштабування Upscale Type = Тип масштабування
UpscaleLevel Tip = Процесор завантажений - деяке масштабування може затягнутися, щоб уникнути заїкання UpscaleLevel Tip = Процесор завантажений - деяке масштабування може затягнутися, щоб уникнути заїкання
Use all displays = Використовувати всі екрани Use all displays = Використовувати всі екрани
Vertex Cache = Вершинний кеш
VertexCache Tip = Швидше, але може спричинити тимчасове мерехтіння
VSync = Вертикальна синхронізація VSync = Вертикальна синхронізація
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Розмір вікна Window Size = Розмір вікна

View File

@ -268,7 +268,6 @@ Texture Filtering = Bộ lọc texture
Texture Scaling = Scaling texture (thu nhỏ) Texture Scaling = Scaling texture (thu nhỏ)
Use Lossless Video Codec (FFV1) = Sử dụng codec video lossless (FFV1) Use Lossless Video Codec (FFV1) = Sử dụng codec video lossless (FFV1)
Use output buffer for video = Use output buffer for video Use output buffer for video = Use output buffer for video
Vertex Cache = Bộ đệm điểm
VSync = Đồng bộ VSync = Đồng bộ
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Kích cỡ màn hình Window Size = Kích cỡ màn hình
@ -661,8 +660,6 @@ Upscale Level = Cấp cao
Upscale Type = Loại cao cấp Upscale Type = Loại cao cấp
UpscaleLevel Tip = CPU nặng - một số tỷ lệ có thể bị hoãn để tránh lỗi. UpscaleLevel Tip = CPU nặng - một số tỷ lệ có thể bị hoãn để tránh lỗi.
Use all displays = Sử dụng tất cả các hiển thị Use all displays = Sử dụng tất cả các hiển thị
Vertex Cache = Bộ đệm điểm
VertexCache Tip = Nhanh hơn, nhưng có thể gây ra nhấp nháy
VSync = Đồng bộ VSync = Đồng bộ
Vulkan = Vulkan Vulkan = Vulkan
Window Size = Kích cỡ cửa sổ Window Size = Kích cỡ cửa sổ

View File

@ -268,7 +268,6 @@ Texture Filtering = 纹理过滤方法(&X)
Texture Scaling = 纹理缩放方法(&T) Texture Scaling = 纹理缩放方法(&T)
Use Lossless Video Codec (FFV1) = 使用无损视频编码器(FFV1)(&U) Use Lossless Video Codec (FFV1) = 使用无损视频编码器(FFV1)(&U)
Use output buffer for video = 录制包括输出缓冲 Use output buffer for video = 录制包括输出缓冲
Vertex Cache = 顶点缓存(&V)
VSync = 垂直同步(&Y) VSync = 垂直同步(&Y)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = 窗口大小(&W) Window Size = 窗口大小(&W)
@ -661,8 +660,6 @@ Upscale Level = 纹理缩放级别
Upscale Type = 纹理缩放 (CPU) Upscale Type = 纹理缩放 (CPU)
UpscaleLevel Tip = CPU负担大。某些缩放会延后以减少卡顿 UpscaleLevel Tip = CPU负担大。某些缩放会延后以减少卡顿
Use all displays = 使用全部显示器 Use all displays = 使用全部显示器
Vertex Cache = 顶点缓存
VertexCache Tip = 略微提速,可能造成暂时模型闪烁或丢失
VSync = 垂直同步 VSync = 垂直同步
Vulkan = Vulkan Vulkan = Vulkan
Window Size = 窗口大小 Window Size = 窗口大小

View File

@ -268,7 +268,6 @@ Texture Filtering = 紋理過濾(&X)
Texture Scaling = 紋理縮放(&T) Texture Scaling = 紋理縮放(&T)
Use Lossless Video Codec (FFV1) = 使用不失真視訊轉碼器 (FFV1)(&U) Use Lossless Video Codec (FFV1) = 使用不失真視訊轉碼器 (FFV1)(&U)
Use output buffer for video = 為視訊使用輸出緩衝區 Use output buffer for video = 為視訊使用輸出緩衝區
Vertex Cache = 頂點快取(&V)
VSync = 垂直同步(&Y) VSync = 垂直同步(&Y)
Vulkan = Vulkan Vulkan = Vulkan
Window Size = 視窗大小(&W) Window Size = 視窗大小(&W)
@ -661,8 +660,6 @@ Upscale Level = 放大層級
Upscale Type = 放大類型 Upscale Type = 放大類型
UpscaleLevel Tip = CPU 負載過重 - 部分縮放可能會延遲以避免間斷 UpscaleLevel Tip = CPU 負載過重 - 部分縮放可能會延遲以避免間斷
Use all displays = 使用所有顯示器 Use all displays = 使用所有顯示器
Vertex Cache = 頂點快取
VertexCache Tip = 更快,但可能會造成暫時閃爍
VSync = 垂直同步 VSync = 垂直同步
Vulkan = Vulkan Vulkan = Vulkan
Window Size = 視窗大小 Window Size = 視窗大小

View File

@ -472,7 +472,6 @@ int main(int argc, const char* argv[])
g_Config.bHardwareTransform = true; g_Config.bHardwareTransform = true;
g_Config.iAnisotropyLevel = 0; // When testing mipmapping we really don't want this. g_Config.iAnisotropyLevel = 0; // When testing mipmapping we really don't want this.
g_Config.iMultiSampleLevel = 0; g_Config.iMultiSampleLevel = 0;
g_Config.bVertexCache = false;
g_Config.iLanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; g_Config.iLanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR; g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
g_Config.bEncryptSave = true; g_Config.bEncryptSave = true;

View File

@ -706,15 +706,6 @@ static void check_variables(CoreParameter &coreParam)
g_Config.bSoftwareSkinning = true; g_Config.bSoftwareSkinning = true;
} }
var.key = "ppsspp_vertex_cache";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "disabled"))
g_Config.bVertexCache = false;
else
g_Config.bVertexCache = true;
}
var.key = "ppsspp_lazy_texture_caching"; var.key = "ppsspp_lazy_texture_caching";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {