mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Pipeline checker: Add support for checking for identical pipelines with different vertex formats
This turned out not to be very fruitful.
This commit is contained in:
@@ -999,7 +999,7 @@ bool DrawEngineCommon::DescribeCodePtr(const u8 *ptr, std::string &name) const {
|
|||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
char temp[256];
|
char temp[256];
|
||||||
found->ToString(temp, false);
|
found->ToString(temp, sizeof(temp), false);
|
||||||
name = temp;
|
name = temp;
|
||||||
snprintf(temp, sizeof(temp), "_%08X", foundKey);
|
snprintf(temp, sizeof(temp), "_%08X", foundKey);
|
||||||
name += temp;
|
name += temp;
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
// Reset the code ptr and return zero to indicate that we failed.
|
// Reset the code ptr and return zero to indicate that we failed.
|
||||||
ResetCodePtr(GetOffset(start));
|
ResetCodePtr(GetOffset(start));
|
||||||
char temp[1024]{};
|
char temp[1024]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
/*
|
/*
|
||||||
DisassembleArm(start, GetCodePtr() - start);
|
DisassembleArm(start, GetCodePtr() - start);
|
||||||
char temp[1024] = {0};
|
char temp[1024] = {0};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
INFO_LOG(Log::G3D, "%s", temp);
|
INFO_LOG(Log::G3D, "%s", temp);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
// Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed.
|
// Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed.
|
||||||
ResetCodePtr(GetOffset(start));
|
ResetCodePtr(GetOffset(start));
|
||||||
char temp[1024]{};
|
char temp[1024]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -291,7 +291,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
|
|
||||||
if (log) {
|
if (log) {
|
||||||
char temp[1024] = { 0 };
|
char temp[1024] = { 0 };
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
INFO_LOG(Log::JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start));
|
INFO_LOG(Log::JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start));
|
||||||
std::vector<std::string> lines = DisassembleArm64(start, (int)(GetCodePtr() - start));
|
std::vector<std::string> lines = DisassembleArm64(start, (int)(GetCodePtr() - start));
|
||||||
for (auto line : lines) {
|
for (auto line : lines) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Data/Convert/ColorConv.h"
|
#include "Common/Data/Convert/ColorConv.h"
|
||||||
|
#include "Common/Data/Text/StringWriter.h"
|
||||||
#include "Common/Math/CrossSIMD.h"
|
#include "Common/Math/CrossSIMD.h"
|
||||||
#include "Common/Log.h"
|
#include "Common/Log.h"
|
||||||
#include "Common/LogReporting.h"
|
#include "Common/LogReporting.h"
|
||||||
@@ -84,6 +85,41 @@ static int DecFmtSize(u8 fmt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *DecFmtComponentToString(u8 fmt) {
|
||||||
|
switch (fmt) {
|
||||||
|
case DEC_NONE: return "NONE";
|
||||||
|
case DEC_FLOAT_1: return "FLOAT_1";
|
||||||
|
case DEC_FLOAT_2: return "FLOAT_2";
|
||||||
|
case DEC_FLOAT_3: return "FLOAT_3";
|
||||||
|
case DEC_FLOAT_4: return "FLOAT_4";
|
||||||
|
case DEC_S8_3: return "S8_3";
|
||||||
|
case DEC_S16_3: return "S16_3";
|
||||||
|
case DEC_U8_1: return "U8_1";
|
||||||
|
case DEC_U8_2: return "U8_2";
|
||||||
|
case DEC_U8_3: return "U8_3";
|
||||||
|
case DEC_U8_4: return "U8_4";
|
||||||
|
case DEC_U16_1: return "U16_1";
|
||||||
|
case DEC_U16_2: return "U16_2";
|
||||||
|
case DEC_U16_3: return "U16_3";
|
||||||
|
case DEC_U16_4: return "U16_4";
|
||||||
|
default: return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DecVtxFormat::ToString() const {
|
||||||
|
char buf[256];
|
||||||
|
StringWriter w(buf, sizeof(buf));
|
||||||
|
if (w0fmt) {
|
||||||
|
w.F("W0: %s ", DecFmtComponentToString(w0fmt));
|
||||||
|
}
|
||||||
|
w.F("W1: %s ", DecFmtComponentToString(w1fmt));
|
||||||
|
w.F("UV: %s ", DecFmtComponentToString(uvfmt));
|
||||||
|
w.F("C0: %s ", DecFmtComponentToString(c0fmt));
|
||||||
|
w.F("C1: %s ", DecFmtComponentToString(c1fmt));
|
||||||
|
w.F("N: %s", DecFmtComponentToString(nrmfmt));
|
||||||
|
return w.as_string();
|
||||||
|
}
|
||||||
|
|
||||||
void DecVtxFormat::ComputeID() {
|
void DecVtxFormat::ComputeID() {
|
||||||
id = w0fmt | (w1fmt << 4) | (uvfmt << 8) | (c0fmt << 12) | (c1fmt << 16) | (nrmfmt << 20);
|
id = w0fmt | (w1fmt << 4) | (uvfmt << 8) | (c0fmt << 12) | (c1fmt << 16) | (nrmfmt << 20);
|
||||||
}
|
}
|
||||||
@@ -1413,7 +1449,7 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
|
|||||||
|
|
||||||
if (reportNoPos) {
|
if (reportNoPos) {
|
||||||
char temp[256]{};
|
char temp[256]{};
|
||||||
ToString(temp, true);
|
ToString(temp, sizeof(temp), true);
|
||||||
ERROR_LOG(Log::G3D, "Vertices without position found (and ignored): (%08x) %s", fmt_, temp);
|
ERROR_LOG(Log::G3D, "Vertices without position found (and ignored): (%08x) %s", fmt_, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1550,8 +1586,8 @@ void VertexDecoder::CompareToJit(const u8 *startPtr, u8 *decodedptr, int count,
|
|||||||
controlReader.Goto(i);
|
controlReader.Goto(i);
|
||||||
jittedReader.Goto(i);
|
jittedReader.Goto(i);
|
||||||
if (!DecodedVertsAreSimilar(controlReader, jittedReader)) {
|
if (!DecodedVertsAreSimilar(controlReader, jittedReader)) {
|
||||||
char name[512]{};
|
char name[256]{};
|
||||||
ToString(name, true);
|
ToString(name, sizeof(name), true);
|
||||||
ERROR_LOG(Log::G3D, "Encountered vertexjit mismatch at %d/%d for %s", i, count, name);
|
ERROR_LOG(Log::G3D, "Encountered vertexjit mismatch at %d/%d for %s", i, count, name);
|
||||||
if (morphcount > 1) {
|
if (morphcount > 1) {
|
||||||
printf("Morph:\n");
|
printf("Morph:\n");
|
||||||
@@ -1605,26 +1641,30 @@ static const char * const idxnames[4] = { "-", "u8", "u16", "?" };
|
|||||||
static const char * const weightnames[4] = { "-", "u8", "u16", "f" };
|
static const char * const weightnames[4] = { "-", "u8", "u16", "f" };
|
||||||
static const char * const colnames[8] = { "", "?", "?", "?", "565", "5551", "4444", "8888" };
|
static const char * const colnames[8] = { "", "?", "?", "?", "565", "5551", "4444", "8888" };
|
||||||
|
|
||||||
int VertexDecoder::ToString(char *output, bool spaces) const {
|
// There's a direct ToString function for vertex types in the GPU debugger, GeDescribeVertexType.
|
||||||
char *start = output;
|
|
||||||
output += sprintf(output, "[%08x] ", fmt_);
|
|
||||||
output += sprintf(output, "P: %s ", posnames[pos]);
|
|
||||||
if (nrm)
|
|
||||||
output += sprintf(output, "N: %s ", nrmnames[nrm]);
|
|
||||||
if (col)
|
|
||||||
output += sprintf(output, "C: %s ", colnames[col]);
|
|
||||||
if (tc)
|
|
||||||
output += sprintf(output, "T: %s ", tcnames[tc]);
|
|
||||||
if (weighttype)
|
|
||||||
output += sprintf(output, "W: %s (%ix) ", weightnames[weighttype], nweights);
|
|
||||||
if (idx)
|
|
||||||
output += sprintf(output, "I: %s ", idxnames[idx]);
|
|
||||||
if (morphcount > 1)
|
|
||||||
output += sprintf(output, "Morph: %i ", morphcount);
|
|
||||||
if (throughmode)
|
|
||||||
output += sprintf(output, " (through)");
|
|
||||||
|
|
||||||
output += sprintf(output, " (%ib)", VertexSize());
|
int VertexDecoder::ToString(char *buf, int bufSize, bool spaces) const {
|
||||||
|
StringWriter w(buf, bufSize);
|
||||||
|
|
||||||
|
char *start = buf;
|
||||||
|
w.F("[%08x] ", fmt_);
|
||||||
|
w.F("P: %s ", posnames[pos]);
|
||||||
|
if (nrm)
|
||||||
|
w.F("N: %s ", nrmnames[nrm]);
|
||||||
|
if (col)
|
||||||
|
w.F("C: %s ", colnames[col]);
|
||||||
|
if (tc)
|
||||||
|
w.F("T: %s ", tcnames[tc]);
|
||||||
|
if (weighttype)
|
||||||
|
w.F("W: %s (%ix) ", weightnames[weighttype], nweights);
|
||||||
|
if (idx)
|
||||||
|
w.F("I: %s ", idxnames[idx]);
|
||||||
|
if (morphcount > 1)
|
||||||
|
w.F("Morph: %i ", morphcount);
|
||||||
|
if (throughmode)
|
||||||
|
w.F(" (through)");
|
||||||
|
|
||||||
|
w.F(" (%ib)", VertexSize());
|
||||||
|
|
||||||
if (!spaces) {
|
if (!spaces) {
|
||||||
size_t len = strlen(start);
|
size_t len = strlen(start);
|
||||||
@@ -1635,17 +1675,16 @@ int VertexDecoder::ToString(char *output, bool spaces) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
output += sprintf(output, " (%llu)", (long long)decodedCount);
|
w.F(" (%llu)", (long long)decodedCount);
|
||||||
#endif
|
#endif
|
||||||
|
return (int)w.size();
|
||||||
return output - start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VertexDecoder::GetString(DebugShaderStringType stringType) const {
|
std::string VertexDecoder::GetString(DebugShaderStringType stringType) const {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
switch (stringType) {
|
switch (stringType) {
|
||||||
case SHADER_STRING_SHORT_DESC:
|
case SHADER_STRING_SHORT_DESC:
|
||||||
ToString(buffer, true);
|
ToString(buffer, sizeof(buffer), true);
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
case SHADER_STRING_SOURCE_CODE:
|
case SHADER_STRING_SOURCE_CODE:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
// Keep this in 4 bits.
|
// Keep this in 4 bits.
|
||||||
enum {
|
enum {
|
||||||
DEC_NONE,
|
DEC_NONE = 0,
|
||||||
DEC_FLOAT_1,
|
DEC_FLOAT_1,
|
||||||
DEC_FLOAT_2,
|
DEC_FLOAT_2,
|
||||||
DEC_FLOAT_3,
|
DEC_FLOAT_3,
|
||||||
@@ -63,6 +63,8 @@ enum {
|
|||||||
DEC_U16_4,
|
DEC_U16_4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *DecFmtComponentToString(u8 fmt);
|
||||||
|
|
||||||
// DecVtxFormat - vertex formats for PC
|
// DecVtxFormat - vertex formats for PC
|
||||||
// Kind of like a D3D VertexDeclaration.
|
// Kind of like a D3D VertexDeclaration.
|
||||||
// No morph support, that is taken care of by the VertexDecoder.
|
// No morph support, that is taken care of by the VertexDecoder.
|
||||||
@@ -81,6 +83,8 @@ struct DecVtxFormat {
|
|||||||
void InitializeFromID(uint32_t id);
|
void InitializeFromID(uint32_t id);
|
||||||
|
|
||||||
static u8 PosFmt() { return DEC_FLOAT_3; }
|
static u8 PosFmt() { return DEC_FLOAT_3; }
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBound, u16 *indexUpperBound);
|
void GetIndexBounds(const void *inds, int count, u32 vertType, u16 *indexLowerBound, u16 *indexUpperBound);
|
||||||
@@ -153,6 +157,8 @@ inline GETexMapMode VertTypeIDUVGenMode(uint32_t vertType) {
|
|||||||
return (GETexMapMode)((vertType >> 24) & 3);
|
return (GETexMapMode)((vertType >> 24) & 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string DecFmtIdToString(u32 id);
|
||||||
|
|
||||||
class VertexDecoder {
|
class VertexDecoder {
|
||||||
public:
|
public:
|
||||||
// A jit cache is not mandatory.
|
// A jit cache is not mandatory.
|
||||||
@@ -258,7 +264,7 @@ public:
|
|||||||
// output must be big for safety.
|
// output must be big for safety.
|
||||||
// Returns number of chars written.
|
// Returns number of chars written.
|
||||||
// Ugly for speed.
|
// Ugly for speed.
|
||||||
int ToString(char *output, bool spaces) const;
|
int ToString(char *buf, int bufSize, bool spaces) const;
|
||||||
|
|
||||||
bool IsInSpace(const uint8_t *ptr) const {
|
bool IsInSpace(const uint8_t *ptr) const {
|
||||||
return ptr >= (const uint8_t *)jitted_ && ptr < ((const uint8_t *)jitted_ + jittedSize_);
|
return ptr >= (const uint8_t *)jitted_ && ptr < ((const uint8_t *)jitted_ + jittedSize_);
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
// Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed.
|
// Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed.
|
||||||
ResetCodePtr(GetOffset(start));
|
ResetCodePtr(GetOffset(start));
|
||||||
char temp[1024]{};
|
char temp[1024]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -338,7 +338,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
|
|
||||||
if (log) {
|
if (log) {
|
||||||
char temp[1024]{};
|
char temp[1024]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
INFO_LOG(Log::JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start));
|
INFO_LOG(Log::JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start));
|
||||||
std::vector<std::string> lines = DisassembleLA64(start, (int)(GetCodePtr() - start));
|
std::vector<std::string> lines = DisassembleLA64(start, (int)(GetCodePtr() - start));
|
||||||
for (auto line : lines) {
|
for (auto line : lines) {
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
// Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed.
|
// Reset the code ptr (effectively undoing what we generated) and return zero to indicate that we failed.
|
||||||
ResetCodePtr(GetOffset(start));
|
ResetCodePtr(GetOffset(start));
|
||||||
char temp[1024]{};
|
char temp[1024]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -349,7 +349,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
|
|
||||||
if (log) {
|
if (log) {
|
||||||
char temp[1024]{};
|
char temp[1024]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
INFO_LOG(Log::JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start));
|
INFO_LOG(Log::JIT, "=== %s (%d bytes) ===", temp, (int)(GetCodePtr() - start));
|
||||||
std::vector<std::string> lines = DisassembleRV64(start, (int)(GetCodePtr() - start));
|
std::vector<std::string> lines = DisassembleRV64(start, (int)(GetCodePtr() - start));
|
||||||
for (auto line : lines) {
|
for (auto line : lines) {
|
||||||
|
|||||||
@@ -281,8 +281,8 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int
|
|||||||
EndWrite();
|
EndWrite();
|
||||||
// Reset the code ptr and return zero to indicate that we failed.
|
// Reset the code ptr and return zero to indicate that we failed.
|
||||||
ResetCodePtr(GetOffset(start));
|
ResetCodePtr(GetOffset(start));
|
||||||
char temp[1024]{};
|
char temp[256]{};
|
||||||
dec.ToString(temp, true);
|
dec.ToString(temp, sizeof(temp), true);
|
||||||
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
WARN_LOG(Log::G3D, "Could not compile vertex decoder, failed at step %s: %s", GetStepFunctionName(dec.steps_[i]), temp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ struct VulkanPipelineKey {
|
|||||||
VulkanPipelineRasterStateKey raster; // prim is included here
|
VulkanPipelineRasterStateKey raster; // prim is included here
|
||||||
VShaderID vid;
|
VShaderID vid;
|
||||||
FShaderID fid;
|
FShaderID fid;
|
||||||
uint32_t vtxFmtId;
|
uint32_t vtxFmtId; // Note: This is the decoded format ID, not the source format!
|
||||||
bool useHWTransform;
|
bool useHWTransform;
|
||||||
|
|
||||||
void ToString(std::string *str) const {
|
void ToString(std::string *str) const {
|
||||||
|
|||||||
@@ -510,6 +510,10 @@ const bool IsSameExceptForShaders(const VulkanPipelineKey &a, const VulkanPipeli
|
|||||||
return a.useHWTransform == b.useHWTransform && a.raster == b.raster && a.vtxFmtId == b.vtxFmtId;
|
return a.useHWTransform == b.useHWTransform && a.raster == b.raster && a.vtxFmtId == b.vtxFmtId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool IsSameExceptForVertexFormat(const VulkanPipelineKey &a, const VulkanPipelineKey &b) {
|
||||||
|
return a.useHWTransform == b.useHWTransform && a.raster == b.raster && a.vid == b.vid && a.fid == b.fid;
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderListScreen::AddPipelineAnalysis(UI::LinearLayout *tabContent) {
|
void ShaderListScreen::AddPipelineAnalysis(UI::LinearLayout *tabContent) {
|
||||||
#if !PPSSPP_PLATFORM(UWP)
|
#if !PPSSPP_PLATFORM(UWP)
|
||||||
GPU_Vulkan *vgpu = dynamic_cast<GPU_Vulkan *>(gpu);
|
GPU_Vulkan *vgpu = dynamic_cast<GPU_Vulkan *>(gpu);
|
||||||
@@ -538,6 +542,15 @@ void ShaderListScreen::AddPipelineAnalysis(UI::LinearLayout *tabContent) {
|
|||||||
toBeMerged += "FShader: " + keyA.fid.Description() + " vs " + keyB.fid.Description() + "\n";
|
toBeMerged += "FShader: " + keyA.fid.Description() + " vs " + keyB.fid.Description() + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (IsSameExceptForVertexFormat(keyA, keyB)) {
|
||||||
|
if (keyA.vtxFmtId != 0 && keyB.vtxFmtId != 0 && keyA.vtxFmtId != keyB.vtxFmtId) {
|
||||||
|
DecVtxFormat fmtA;
|
||||||
|
DecVtxFormat fmtB;
|
||||||
|
fmtA.InitializeFromID(keyA.vtxFmtId);
|
||||||
|
fmtB.InitializeFromID(keyB.vtxFmtId);
|
||||||
|
toBeMerged += "VertexFmt: " + fmtA.ToString() + " vs " + fmtB.ToString() + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!toBeMerged.empty()) {
|
if (!toBeMerged.empty()) {
|
||||||
tabContent->Add(new UI::TextView(keys[i].GetDescription(SHADER_STRING_SHORT_DESC), FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT, true));
|
tabContent->Add(new UI::TextView(keys[i].GetDescription(SHADER_STRING_SHORT_DESC), FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT, true));
|
||||||
|
|||||||
Reference in New Issue
Block a user