mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Merge pull request #18339 from hrydgard/delete-vertex-cache
Remove the vertex cache option
This commit is contained in:
commit
bdff93374b
@ -35,127 +35,6 @@ using namespace PPSSPP_VK;
|
||||
// Always keep around push buffers at least this long (seconds).
|
||||
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)
|
||||
: vulkan_(vulkan), name_(name), originalBlockSize_(originalBlockSize), usage_(usage) {
|
||||
RegisterGPUMemoryManager(this);
|
||||
|
@ -16,88 +16,6 @@ VK_DEFINE_HANDLE(VmaAllocation);
|
||||
//
|
||||
// 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 -
|
||||
// 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).
|
||||
|
@ -590,7 +590,6 @@ static const ConfigSetting graphicsSettings[] = {
|
||||
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("VertexDecCache", &g_Config.bVertexCache, 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),
|
||||
|
||||
|
@ -176,7 +176,6 @@ public:
|
||||
float fUITint;
|
||||
float fUISaturation;
|
||||
|
||||
bool bVertexCache;
|
||||
bool bTextureBackoffCache;
|
||||
bool bVertexDecoderJit;
|
||||
bool bFullScreen;
|
||||
|
@ -575,80 +575,6 @@ void DrawEngineCommon::ApplyFramebufferRead(FBOTexState *fboTexState) {
|
||||
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 sum = 0;
|
||||
for (int i = 0; i < numDrawVerts_; i++) {
|
||||
@ -657,32 +583,6 @@ int DrawEngineCommon::ComputeNumVertsToDecode() const {
|
||||
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) {
|
||||
const uint32_t *start = cmd;
|
||||
int prevDrawVerts = numDrawVerts_ - 1;
|
||||
|
@ -159,10 +159,6 @@ protected:
|
||||
// Preprocessing for spline/bezier
|
||||
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;
|
||||
|
||||
void ApplyFramebufferRead(FBOTexState *fboTexState);
|
||||
@ -271,7 +267,6 @@ protected:
|
||||
int numDrawInds_ = 0;
|
||||
int vertexCountInDrawCalls_ = 0;
|
||||
|
||||
int decimationCounter_ = 0;
|
||||
int decodeVertsCounter_ = 0;
|
||||
int decodeIndsCounter_ = 0;
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
#define VERTEXCACHE_DECIMATION_INTERVAL 17
|
||||
|
||||
enum { VAI_KILL_AGE = 120, VAI_UNRELIABLE_KILL_AGE = 240, VAI_UNRELIABLE_KILL_MAX = 4 };
|
||||
enum {
|
||||
VERTEX_PUSH_SIZE = 1024 * 1024 * 16,
|
||||
INDEX_PUSH_SIZE = 1024 * 1024 * 4,
|
||||
@ -73,7 +70,6 @@ DrawEngineD3D11::DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device,
|
||||
: draw_(draw),
|
||||
device_(device),
|
||||
context_(context),
|
||||
vai_(256),
|
||||
inputLayoutMap_(32),
|
||||
blendCache_(32),
|
||||
blendCache1_(32),
|
||||
@ -84,7 +80,6 @@ DrawEngineD3D11::DrawEngineD3D11(Draw::DrawContext *draw, ID3D11Device *device,
|
||||
decOptions_.expandAllWeightsToFloat = true;
|
||||
decOptions_.expand8BitNormalsToFloat = true;
|
||||
|
||||
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
|
||||
// Allocate nicely aligned memory. Maybe graphics drivers will
|
||||
// appreciate it.
|
||||
// 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));
|
||||
}
|
||||
|
||||
void DrawEngineD3D11::ClearTrackedVertexArrays() {
|
||||
vai_.Iterate([&](uint32_t hash, VertexArrayInfoD3D11 *vai){
|
||||
delete vai;
|
||||
});
|
||||
vai_.Clear();
|
||||
}
|
||||
|
||||
void DrawEngineD3D11::ClearInputLayoutMap() {
|
||||
inputLayoutMap_.Iterate([&](const InputLayoutKey &key, ID3D11InputLayout *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() {
|
||||
pushVerts_->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;
|
||||
}
|
||||
|
||||
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.
|
||||
void DrawEngineD3D11::Invalidate(InvalidationCallbackFlags flags) {
|
||||
if (flags & InvalidationCallbackFlags::RENDER_PASS_STATE) {
|
||||
@ -354,175 +286,16 @@ void DrawEngineD3D11::DoFlush() {
|
||||
ID3D11Buffer *vb_ = 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_);
|
||||
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();
|
||||
useElements = !indexGen.SeenOnlyPurePrims() || prim == GE_PRIM_TRIANGLE_FAN;
|
||||
vertexCount = indexGen.VertexCount();
|
||||
maxIndex = MaxIndex();
|
||||
if (!useElements && indexGen.PureCount()) {
|
||||
vertexCount = indexGen.PureCount();
|
||||
}
|
||||
prim = indexGen.Prim();
|
||||
DecodeVerts(decoded_);
|
||||
DecodeInds();
|
||||
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
|
||||
bool useElements = !indexGen.SeenOnlyPurePrims() || prim == GE_PRIM_TRIANGLE_FAN;
|
||||
int vertexCount = indexGen.VertexCount();
|
||||
int maxIndex = MaxIndex();
|
||||
if (!useElements && indexGen.PureCount()) {
|
||||
vertexCount = indexGen.PureCount();
|
||||
}
|
||||
prim = indexGen.Prim();
|
||||
|
||||
bool hasColor = (lastVType_ & GE_VTYPE_COL_MASK) != GE_VTYPE_COL_NONE;
|
||||
if (gstate.isModeThrough()) {
|
||||
|
@ -38,65 +38,6 @@ class ShaderManagerD3D11;
|
||||
class TextureCacheD3D11;
|
||||
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 {
|
||||
private:
|
||||
ID3D11DeviceContext *context_;
|
||||
@ -155,8 +96,6 @@ public:
|
||||
Flush();
|
||||
}
|
||||
|
||||
void ClearTrackedVertexArrays() override;
|
||||
|
||||
void NotifyConfigChanged() override;
|
||||
|
||||
void ClearInputLayoutMap();
|
||||
@ -171,16 +110,12 @@ private:
|
||||
|
||||
ID3D11InputLayout *SetupDecFmtForDraw(D3D11VertexShader *vshader, const DecVtxFormat &decFmt, u32 pspFmt);
|
||||
|
||||
void MarkUnreliable(VertexArrayInfoD3D11 *vai);
|
||||
|
||||
Draw::DrawContext *draw_; // Used for framebuffer related things exclusively.
|
||||
ID3D11Device *device_;
|
||||
ID3D11Device1 *device1_;
|
||||
ID3D11DeviceContext *context_;
|
||||
ID3D11DeviceContext1 *context1_;
|
||||
|
||||
PrehashMap<VertexArrayInfoD3D11 *> vai_;
|
||||
|
||||
struct InputLayoutKey {
|
||||
D3D11VertexShader *vshader;
|
||||
u32 decFmtId;
|
||||
|
@ -72,10 +72,6 @@ enum {
|
||||
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[] = {
|
||||
{ 0, offsetof(TransformedVertex, pos), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, offsetof(TransformedVertex, uv), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
@ -85,13 +81,11 @@ static const D3DVERTEXELEMENT9 TransformedVertexElements[] = {
|
||||
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);
|
||||
decOptions_.expandAllWeightsToFloat = true;
|
||||
decOptions_.expand8BitNormalsToFloat = true;
|
||||
|
||||
decimationCounter_ = VERTEXCACHE_DECIMATION_INTERVAL;
|
||||
|
||||
indexGen.Setup(decIndex_);
|
||||
|
||||
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) {
|
||||
return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000);
|
||||
}
|
||||
|
||||
void DrawEngineDX9::BeginFrame() {
|
||||
gpuStats.numTrackedVertexArrays = (int)vai_.size();
|
||||
|
||||
DecimateTrackedVertexArrays();
|
||||
|
||||
lastRenderStepId_ = -1;
|
||||
}
|
||||
|
||||
@ -336,166 +261,9 @@ void DrawEngineDX9::DoFlush() {
|
||||
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();
|
||||
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_);
|
||||
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();
|
||||
useElements = !indexGen.SeenOnlyPurePrims();
|
||||
vertexCount = indexGen.VertexCount();
|
||||
|
@ -35,65 +35,6 @@ class ShaderManagerDX9;
|
||||
class TextureCacheDX9;
|
||||
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 {
|
||||
public:
|
||||
TessellationDataTransferDX9() {}
|
||||
@ -122,8 +63,6 @@ public:
|
||||
void InitDeviceObjects();
|
||||
void DestroyDeviceObjects();
|
||||
|
||||
void ClearTrackedVertexArrays() override;
|
||||
|
||||
void BeginFrame();
|
||||
|
||||
// So that this can be inlined
|
||||
@ -148,7 +87,6 @@ public:
|
||||
protected:
|
||||
// Not currently supported.
|
||||
bool UpdateUseHWTessellation(bool enable) const override { return false; }
|
||||
void DecimateTrackedVertexArrays();
|
||||
|
||||
private:
|
||||
void Invalidate(InvalidationCallbackFlags flags);
|
||||
@ -159,12 +97,9 @@ private:
|
||||
|
||||
IDirect3DVertexDeclaration9 *SetupDecFmtForDraw(const DecVtxFormat &decFmt, u32 pspFmt);
|
||||
|
||||
void MarkUnreliable(VertexArrayInfoDX9 *vai);
|
||||
|
||||
LPDIRECT3DDEVICE9 device_ = nullptr;
|
||||
Draw::DrawContext *draw_;
|
||||
|
||||
PrehashMap<VertexArrayInfoDX9 *> vai_;
|
||||
DenseHashMap<u32, IDirect3DVertexDeclaration9 *> vertexDeclMap_;
|
||||
|
||||
// SimpleVertex
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include "GPU/GLES/ShaderManagerGLES.h"
|
||||
#include "GPU/GLES/GPU_GLES.h"
|
||||
|
||||
const GLuint glprim[8] = {
|
||||
static const GLuint glprim[8] = {
|
||||
// Points, which are expanded to triangles.
|
||||
GL_TRIANGLES,
|
||||
// Lines and line strips, which are also expanded to triangles.
|
||||
@ -149,8 +149,6 @@ void DrawEngineGLES::ClearInputLayoutMap() {
|
||||
}
|
||||
|
||||
void DrawEngineGLES::BeginFrame() {
|
||||
gpuStats.numTrackedVertexArrays = 0;
|
||||
|
||||
FrameData &frameData = frameData_[render_->GetCurFrame()];
|
||||
render_->BeginPushBuffer(frameData.pushIndex);
|
||||
render_->BeginPushBuffer(frameData.pushVertex);
|
||||
|
@ -78,11 +78,8 @@ struct GPUStatistics {
|
||||
numVertexDecodes = 0;
|
||||
numDrawSyncs = 0;
|
||||
numListSyncs = 0;
|
||||
numCachedDrawCalls = 0;
|
||||
numVertsSubmitted = 0;
|
||||
numCachedVertsDrawn = 0;
|
||||
numUncachedVertsDrawn = 0;
|
||||
numTrackedVertexArrays = 0;
|
||||
numTextureInvalidations = 0;
|
||||
numTextureInvalidationsByFramebuffer = 0;
|
||||
numTexturesHashed = 0;
|
||||
@ -115,14 +112,11 @@ struct GPUStatistics {
|
||||
int numVertexDecodes;
|
||||
int numDrawSyncs;
|
||||
int numListSyncs;
|
||||
int numCachedDrawCalls;
|
||||
int numFlushes;
|
||||
int numBBOXJumps;
|
||||
int numPlaneUpdates;
|
||||
int numVertsSubmitted;
|
||||
int numCachedVertsDrawn;
|
||||
int numUncachedVertsDrawn;
|
||||
int numTrackedVertexArrays;
|
||||
int numTextureInvalidations;
|
||||
int numTextureInvalidationsByFramebuffer;
|
||||
int numTexturesHashed;
|
||||
|
@ -1685,8 +1685,7 @@ size_t GPUCommonHW::FormatGPUStatsCommon(char *buffer, size_t size) {
|
||||
return snprintf(buffer, size,
|
||||
"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"
|
||||
"Cached draws: %d (tracked: %d)\n"
|
||||
"Vertices: %d cached: %d uncached: %d\n"
|
||||
"Vertices: %d drawn: %d\n"
|
||||
"FBOs active: %d (evaluations: %d)\n"
|
||||
"Textures: %d, dec: %d, invalidated: %d, hashed: %d kB\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.numBBOXJumps,
|
||||
gpuStats.numPlaneUpdates,
|
||||
gpuStats.numCachedDrawCalls,
|
||||
gpuStats.numTrackedVertexArrays,
|
||||
gpuStats.numVertsSubmitted,
|
||||
gpuStats.numCachedVertsDrawn,
|
||||
gpuStats.numUncachedVertsDrawn,
|
||||
(int)framebufferManager_->NumVFBs(),
|
||||
gpuStats.numFramebufferEvaluations,
|
||||
|
@ -54,20 +54,12 @@
|
||||
|
||||
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 {
|
||||
TRANSFORMED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * sizeof(TransformedVertex)
|
||||
};
|
||||
|
||||
DrawEngineVulkan::DrawEngineVulkan(Draw::DrawContext *draw)
|
||||
: draw_(draw), vai_(1024) {
|
||||
: draw_(draw) {
|
||||
decOptions_.expandAllWeightsToFloat = false;
|
||||
decOptions_.expand8BitNormalsToFloat = false;
|
||||
#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
|
||||
@ -117,8 +109,6 @@ void DrawEngineVulkan::InitDeviceObjects() {
|
||||
res = vkCreateSampler(device, &samp, nullptr, &nullSampler_);
|
||||
_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);
|
||||
tessDataTransfer = tessDataTransferVulkan;
|
||||
|
||||
@ -163,18 +153,8 @@ void DrawEngineVulkan::DestroyDeviceObjects() {
|
||||
vulkan->Delete().QueueDeleteSampler(samplerSecondaryLinear_);
|
||||
if (nullSampler_ != VK_NULL_HANDLE)
|
||||
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.
|
||||
vai_.Iterate([](uint32_t hash, VertexArrayInfoVulkan *vai) {
|
||||
delete vai;
|
||||
});
|
||||
vai_.Clear();
|
||||
renderManager->DestroyPipelineLayout(pipelineLayout_);
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::DeviceLost() {
|
||||
@ -189,8 +169,6 @@ void DrawEngineVulkan::DeviceRestore(Draw::DrawContext *draw) {
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::BeginFrame() {
|
||||
gpuStats.numTrackedVertexArrays = (int)vai_.size();
|
||||
|
||||
lastPipeline_ = nullptr;
|
||||
|
||||
// pushUBO is the thin3d push pool, don't need to BeginFrame again.
|
||||
@ -200,65 +178,11 @@ void DrawEngineVulkan::BeginFrame() {
|
||||
tessDataTransferVulkan->SetPushPool(pushUBO_);
|
||||
|
||||
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() {
|
||||
stats_.pushVertexSpaceUsed = (int)pushVertex_->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) {
|
||||
@ -285,12 +209,6 @@ void DrawEngineVulkan::DirtyAllUBOs() {
|
||||
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) {
|
||||
if (flags & InvalidationCallbackFlags::COMMAND_BUFFER_STATE) {
|
||||
// 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
|
||||
void DrawEngineVulkan::DoFlush() {
|
||||
VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
@ -490,32 +256,21 @@ void DrawEngineVulkan::DoFlush() {
|
||||
if (useHWTransform) {
|
||||
int vertexCount = 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.
|
||||
VkBuffer vbuf = VK_NULL_HANDLE;
|
||||
VkBuffer ibuf = VK_NULL_HANDLE;
|
||||
if (decOptions_.applySkinInDecode && (lastVType_ & GE_VTYPE_WEIGHT_MASK)) {
|
||||
useCache = false;
|
||||
}
|
||||
bool useIndexGen = true;
|
||||
if (useCache) {
|
||||
useIndexGen = VertexCacheLookup(vertexCount, prim, vbuf, vbOffset, ibuf, ibOffset, useElements, forceIndexed);
|
||||
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.
|
||||
DecodeVerts(decoded_);
|
||||
VkDeviceSize size = decodedVerts_ * dec_->GetDecVtxFmt().stride;
|
||||
u8 *dest = (u8 *)pushVertex_->Allocate(size, 4, &vbuf, &vbOffset);
|
||||
memcpy(dest, decoded_, size);
|
||||
} else {
|
||||
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.
|
||||
DecodeVerts(decoded_);
|
||||
VkDeviceSize size = decodedVerts_ * dec_->GetDecVtxFmt().stride;
|
||||
u8 *dest = (u8 *)pushVertex_->Allocate(size, 4, &vbuf, &vbOffset);
|
||||
memcpy(dest, decoded_, size);
|
||||
} else {
|
||||
// Decode directly into the pushbuffer
|
||||
DecodeVertsToPushPool(pushVertex_, &vbOffset, &vbuf);
|
||||
}
|
||||
DecodeInds();
|
||||
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
|
||||
// Decode directly into the pushbuffer
|
||||
DecodeVertsToPushPool(pushVertex_, &vbOffset, &vbuf);
|
||||
}
|
||||
DecodeInds();
|
||||
gpuStats.numUncachedVertsDrawn += indexGen.VertexCount();
|
||||
|
||||
if (useIndexGen) {
|
||||
vertexCount = indexGen.VertexCount();
|
||||
|
@ -61,7 +61,6 @@ class TextureCacheVulkan;
|
||||
class FramebufferManagerVulkan;
|
||||
|
||||
class VulkanContext;
|
||||
class VulkanPushBuffer;
|
||||
class VulkanPushPool;
|
||||
struct VulkanPipeline;
|
||||
|
||||
@ -70,49 +69,6 @@ struct DrawEngineVulkanStats {
|
||||
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 TessellationDataTransferVulkan : public TessellationDataTransfer {
|
||||
@ -228,10 +184,7 @@ private:
|
||||
|
||||
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 DecodeVertsToPushBuffer(VulkanPushBuffer *push, uint32_t *bindOffset, VkBuffer *vkbuf);
|
||||
|
||||
void DoFlush();
|
||||
void UpdateUBOs();
|
||||
@ -254,9 +207,6 @@ private:
|
||||
VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE;
|
||||
VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE;
|
||||
|
||||
PrehashMap<VertexArrayInfoVulkan *> vai_;
|
||||
VulkanPushBuffer *vertexCache_;
|
||||
|
||||
struct DescriptorSetKey {
|
||||
VkImageView imageView_;
|
||||
VkImageView secondaryImageView_;
|
||||
|
@ -33,7 +33,6 @@ class DrawEngineVulkan;
|
||||
|
||||
class VulkanContext;
|
||||
class VulkanTexture;
|
||||
class VulkanPushBuffer;
|
||||
|
||||
class SamplerCache {
|
||||
public:
|
||||
|
@ -650,8 +650,6 @@ void MainWindow::createMenus()
|
||||
|
||||
gameSettingsMenu->add(new MenuAction(this, SLOT(transformAct()), QT_TR_NOOP("&Hardware transform")))
|
||||
->addEventChecked(&g_Config.bHardwareTransform);
|
||||
gameSettingsMenu->add(new MenuAction(this, SLOT(vertexCacheAct()), QT_TR_NOOP("&Vertex cache")))
|
||||
->addEventChecked(&g_Config.bVertexCache);
|
||||
gameSettingsMenu->addSeparator();
|
||||
gameSettingsMenu->add(new MenuAction(this, SLOT(audioAct()), QT_TR_NOOP("Enable s&ound")))
|
||||
->addEventChecked(&g_Config.bEnableSound);
|
||||
|
@ -157,7 +157,6 @@ private slots:
|
||||
g_Config.bHardwareTransform = !g_Config.bHardwareTransform;
|
||||
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
|
||||
}
|
||||
void vertexCacheAct() { g_Config.bVertexCache = !g_Config.bVertexCache; }
|
||||
void frameskipAct() { g_Config.iFrameSkip = !g_Config.iFrameSkip; }
|
||||
void frameskipTypeAct() { g_Config.iFrameSkipType = !g_Config.iFrameSkipType; }
|
||||
|
||||
|
@ -401,15 +401,6 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
|
||||
CheckBox *skipGPUReadbacks = graphicsSettings->Add(new CheckBox(&g_Config.bSkipGPUReadbacks, gr->T("Skip GPU Readbacks")));
|
||||
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)")));
|
||||
texBackoff->SetDisabledPtr(&g_Config.bSoftwareRendering);
|
||||
texBackoff->OnClick.Add([=](EventParams& e) {
|
||||
|
@ -290,7 +290,6 @@ namespace MainWindow {
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID_BICUBIC);
|
||||
TranslateMenuItem(menu, ID_TEXTURESCALING_DEPOSTERIZE);
|
||||
TranslateMenuItem(menu, ID_OPTIONS_HARDWARETRANSFORM);
|
||||
TranslateMenuItem(menu, ID_OPTIONS_VERTEXCACHE);
|
||||
TranslateMenuItem(menu, ID_EMULATION_SOUND);
|
||||
TranslateMenuItem(menu, ID_EMULATION_CHEATS, g_Config.bSystemControls ? L"\tCtrl+T" : L"");
|
||||
TranslateMenuItem(menu, ID_EMULATION_CHAT, g_Config.bSystemControls ? L"\tCtrl+C" : L"");
|
||||
@ -859,9 +858,6 @@ namespace MainWindow {
|
||||
SendToggleFullscreen(!g_Config.UseFullScreen());
|
||||
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_NEARESTFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_NEAREST; 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_OPTIONS_HARDWARETRANSFORM, g_Config.bHardwareTransform);
|
||||
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, g_Config.iFrameSkip != FRAMESKIP_OFF);
|
||||
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));
|
||||
}
|
||||
|
||||
// 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] = {
|
||||
ID_OPTIONS_SCREENAUTO,
|
||||
ID_OPTIONS_SCREEN1X,
|
||||
|
@ -685,7 +685,6 @@ BEGIN
|
||||
MENUITEM "Deposterize", ID_TEXTURESCALING_DEPOSTERIZE
|
||||
END
|
||||
MENUITEM "Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM
|
||||
MENUITEM "Vertex Cache", ID_OPTIONS_VERTEXCACHE
|
||||
MENUITEM "", 0, MFT_SEPARATOR
|
||||
MENUITEM "Enable Sound", ID_EMULATION_SOUND
|
||||
MENUITEM "", 0, MFT_SEPARATOR
|
||||
|
@ -169,7 +169,6 @@
|
||||
#define ID_OPTIONS_CONTROLS 40038
|
||||
#define ID_DEBUG_BREAKONLOAD 40039
|
||||
#define ID_DEBUG_DUMPNEXTFRAME 40040
|
||||
#define ID_OPTIONS_VERTEXCACHE 40041
|
||||
#define ID_OPTIONS_FRAMESKIP 40044
|
||||
#define IDC_MEMCHECK 40045
|
||||
#define ID_FILE_MEMSTICK 40046
|
||||
|
@ -276,7 +276,6 @@ Texture Filtering = Te&xture filtering
|
||||
Texture Scaling = &تكبير الرسوم
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &مخزن الفريتكس
|
||||
VSync = VS&ync
|
||||
Vulkan = فولكان
|
||||
Window Size = &حجم النافذة
|
||||
@ -669,8 +668,6 @@ Upscale Level = مستوي التكبير
|
||||
Upscale Type = نوع التكبير
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex cache
|
||||
VertexCache Tip = أسرع, لكن ربما يسبب تميع مؤقت
|
||||
VSync = VSync
|
||||
Vulkan = فولكان
|
||||
Window Size = حجم النافذة
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
|
||||
Texture Scaling = &Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window Size
|
||||
@ -661,8 +660,6 @@ Upscale Level = Upscale level
|
||||
Upscale Type = Upscale type
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex Keş
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Текстурно филтриране
|
||||
Texture Scaling = Текстурно мащабиране
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Размер на прозореца
|
||||
@ -661,8 +660,6 @@ Upscale Level = Upscale level
|
||||
Upscale Type = Upscale type
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex cache
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Размер на прозореца
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Filtrat de te&xtura
|
||||
Texture Scaling = Escalat de &textura
|
||||
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
|
||||
Vertex Cache = &Memòria cau de vèrtexs
|
||||
VSync = Sincronització vertical (VS&ync)
|
||||
Vulkan = Vulkan
|
||||
Window Size = Mida de la &finestra
|
||||
@ -661,8 +660,6 @@ Upscale Level = Nivell d'escalat
|
||||
Upscale Type = Tipus d'escalat
|
||||
UpscaleLevel Tip = Exigeix consum de CPU, alguns escalats es poden retardar per evitar estrebades.
|
||||
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)
|
||||
Vulkan = Vulkan
|
||||
Window Size = Mida de la finestra
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Filtrování textur
|
||||
Texture Scaling = &Změna velikosti textur
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Mezipaměť verte&xů
|
||||
VSync = Vertikální S&ynchronizace
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Velikost okna
|
||||
@ -661,8 +660,6 @@ Upscale Level = Úroveň zvětšení
|
||||
Upscale Type = Typ zvětšení
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Mezipaměť vertexů
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = Vertikální synchronizace
|
||||
Vulkan = Vulkan
|
||||
Window Size = Velikost okna
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xturfilter
|
||||
Texture Scaling = &Texturskalering
|
||||
Use Lossless Video Codec (FFV1) = Brug Tabsfri Video Codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertexcache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Vinduesstørrelse
|
||||
@ -661,8 +660,6 @@ Upscale Level = Opskaleringsniveau
|
||||
Upscale Type = Opskaleringstype
|
||||
UpscaleLevel Tip = CPU tung - noget skallering kan belive forsinket for at undgå flimmer
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertexcache
|
||||
VertexCache Tip = Hurtigere, men kan medføre midlertidig flimmer
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Vinduesstørrelse
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Texturfilter
|
||||
Texture Scaling = Texturskalierung
|
||||
Use Lossless Video Codec (FFV1) = Benutze verlustfreien Videocodec (FFV1)
|
||||
Use output buffer for video = Benutze Ausgabepuffer für Video
|
||||
Vertex Cache = Vertex-Cache
|
||||
VSync = V-Sync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Fenstergröße
|
||||
@ -661,8 +660,6 @@ Upscale Level = Skalierungsgrad
|
||||
Upscale Type = Skalierungsart
|
||||
UpscaleLevel Tip = CPU-lastig - einige Skalierungen könnten verzögert sein um Stottern zu vermeiden
|
||||
Use all displays = Benutze alle Bildschirme
|
||||
Vertex Cache = Vertex-Cache
|
||||
VertexCache Tip = Schneller, kann temporäres Flackern verursachen
|
||||
VSync = V-Sync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Fenstergröße
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
|
||||
Texture Scaling = &Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window Size
|
||||
@ -661,8 +660,6 @@ Upscale Level = Patonggoi skala
|
||||
Upscale Type = Skala apa mane?
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Pangnganna Vertex
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -292,7 +292,6 @@ Texture Filtering = Te&xture filtering
|
||||
Texture Scaling = &Texture scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window size
|
||||
@ -686,8 +685,6 @@ Upscale Level = Upscale level
|
||||
Upscale Type = Upscale type
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex cache
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Filtrado de texturas
|
||||
Texture Scaling = &Escalado de texturas
|
||||
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
|
||||
Vertex Cache = &Caché de vértices
|
||||
VSync = Sincronización &vertical
|
||||
Vulkan = &Vulkan
|
||||
Window Size = &Tamaño de ventana
|
||||
@ -661,8 +660,6 @@ Upscale Level = Nivel de escalado
|
||||
Upscale Type = Tipo de escalado
|
||||
UpscaleLevel Tip = Exige consumo de CPU, algunos escalados se pueden retrasar para evitar tirones.
|
||||
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)
|
||||
Vulkan = Vulkan
|
||||
Window Size = Tamaño de ventana
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Filtrado de texturas
|
||||
Texture Scaling = &Escalado de texturas
|
||||
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
|
||||
Vertex Cache = &Caché de vértices
|
||||
VSync = Sincronización &vertical
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Tamaño de ventana
|
||||
@ -661,8 +660,6 @@ Upscale Level = Nivel de escalado
|
||||
Upscale Type = Tipo de escalado
|
||||
UpscaleLevel Tip = Consume tanta CPU. Cierto escalado se retrasa para evitar caídas de frames.
|
||||
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)
|
||||
Vulkan = Vulkan
|
||||
Window Size = Tamaño de ventana
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = فیلتر تکسچر
|
||||
Texture Scaling = تغییر سایز تکسچر
|
||||
Use Lossless Video Codec (FFV1) = (FFV1) استفاده از کدک بدون دستکاری
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Vertex کش کردن
|
||||
VSync = VS&ync
|
||||
Vulkan = والکمن
|
||||
Window Size = سایز پنجره
|
||||
@ -661,8 +660,6 @@ Upscale Level = میزان افزایش سایز
|
||||
Upscale Type = نوع افزایش سایز
|
||||
UpscaleLevel Tip = زیاد کار میکشد CPU از
|
||||
Use all displays = استفاده از همه نمایشگر ها
|
||||
Vertex Cache = Vertex کش
|
||||
VertexCache Tip = سریع تر، اما ممکن است باعث لرزش موقتی شود
|
||||
VSync = VSync
|
||||
Vulkan = والکمن
|
||||
Window Size = سایز پنجره
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Tekstuurien suodatus
|
||||
Texture Scaling = &Tekstuurien skaalaus
|
||||
Use Lossless Video Codec (FFV1) = Käytä häviötöntä &videokoodekkia (FFV1)
|
||||
Use output buffer for video = Käytä ulostulopuskuria videolle
|
||||
Vertex Cache = &Vertex-välimuisti
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Ikkunan koko
|
||||
@ -661,8 +660,6 @@ Upscale Level = Ylösskaalauksen taso
|
||||
Upscale Type = Ylösskaalauksen tapa
|
||||
UpscaleLevel Tip = Prosessorille raskas - joillekkin skaalauksille voidaan antaa viivettä nykimisen välttämiseksi
|
||||
Use all displays = Käytä kaikkia näyttöjä
|
||||
Vertex Cache = Verteksivälimuisti
|
||||
VertexCache Tip = Nopeampi, mutta voi välillä aiheuttaa vilkkumista
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Ikkunan koko
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Filtrage des textures
|
||||
Texture Scaling = Mise à l'échelle des &textures
|
||||
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
|
||||
Vertex Cache = &Cache vertex
|
||||
VSync = Synchronisation &verticale
|
||||
Vulkan = Vulkan
|
||||
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
|
||||
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
|
||||
Vertex Cache = Cache vertex
|
||||
VertexCache Tip = Plus rapide, mais peut causer des scintillements temporaires
|
||||
VSync = Synchronisation verticale
|
||||
Vulkan = Vulkan
|
||||
Window Size = Taille de la fenêtre
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Filtrado de texturas
|
||||
Texture Scaling = &Escalado de texturas
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Caché de vértices
|
||||
VSync = Sincronización &vertical
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Tamaño de ventá
|
||||
@ -661,8 +660,6 @@ Upscale Level = Nivel de escalado
|
||||
Upscale Type = Tipo de escalado
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Caché de vértices
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = Sincronización vertical
|
||||
Vulkan = Vulkan
|
||||
Window Size = Tamaño de ventana
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Φιλτράρισμα Υφών
|
||||
Texture Scaling = Κλιμάκωση Υφών
|
||||
Use Lossless Video Codec (FFV1) = Χρήση μη απολεστικού κωδικοποιητή (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Π&ροσωρινή Μνήμη Κορυφών
|
||||
VSync = Κά&θετος Συγχρονισμός
|
||||
Vulkan = Vulkan
|
||||
Window Size = Μέγεθος Παραθύρου
|
||||
@ -661,8 +660,6 @@ Upscale Level = Επίπεδο Κλιμάκωσης
|
||||
Upscale Type = Τύπος Κλιμάκωσης
|
||||
UpscaleLevel Tip = Βαρύ για τον επεξεργαστή - κάποια κλιμάκωση μπορεί να καθυστερήσει για να αποφευχθούν κολλήματα
|
||||
Use all displays = Χρησιμοποιήστε όλες τις οθόνες
|
||||
Vertex Cache = Προσωρινή Μνήμη Κορυφών
|
||||
VertexCache Tip = Πιο γρήγορα, αλλά μπορεί να προκαλέσει προσωρινό τρεμόπαιγμα
|
||||
VSync = Κάθετος Συγχρονισμός
|
||||
Vulkan = Vulkan
|
||||
Window Size = Μέγεθος Παραθύρου
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
|
||||
Texture Scaling = &Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window Size
|
||||
@ -661,8 +660,6 @@ Upscale Level = רמה יוקרתית
|
||||
Upscale Type = סוג יוקרתי
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex מטמון
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = סנכרון אנכי
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
|
||||
Texture Scaling = &Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window Size
|
||||
@ -661,8 +660,6 @@ Upscale Level = תיתרקוי המר
|
||||
Upscale Type = יתרקוי גוס
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex ןומטמ
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = יכנא ןורכנס
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Fi<riranje teksturi
|
||||
Texture Scaling = &Skaliranje teksturi
|
||||
Use Lossless Video Codec (FFV1) = &Koristite lossless video protokol (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Veličina prozora
|
||||
@ -661,8 +660,6 @@ Upscale Level = Nadograđivanje razine
|
||||
Upscale Type = Vrsta nadograđivanja
|
||||
UpscaleLevel Tip = CPU težak - neke nadogradnje mogu biti usporene da izbjegnu mucanje
|
||||
Use all displays = Koristi sve prikaze
|
||||
Vertex Cache = Predmemorija tjemena
|
||||
VertexCache Tip = Brže, ali može izazvati privremeno treperenje
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Veličina prozora
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xtúra szűrés
|
||||
Texture Scaling = &Textúra nagyítás
|
||||
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
|
||||
Vertex Cache = &Vertex gyorsítótár
|
||||
VSync = VS&ync
|
||||
Vulkan = &Vulkan
|
||||
Window Size = &Ablak méret
|
||||
@ -661,8 +660,6 @@ Upscale Level = Nagyítási szint
|
||||
Upscale Type = Nagyítás típusa
|
||||
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
|
||||
Vertex Cache = Vertex gyorsítótár
|
||||
VertexCache Tip = Gyorsabb, de néha villódzást okoz
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Ablak méret
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Pemfilteran tekstur
|
||||
Texture Scaling = Penskala &tekstur
|
||||
Use Lossless Video Codec (FFV1) = Gunakan kompresi video (FFV1)
|
||||
Use output buffer for video = Gunakan penyangga keluaran untuk video
|
||||
Vertex Cache = Tembolok &vertex
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Ukuran window
|
||||
@ -661,8 +660,6 @@ Upscale Level = Tingkat skala-atas
|
||||
Upscale Type = Jenis skala-atas
|
||||
UpscaleLevel Tip = Berat di CPU - beberapa penskala mungkin tertunda untuk menghindari kegagapan
|
||||
Use all displays = Gunakan semua tampilan
|
||||
Vertex Cache = Tembolok vertex
|
||||
VertexCache Tip = Lebih cepat, namun dapat menyebabkan kedipan sementara
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Ukuran Window
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Filtro Texture
|
||||
Texture Scaling = Scalatura Texture
|
||||
Use Lossless Video Codec (FFV1) = Usa Codec Video senza perdite (FFV1)
|
||||
Use output buffer for video = Usa il buffer per il video
|
||||
Vertex Cache = Cache dei Vertici
|
||||
VSync = Sincronizzazione Verticale
|
||||
Vulkan = Vulkan
|
||||
Window Size = Dimensioni Finestra
|
||||
@ -662,8 +661,6 @@ Upscale Level = Livello Ottimizzazione
|
||||
Upscale Type = Tipo Ottimizzazione
|
||||
UpscaleLevel Tip = Pesante per le CPU - alcune scalature posso essere ritardate per evitare scatti
|
||||
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
|
||||
Vulkan = Vulkan
|
||||
Window Size = Dimensioni Finestra
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = テクスチャフィルタリング(&X)
|
||||
Texture Scaling = テクスチャスケーリング(&T)
|
||||
Use Lossless Video Codec (FFV1) = ロスレスビデオコーデックを使う (FFV1)(&U)
|
||||
Use output buffer for video = ビデオに出力バッファを使う
|
||||
Vertex Cache = 頂点キャッシュ(&V)
|
||||
VSync = VSync(&Y)
|
||||
Vulkan = Vulkan
|
||||
Window Size = ウィンドウサイズ(&W)
|
||||
@ -661,8 +660,6 @@ Upscale Level = アップスケールのレベル
|
||||
Upscale Type = アップスケールのタイプ
|
||||
UpscaleLevel Tip = CPUに重い負荷 - カクつきを避けるためタイプによっては遅延するスケーリングがあるかもしれません
|
||||
Use all displays = 全てのディスプレイを使う
|
||||
Vertex Cache = 頂点キャッシュ
|
||||
VertexCache Tip = 高速ですがフリッカーが生じるかもしれません
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = ウィンドウサイズ
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Tektur Nyaring
|
||||
Texture Scaling = Tektur njongko
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Penyimpenan Vertex
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Ukuran Window
|
||||
@ -661,8 +660,6 @@ Upscale Level = Tingkatan Penaikan-skala
|
||||
Upscale Type = Jenis Penaikan-skala
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Penyimpenan Vertex
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Ukuran window
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = 텍스처 필터링(&X)
|
||||
Texture Scaling = 텍스처 크기 조절(&T)
|
||||
Use Lossless Video Codec (FFV1) = 무손실 비디오 코덱 사용 (FFV1)(&U)
|
||||
Use output buffer for video = 비디오에 출력 버퍼 사용
|
||||
Vertex Cache = 정점 캐시(&V)
|
||||
VSync = 수직 동기화(&Y)
|
||||
Vulkan = Vulkan
|
||||
Window Size = 창 크기(&W)
|
||||
@ -661,8 +660,6 @@ Upscale Level = 업스케일 레벨
|
||||
Upscale Type = 업스케일 유형
|
||||
UpscaleLevel Tip = CPU 사용률 높음 - 버벅거림을 방지하기 위해 일부 확장이 지연될 수 있음
|
||||
Use all displays = 모든 화면 사용
|
||||
Vertex Cache = 정점 캐시
|
||||
VertexCache Tip = 더 빠르지만 일시적인 깜박임이 발생할 수 있습니다.
|
||||
VSync = 수직 동기화
|
||||
Vulkan = Vulkan
|
||||
Window Size = 창 크기
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &ຕອງພື້ນຜິວ
|
||||
Texture Scaling = &ປັບພື້ນຜິວ
|
||||
Use Lossless Video Codec (FFV1) = Use Lossless Video Codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex ແຄດ
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &ຂະໜາດໜ້າຈໍ
|
||||
@ -661,8 +660,6 @@ Upscale Level = ການເພີ່ມລະດັບສເກລພາບ
|
||||
Upscale Type = ຮູບແບບການເພີ່ມສເກລພາບ
|
||||
UpscaleLevel Tip = ຊີພີຢູເຮັດວຽກໜັກຂຶ້ນ - ບາງສເກລພາບອາດເກີດອາການໜ່ວງຈົນເຖິງຂັ້ນບໍ່ສະແດງ
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex Cache
|
||||
VertexCache Tip = ໄວຂຶ້ນ, ແຕ່ອາດເກີດມີອາການພາບກະພິບໃນບາງເທື່ອ
|
||||
VSync = ຄວບຄຸມລະດັບເຟຣມເຣດໃຫ້ຄົງທີ່
|
||||
Vulkan = Vulkan
|
||||
Window Size = ຂະໜາດໜ້າຈໍ
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&kstūrų filtravimas
|
||||
Texture Scaling = &Tekstūrų Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = "VS&ync"
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Lango dydis
|
||||
@ -661,8 +660,6 @@ Upscale Level = "Pakėlimo" lygis
|
||||
Upscale Type = "Pakėlimo" tipas
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
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
|
||||
Vulkan = Vulkan
|
||||
Window Size = Lango dydis
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Penapisan Te&kstur
|
||||
Texture Scaling = &Penskalaan Tekstur
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Kuki Vertek
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Saiz tetingkap
|
||||
@ -661,8 +660,6 @@ Upscale Level = Tahap penskalaan
|
||||
Upscale Type = Jenis penskalaan
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Kuki Vertek
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Saiz tetingkap
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Texturefilter
|
||||
Texture Scaling = Te&xtures schalen
|
||||
Use Lossless Video Codec (FFV1) = Lossless videocodec gebruiken (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Vertex &Cache
|
||||
VSync = Ve&rticale Synchronisatie
|
||||
Vulkan = Vulkan
|
||||
Window Size = Venster&grootte
|
||||
@ -661,8 +660,6 @@ Upscale Level = Upscaleniveau
|
||||
Upscale Type = Upscaletype
|
||||
UpscaleLevel Tip = CPU-belastend - schalen kan vertraagd worden om haperingen te voorkomen
|
||||
Use all displays = Alle beeldschermen gebruiken
|
||||
Vertex Cache = Vertexcache
|
||||
VertexCache Tip = Sneller, maar kan tijdelijk flikkeringen veroorzaken
|
||||
VSync = Verticale synchronisatie
|
||||
Vulkan = Vulkan
|
||||
Window Size = Venstergrootte
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Te&xture Filtering
|
||||
Texture Scaling = &Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window Size
|
||||
@ -661,8 +660,6 @@ Upscale Level = Oppskaler nivå
|
||||
Upscale Type = Oppskaler type
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex buffer
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Filtrowanie tekstur
|
||||
Texture Scaling = Skalowanie tekstur
|
||||
Use Lossless Video Codec (FFV1) = &Używaj stratnego kodeka wideo (FFV1)
|
||||
Use output buffer for video = Używaj buforu wyjścia dla wideo
|
||||
Vertex Cache = Pamięć podręczna wierzchołków
|
||||
VSync = Limit klatek
|
||||
Vulkan = Vulkan
|
||||
Window Size = Rozmiar okna
|
||||
@ -666,8 +665,6 @@ Upscale Level = Poziom skalowania
|
||||
Upscale Type = Rodzaj skalowania
|
||||
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
|
||||
Vertex Cache = Pamięć podręczna wierzchołków
|
||||
VertexCache Tip = Szybsze, jednak może powodować krótkotrwałe migotanie
|
||||
VSync = Synchronizacja pionowa
|
||||
Vulkan = Vulkan
|
||||
Window Size = Rozmiar okna
|
||||
|
@ -292,7 +292,6 @@ Texture Filtering = Fi<ragem das texturas
|
||||
Texture Scaling = &Dimensionamento das texturas
|
||||
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
|
||||
Vertex Cache = &Cache do vértice
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Tamanho da janela
|
||||
@ -686,8 +685,6 @@ Upscale Level = Nível da ampliação
|
||||
Upscale Type = Tipo de ampliação
|
||||
UpscaleLevel Tip = Pesado pra CPU - alguns dimensionamentos podem ser atrasados pra evitar travamentos
|
||||
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
|
||||
Vulkan = Vulkan
|
||||
Window Size = Tamanho da janela
|
||||
|
@ -292,7 +292,6 @@ Texture Filtering = Fi<ragem das texturas
|
||||
Texture Scaling = &Dimensionamento das texturas
|
||||
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
|
||||
Vertex Cache = &Cache do vértice
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Tamanho da Janela
|
||||
@ -685,8 +684,6 @@ Upscale Level = Nível de ampliação
|
||||
Upscale Type = Tipo de ampliação
|
||||
UpscaleLevel Tip = Pesado para a CPU - alguns dimensionamentos poderão atrasados para evitar travamentos
|
||||
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
|
||||
Vulkan = Vulkan
|
||||
Window Size = Tamanho da janela
|
||||
|
@ -269,7 +269,6 @@ Texture Filtering = Te&xture Filtering
|
||||
Texture Scaling = &Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = &Vertex Cache
|
||||
VSync = VS&ync
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Window Size
|
||||
@ -662,8 +661,6 @@ Upscale Level = Nivel Suprascalare
|
||||
Upscale Type = Tip Suprascalare
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Stocare vertecși
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Mărime ecran
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Фильтрация текстур
|
||||
Texture Scaling = &Масштабирование текстур
|
||||
Use Lossless Video Codec (FFV1) = Использовать видеокодек без потерь (FFV1)
|
||||
Use output buffer for video = Использовать выходной буфер для видео
|
||||
Vertex Cache = &Вершинный кэш
|
||||
VSync = Вертикальная син&хронизация
|
||||
Vulkan = Vulkan
|
||||
Window Size = Размер &окна
|
||||
@ -661,8 +660,6 @@ Upscale Level = Уровень масштабирования
|
||||
Upscale Type = Тип масштабирования
|
||||
UpscaleLevel Tip = Нагружает ЦП. Масштабирование может происходить с задержкой для предотвращения заиканий
|
||||
Use all displays = Задействовать все экраны
|
||||
Vertex Cache = Вершинный кэш
|
||||
VertexCache Tip = Быстрее, но может вызывать мерцание
|
||||
VSync = Вертикальная синхронизация
|
||||
Vulkan = Vulkan
|
||||
Window Size = Размер окна
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Texturfiltrering
|
||||
Texture Scaling = Texturskalning
|
||||
Use Lossless Video Codec (FFV1) = &Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Vertexcache
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Fönsterstorlek
|
||||
@ -662,8 +661,6 @@ Upscale Level = Uppskalningsnivå
|
||||
Upscale Type = Uppskalningstyp
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Använd alla displayer
|
||||
Vertex Cache = Vertexcache
|
||||
VertexCache Tip = Faster, but may cause temporary flicker
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Fönsterstorlek
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Texture Filtering
|
||||
Texture Scaling = Texture Scaling
|
||||
Use Lossless Video Codec (FFV1) = Use lossless video codec (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Vertex Cache
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window Size
|
||||
@ -661,8 +660,6 @@ Upscale Level = Antas ng upscale
|
||||
Upscale Type = Uri ng upscale
|
||||
UpscaleLevel Tip = CPU heavy - some scaling may be delayed to avoid stutter
|
||||
Use all displays = Use all displays
|
||||
Vertex Cache = Vertex Cache
|
||||
VertexCache Tip = Mabilis, pero mag kaka flicker ng temporary
|
||||
VSync = VSync
|
||||
Vulkan = Vulkan
|
||||
Window Size = Window size
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = การกรองพื้นผิว
|
||||
Texture Scaling = การปรับพื้นผิว
|
||||
Use Lossless Video Codec (FFV1) = ใช้โค้ด FFV1 บันทึกวีดีโอ เพื่อรักษาความคมชัด
|
||||
Use output buffer for video = ใช้การส่งออกบัฟเฟอร์ในการบันทึกวีดีโอ
|
||||
Vertex Cache = เวอร์เท็กซ์ แคช
|
||||
VSync = ควบคุมช่วงของเฟรมเรทให้คงที่
|
||||
Vulkan = วัลแคน
|
||||
Window Size = ขนาดของหน้าจอ
|
||||
@ -661,8 +660,6 @@ Upscale Level = เพิ่มระดับสเกลภาพ
|
||||
Upscale Type = รูปแบบการเพิ่มสเกลภาพ
|
||||
UpscaleLevel Tip = ซีพียูทำงานหนักขึ้น บางสเกลภาพอาจเกิดอาการหน่วงจนถึงขั้นไม่แสดงผล
|
||||
Use all displays = ใช้กับหน้าจอการแสดงผลทั้งหมด
|
||||
Vertex Cache = เวอร์เท็ค แคช
|
||||
VertexCache Tip = เร็วขึ้น แต่อาจทำให้เกิดอาการภาพกระพริบชั่วครั้งชั่วคราว
|
||||
VSync = ควบคุมช่วงของเฟรมเรทให้คงที่
|
||||
Vulkan = วัลแคน
|
||||
Window Size = ขนาดของหน้าจอ
|
||||
|
@ -270,7 +270,6 @@ Texture Filtering = Doku Filtreleme
|
||||
Texture Scaling = &Doku Ölçekleme
|
||||
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
|
||||
Vertex Cache = &Vertex Önbellek
|
||||
VSync = Dikey Eşleme (VSync)
|
||||
Vulkan = Vulkan
|
||||
Window Size = &Pencere Boyutu
|
||||
@ -663,8 +662,6 @@ Upscale Level = Ölçeklendirme seviyesi
|
||||
Upscale Type = Ölçeklendirme türü
|
||||
UpscaleLevel Tip = CPU ağır - takılmayı önlemek için bazı yeniden ölçeklendirmeler gecikebilir
|
||||
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)
|
||||
Vulkan = Vulkan
|
||||
Window Size = Pencere boyutu
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = &Фільтрація текстур
|
||||
Texture Scaling = &Масштабування текстур
|
||||
Use Lossless Video Codec (FFV1) = &Використовувати відеокодек без втрат (FFV1)
|
||||
Use output buffer for video = Використовувати вихідний буфер для відео
|
||||
Vertex Cache = &Вершинний кеш
|
||||
VSync = Вертикальна син&хронізація
|
||||
Vulkan = Vulkan
|
||||
Window Size = Розмір &вікна
|
||||
@ -661,8 +660,6 @@ Upscale Level = Рівень масштабування
|
||||
Upscale Type = Тип масштабування
|
||||
UpscaleLevel Tip = Процесор завантажений - деяке масштабування може затягнутися, щоб уникнути заїкання
|
||||
Use all displays = Використовувати всі екрани
|
||||
Vertex Cache = Вершинний кеш
|
||||
VertexCache Tip = Швидше, але може спричинити тимчасове мерехтіння
|
||||
VSync = Вертикальна синхронізація
|
||||
Vulkan = Vulkan
|
||||
Window Size = Розмір вікна
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = Bộ lọc texture
|
||||
Texture Scaling = Scaling texture (thu nhỏ)
|
||||
Use Lossless Video Codec (FFV1) = Sử dụng codec video lossless (FFV1)
|
||||
Use output buffer for video = Use output buffer for video
|
||||
Vertex Cache = Bộ đệm điểm
|
||||
VSync = Đồng bộ
|
||||
Vulkan = Vulkan
|
||||
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
|
||||
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ị
|
||||
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ộ
|
||||
Vulkan = Vulkan
|
||||
Window Size = Kích cỡ cửa sổ
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = 纹理过滤方法(&X)
|
||||
Texture Scaling = 纹理缩放方法(&T)
|
||||
Use Lossless Video Codec (FFV1) = 使用无损视频编码器(FFV1)(&U)
|
||||
Use output buffer for video = 录制包括输出缓冲
|
||||
Vertex Cache = 顶点缓存(&V)
|
||||
VSync = 垂直同步(&Y)
|
||||
Vulkan = Vulkan
|
||||
Window Size = 窗口大小(&W)
|
||||
@ -661,8 +660,6 @@ Upscale Level = 纹理缩放级别
|
||||
Upscale Type = 纹理缩放 (CPU)
|
||||
UpscaleLevel Tip = CPU负担大。某些缩放会延后,以减少卡顿
|
||||
Use all displays = 使用全部显示器
|
||||
Vertex Cache = 顶点缓存
|
||||
VertexCache Tip = 略微提速,可能造成暂时模型闪烁或丢失
|
||||
VSync = 垂直同步
|
||||
Vulkan = Vulkan
|
||||
Window Size = 窗口大小
|
||||
|
@ -268,7 +268,6 @@ Texture Filtering = 紋理過濾(&X)
|
||||
Texture Scaling = 紋理縮放(&T)
|
||||
Use Lossless Video Codec (FFV1) = 使用不失真視訊轉碼器 (FFV1)(&U)
|
||||
Use output buffer for video = 為視訊使用輸出緩衝區
|
||||
Vertex Cache = 頂點快取(&V)
|
||||
VSync = 垂直同步(&Y)
|
||||
Vulkan = Vulkan
|
||||
Window Size = 視窗大小(&W)
|
||||
@ -661,8 +660,6 @@ Upscale Level = 放大層級
|
||||
Upscale Type = 放大類型
|
||||
UpscaleLevel Tip = CPU 負載過重 - 部分縮放可能會延遲以避免間斷
|
||||
Use all displays = 使用所有顯示器
|
||||
Vertex Cache = 頂點快取
|
||||
VertexCache Tip = 更快,但可能會造成暫時閃爍
|
||||
VSync = 垂直同步
|
||||
Vulkan = Vulkan
|
||||
Window Size = 視窗大小
|
||||
|
@ -472,7 +472,6 @@ int main(int argc, const char* argv[])
|
||||
g_Config.bHardwareTransform = true;
|
||||
g_Config.iAnisotropyLevel = 0; // When testing mipmapping we really don't want this.
|
||||
g_Config.iMultiSampleLevel = 0;
|
||||
g_Config.bVertexCache = false;
|
||||
g_Config.iLanguage = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
|
||||
g_Config.iTimeFormat = PSP_SYSTEMPARAM_TIME_FORMAT_24HR;
|
||||
g_Config.bEncryptSave = true;
|
||||
|
@ -706,15 +706,6 @@ static void check_variables(CoreParameter &coreParam)
|
||||
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";
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user