mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Merge pull request #21889 from hrydgard/assorted-cleanups
Assorted cleanups, reorganize Shader Id bits
This commit is contained in:
@@ -24,6 +24,23 @@ inline u32 ReverseBits32(u32 v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
inline u64 ReverseBits64(u64 v) {
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
|
||||
// swap odd and even bits
|
||||
v = ((v >> 1) & 0x5555555555555555ULL) | ((v & 0x5555555555555555ULL) << 1);
|
||||
// swap consecutive pairs
|
||||
v = ((v >> 2) & 0x3333333333333333ULL) | ((v & 0x3333333333333333ULL) << 2);
|
||||
// swap nibbles ...
|
||||
v = ((v >> 4) & 0x0F0F0F0F0F0F0F0FULL) | ((v & 0x0F0F0F0F0F0F0F0FULL) << 4);
|
||||
// swap bytes
|
||||
v = ((v >> 8) & 0x00FF00FF00FF00FFULL) | ((v & 0x00FF00FF00FF00FFULL) << 8);
|
||||
// swap 2-byte long pairs
|
||||
v = ((v >> 16) & 0x0000FFFF0000FFFFULL) | ((v & 0x0000FFFF0000FFFFULL) << 16);
|
||||
// swap 4-byte long pairs
|
||||
v = (v >> 32) | (v << 32);
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <intrin.h>
|
||||
template <typename T>
|
||||
|
||||
@@ -21,6 +21,11 @@ public:
|
||||
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
|
||||
return (m_z << 16) + m_w;
|
||||
}
|
||||
uint64_t R64() {
|
||||
const uint32_t bottom = R32();
|
||||
const uint32_t top = R32();
|
||||
return ((uint64_t)top << 32) | bottom;
|
||||
}
|
||||
float F() {
|
||||
return (float)R32() / (float)(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ public:
|
||||
std::string_view as_view() const {
|
||||
return std::string_view(start_, p_ - start_);
|
||||
}
|
||||
std::string as_string() const {
|
||||
return std::string(start_, p_ - start_);
|
||||
}
|
||||
const char *begin() const {
|
||||
return start_;
|
||||
}
|
||||
|
||||
+126
-92
@@ -1,9 +1,10 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/GPU/thin3d.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/Data/Text/StringWriter.h"
|
||||
#include "Common/BitSet.h"
|
||||
#include "Core/Config.h"
|
||||
|
||||
#include "GPU/ge_constants.h"
|
||||
@@ -14,54 +15,62 @@
|
||||
#include "GPU/Common/VertexDecoderCommon.h"
|
||||
#include "GPU/Common/DrawEngineCommon.h" // Just for ClipInfoFlags
|
||||
|
||||
std::string ShaderID::ToDebugString() const {
|
||||
return StringFromFormat("%08x:%08x", d >> 32, d & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
std::string VertexShaderDesc(const VShaderID &id) {
|
||||
std::stringstream desc;
|
||||
desc << StringFromFormat("%08x:%08x ", id.d[1], id.d[0]);
|
||||
if (id.Bit(VS_BIT_IS_THROUGH)) desc << "THR ";
|
||||
if (id.Bit(VS_BIT_USE_HW_TRANSFORM)) desc << "HWX ";
|
||||
if (id.Bit(VS_BIT_HAS_COLOR)) desc << "C ";
|
||||
if (id.Bit(VS_BIT_HAS_TEXCOORD)) desc << "T ";
|
||||
if (id.Bit(VS_BIT_HAS_NORMAL)) desc << "N ";
|
||||
if (id.Bit(VS_BIT_LMODE)) desc << "LM ";
|
||||
if (id.Bit(VS_BIT_NORM_REVERSE)) desc << "RevN ";
|
||||
char buffer[512];
|
||||
StringWriter desc(buffer, sizeof(buffer));
|
||||
|
||||
desc.W(id.ToDebugString()).C(" ");
|
||||
if (id.Bit(VS_BIT_IS_THROUGH)) desc.C("THR ");
|
||||
if (id.Bit(VS_BIT_USE_HW_TRANSFORM)) desc.C("HWX "); else desc.C("SWX ");
|
||||
if (id.Bit(VS_BIT_HAS_NORMAL)) desc.C("N ");
|
||||
if (id.Bit(VS_BIT_HAS_TEXCOORD)) desc.C("T ");
|
||||
if (id.Bit(VS_BIT_HAS_COLOR)) desc.C("C ");
|
||||
if (id.Bit(VS_BIT_LMODE)) desc.C("LM ");
|
||||
if (id.Bit(VS_BIT_NORM_REVERSE)) desc.C("RevN ");
|
||||
if (id.Bit(VS_BIT_FLATSHADE)) desc.C("Flat ");
|
||||
if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc.C("MatUp:").F("%d", id.Bits(VS_BIT_MATERIAL_UPDATE, 3)).C(" ");
|
||||
|
||||
int uvgMode = id.Bits(VS_BIT_UVGEN_MODE, 2);
|
||||
static constexpr std::string_view uvgModes[4] = {"UV ", "UVMtx ", "UVEnv ", "UVUnk "};
|
||||
if (uvgMode) desc.W(uvgModes[uvgMode]);
|
||||
if (uvgMode == GE_TEXMAP_TEXTURE_MATRIX) {
|
||||
int uvprojMode = id.Bits(VS_BIT_UVPROJ_MODE, 2);
|
||||
const char *uvprojModes[4] = { "TexProjPos ", "TexProjUV ", "TexProjNNrm ", "TexProjNrm " };
|
||||
desc << uvprojModes[uvprojMode];
|
||||
static constexpr std::string_view uvprojModes[4] = { "TexProjPos ", "TexProjUV ", "TexProjNNrm ", "TexProjNrm " };
|
||||
desc.W(uvprojModes[uvprojMode]);
|
||||
}
|
||||
static constexpr std::array<const char*, 4> uvgModes = { "UV ", "UVMtx ", "UVEnv ", "UVUnk " };
|
||||
|
||||
if (id.Bit(VS_BIT_ENABLE_BONES)) desc.F("Bones:%d ", id.Bits(VS_BIT_BONES, 3) + 1);
|
||||
if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc.F("WScale:%d ", id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2));
|
||||
|
||||
int ls0 = id.Bits(VS_BIT_LS0, 2);
|
||||
int ls1 = id.Bits(VS_BIT_LS1, 2);
|
||||
|
||||
if (uvgMode) desc << uvgModes[uvgMode];
|
||||
if (id.Bit(VS_BIT_ENABLE_BONES)) desc << "Bones:" << (id.Bits(VS_BIT_BONES, 3) + 1) << " ";
|
||||
if (id.Bit(VS_BIT_FS_MINMAX_DISCARD)) desc.C("FSMinMax ");
|
||||
if (id.Bit(VS_BIT_FS_DEPTH_CLAMP)) desc.C("FSDepthClamp ");
|
||||
|
||||
// Lights
|
||||
if (id.Bit(VS_BIT_LIGHTING_ENABLE)) {
|
||||
desc << "Light: ";
|
||||
desc.C("Light: ");
|
||||
}
|
||||
if (id.Bit(VS_BIT_LIGHT_UBERSHADER)) {
|
||||
desc << "LightUberShader ";
|
||||
desc.C("LightUberShader ");
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bool enabled = id.Bit(VS_BIT_LIGHT0_ENABLE + i) && id.Bit(VS_BIT_LIGHTING_ENABLE);
|
||||
if (enabled || (uvgMode == GE_TEXMAP_ENVIRONMENT_MAP && (ls0 == i || ls1 == i))) {
|
||||
desc << i << ": ";
|
||||
desc << "c:" << id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2) << " t:" << id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2) << " ";
|
||||
desc.F("%d: ", i);
|
||||
desc.F("c:%d t:%d ", id.Bits(VS_BIT_LIGHT0_COMP + 4 * i, 2), id.Bits(VS_BIT_LIGHT0_TYPE + 4 * i, 2));
|
||||
}
|
||||
}
|
||||
if (id.Bits(VS_BIT_MATERIAL_UPDATE, 3)) desc << "MatUp:" << id.Bits(VS_BIT_MATERIAL_UPDATE, 3) << " ";
|
||||
if (id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2)) desc << "WScale " << id.Bits(VS_BIT_WEIGHT_FMTSCALE, 2) << " ";
|
||||
if (id.Bit(VS_BIT_FLATSHADE)) desc << "Flat ";
|
||||
|
||||
if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc << "RangeCull ";
|
||||
if (id.Bit(VS_BIT_SIMPLE_STEREO)) desc.C("SimpleStereo ");
|
||||
if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc.C("RangeCull ");
|
||||
|
||||
if (id.Bit(VS_BIT_SIMPLE_STEREO)) desc << "SimpleStereo ";
|
||||
if (id.Bit(VS_BIT_FS_MINMAX_DISCARD)) desc << "FSMinMax ";
|
||||
if (id.Bit(VS_BIT_FS_DEPTH_CLAMP)) desc << "FSDepthClamp ";
|
||||
|
||||
return desc.str();
|
||||
return desc.as_string();
|
||||
}
|
||||
|
||||
void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform, bool weightsAsFloat, bool useSkinInDecode, ClipInfoFlags clipInfoFlags) {
|
||||
@@ -168,96 +177,100 @@ static bool MatrixNeedsProjection(const float m[12], GETexProjMapMode mode) {
|
||||
}
|
||||
|
||||
std::string FragmentShaderDesc(const FShaderID &id) {
|
||||
std::stringstream desc;
|
||||
desc << StringFromFormat("%08x:%08x ", id.d[1], id.d[0]);
|
||||
if (id.Bit(FS_BIT_CLEARMODE)) desc << "Clear ";
|
||||
if (id.Bit(FS_BIT_DO_TEXTURE)) desc << (id.Bit(FS_BIT_3D_TEXTURE) ? "Tex3D " : "Tex ");
|
||||
if (id.Bit(FS_BIT_DO_TEXTURE_PROJ)) desc << "TexProj ";
|
||||
if (id.Bit(FS_BIT_LMODE)) desc << "LM ";
|
||||
if (id.Bit(FS_BIT_FLATSHADE)) desc << "Flat ";
|
||||
if (id.Bit(FS_BIT_DEPTH_TEST_NEVER)) desc << "DepthNever ";
|
||||
if (id.Bit(FS_BIT_COLOR_WRITEMASK)) desc << "WriteMask ";
|
||||
char buffer[512];
|
||||
StringWriter desc(buffer, sizeof(buffer));
|
||||
|
||||
desc.W(id.ToDebugString()).C(" ");
|
||||
if (id.Bit(FS_BIT_CLEARMODE)) desc.C("Clear ");
|
||||
if (id.Bit(FS_BIT_DO_TEXTURE)) {
|
||||
desc.W(id.Bit(FS_BIT_3D_TEXTURE) ? "Tex3D" : "Tex");
|
||||
switch (id.Bits(FS_BIT_TEXFUNC, 3)) {
|
||||
case GE_TEXFUNC_ADD: desc.C("(TFuncAdd) "); break;
|
||||
case GE_TEXFUNC_BLEND: desc.C("(TFuncBlend) "); break;
|
||||
case GE_TEXFUNC_DECAL: desc.C("(TFuncDecal) "); break;
|
||||
case GE_TEXFUNC_MODULATE: desc.C("(TFuncMod) "); break;
|
||||
case GE_TEXFUNC_REPLACE: desc.C("(TFuncRepl) "); break;
|
||||
default: desc.C("(TFuncUnk) "); break;
|
||||
}
|
||||
}
|
||||
if (id.Bit(FS_BIT_LMODE)) desc.C("LM ");
|
||||
if (id.Bit(FS_BIT_ENABLE_FOG)) desc.C("Fog ");
|
||||
if (id.Bit(FS_BIT_FLATSHADE)) desc.C("Flat ");
|
||||
if (id.Bit(FS_BIT_DEPTH_TEST_NEVER)) desc.C("DepthNever ");
|
||||
if (id.Bit(FS_BIT_COLOR_WRITEMASK)) desc.C("WriteMask ");
|
||||
if (id.Bit(FS_BIT_SHADER_TEX_CLAMP)) {
|
||||
desc << "TClamp";
|
||||
if (id.Bit(FS_BIT_CLAMP_S)) desc << "S";
|
||||
if (id.Bit(FS_BIT_CLAMP_T)) desc << "T";
|
||||
desc << " ";
|
||||
desc.C("TClamp");
|
||||
if (id.Bit(FS_BIT_CLAMP_S)) desc.C("S");
|
||||
if (id.Bit(FS_BIT_CLAMP_T)) desc.C("T");
|
||||
desc.C(" ");
|
||||
}
|
||||
int blendBits = id.Bits(FS_BIT_REPLACE_BLEND, 3);
|
||||
if (blendBits) {
|
||||
switch (blendBits) {
|
||||
case ReplaceBlendType::REPLACE_BLEND_BLUE_TO_ALPHA:
|
||||
desc << "BlueToAlpha_" << "A:" << id.Bits(FS_BIT_BLENDFUNC_A, 4);
|
||||
desc.C("BlueToAlpha_" "A:").F("%d ", id.Bits(FS_BIT_BLENDFUNC_A, 4));
|
||||
break;
|
||||
default:
|
||||
desc << "ReplaceBlend_" << id.Bits(FS_BIT_REPLACE_BLEND, 3)
|
||||
<< "A:" << id.Bits(FS_BIT_BLENDFUNC_A, 4)
|
||||
<< "_B:" << id.Bits(FS_BIT_BLENDFUNC_B, 4)
|
||||
<< "_Eq:" << id.Bits(FS_BIT_BLENDEQ, 3) << " ";
|
||||
desc.C("ReplaceBlend_").F("%d ", id.Bits(FS_BIT_REPLACE_BLEND, 3))
|
||||
.C("A:").F("%d ", id.Bits(FS_BIT_BLENDFUNC_A, 4))
|
||||
.C("_B:").F("%d ", id.Bits(FS_BIT_BLENDFUNC_B, 4))
|
||||
.C("_Eq:").F("%d ", id.Bits(FS_BIT_BLENDEQ, 3));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2)) {
|
||||
case REPLACE_ALPHA_NO: break;
|
||||
case REPLACE_ALPHA_YES: desc << "StenToAlpha "; break;
|
||||
case REPLACE_ALPHA_DUALSOURCE: desc << "StenToAlphaDual "; break;
|
||||
}
|
||||
if (id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2) != REPLACE_ALPHA_NO) {
|
||||
switch (id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4)) {
|
||||
case STENCIL_VALUE_UNIFORM: desc << "StenUniform "; break;
|
||||
case STENCIL_VALUE_ZERO: desc << "Sten0 "; break;
|
||||
case STENCIL_VALUE_ONE: desc << "Sten1 "; break;
|
||||
case STENCIL_VALUE_KEEP: desc << "StenKeep "; break;
|
||||
case STENCIL_VALUE_INVERT: desc << "StenInv "; break;
|
||||
case STENCIL_VALUE_INCR_4BIT: desc << "StenIncr4 "; break;
|
||||
case STENCIL_VALUE_INCR_8BIT: desc << "StenIncr8 "; break;
|
||||
case STENCIL_VALUE_DECR_4BIT: desc << "StenDecr4 "; break;
|
||||
case STENCIL_VALUE_DECR_8BIT: desc << "StenDecr8 "; break;
|
||||
default: desc << "StenUnknown "; break;
|
||||
}
|
||||
} else if (id.Bit(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE)) {
|
||||
desc << "StenOff ";
|
||||
}
|
||||
if (id.Bit(FS_BIT_DO_TEXTURE)) {
|
||||
switch (id.Bits(FS_BIT_TEXFUNC, 3)) {
|
||||
case GE_TEXFUNC_ADD: desc << "TFuncAdd "; break;
|
||||
case GE_TEXFUNC_BLEND: desc << "TFuncBlend "; break;
|
||||
case GE_TEXFUNC_DECAL: desc << "TFuncDecal "; break;
|
||||
case GE_TEXFUNC_MODULATE: desc << "TFuncMod "; break;
|
||||
case GE_TEXFUNC_REPLACE: desc << "TFuncRepl "; break;
|
||||
default: desc << "TFuncUnk "; break;
|
||||
}
|
||||
case REPLACE_ALPHA_YES: desc.C("StenToAlpha "); break;
|
||||
case REPLACE_ALPHA_DUALSOURCE: desc.C("StenToAlphaDual "); break;
|
||||
default: desc.C("StenToAlphaUnknown "); break; // bad
|
||||
}
|
||||
|
||||
if (id.Bit(FS_BIT_ALPHA_AGAINST_ZERO)) desc << "AlphaTest0 " << alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)] << " ";
|
||||
else if (id.Bit(FS_BIT_ALPHA_TEST)) desc << "AlphaTest " << alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)] << " ";
|
||||
if (id.Bit(FS_BIT_COLOR_AGAINST_ZERO)) desc << "ColorTest0 " << alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)] << " "; // first 4 match;
|
||||
else if (id.Bit(FS_BIT_COLOR_TEST)) desc << "ColorTest " << alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)] << " "; // first 4 match
|
||||
if (id.Bit(FS_BIT_TEST_DISCARD_TO_ZERO)) desc << "TestDiscardToZero ";
|
||||
if (id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL)) desc << "StencilDiscardWorkaround ";
|
||||
if (id.Bits(FS_BIT_STENCIL_TO_ALPHA, 2) != REPLACE_ALPHA_NO) {
|
||||
switch (id.Bits(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE, 4)) {
|
||||
case STENCIL_VALUE_UNIFORM: desc.C("StenUniform "); break;
|
||||
case STENCIL_VALUE_ZERO: desc.C("Sten0 "); break;
|
||||
case STENCIL_VALUE_ONE: desc.C("Sten1 "); break;
|
||||
case STENCIL_VALUE_KEEP: desc.C("StenKeep "); break;
|
||||
case STENCIL_VALUE_INVERT: desc.C("StenInv "); break;
|
||||
case STENCIL_VALUE_INCR_4BIT: desc.C("StenIncr4 "); break;
|
||||
case STENCIL_VALUE_INCR_8BIT: desc.C("StenIncr8 "); break;
|
||||
case STENCIL_VALUE_DECR_4BIT: desc.C("StenDecr4 "); break;
|
||||
case STENCIL_VALUE_DECR_8BIT: desc.C("StenDecr8 "); break;
|
||||
default: desc.C("StenUnknown "); break;
|
||||
}
|
||||
} else if (id.Bit(FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE)) {
|
||||
desc.C("StenOff ");
|
||||
}
|
||||
|
||||
if (id.Bit(FS_BIT_ALPHA_AGAINST_ZERO)) desc.C("AlphaTest0 ").W(alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)]).C(" ");
|
||||
else if (id.Bit(FS_BIT_ALPHA_TEST)) desc.C("AlphaTest ").W(alphaTestFuncs[id.Bits(FS_BIT_ALPHA_TEST_FUNC, 3)]).C(" ");
|
||||
if (id.Bit(FS_BIT_COLOR_AGAINST_ZERO)) desc.C("ColorTest0 ").W(alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)]).C(" "); // first 4 match;
|
||||
else if (id.Bit(FS_BIT_COLOR_TEST)) desc.C("ColorTest ").W(alphaTestFuncs[id.Bits(FS_BIT_COLOR_TEST_FUNC, 2)]).C(" "); // first 4 match
|
||||
if (id.Bit(FS_BIT_TEST_DISCARD_TO_ZERO)) desc.C("TestDiscardToZero ");
|
||||
if (id.Bit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL)) desc.C("StencilDiscardWorkaround ");
|
||||
int logicMode = id.Bits(FS_BIT_REPLACE_LOGIC_OP, 4);
|
||||
if ((logicMode != GE_LOGIC_COPY) && !id.Bit(FS_BIT_CLEARMODE)) desc << "RLogic(" << logicFuncs[logicMode] << ")";
|
||||
if (id.Bit(FS_BIT_SAMPLE_ARRAY_TEXTURE)) desc << "TexArray ";
|
||||
if (id.Bit(FS_BIT_STEREO)) desc << "Stereo ";
|
||||
if (id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH)) desc << "(fetch)";
|
||||
if (id.Bit(FS_BIT_MINMAX_DISCARD)) desc << "FragMinMaxDiscard ";
|
||||
if (id.Bit(FS_BIT_DEPTH_CLAMP)) desc << "FragDepthClamp ";
|
||||
if ((logicMode != GE_LOGIC_COPY) && !id.Bit(FS_BIT_CLEARMODE)) desc.C("RLogic(").W(logicFuncs[logicMode]).C(")");
|
||||
if (id.Bit(FS_BIT_SAMPLE_ARRAY_TEXTURE)) desc.C("TexArray ");
|
||||
if (id.Bit(FS_BIT_STEREO)) desc.C("Stereo ");
|
||||
if (id.Bit(FS_BIT_USE_FRAMEBUFFER_FETCH)) desc.C("(fetch)");
|
||||
if (id.Bit(FS_BIT_MINMAX_DISCARD)) desc.C("FragMinMaxDiscard ");
|
||||
if (id.Bit(FS_BIT_DEPTH_CLAMP)) desc.C("FragDepthClamp ");
|
||||
|
||||
const ShaderDepalMode depalMode = (ShaderDepalMode)id.Bits(FS_BIT_SHADER_DEPAL_MODE, 2);
|
||||
switch (depalMode) {
|
||||
case ShaderDepalMode::OFF: break;
|
||||
case ShaderDepalMode::NORMAL: desc << "Depal(";
|
||||
case ShaderDepalMode::NORMAL: desc.C("Depal(");
|
||||
{
|
||||
const GEBufferFormat shaderDepalFormat = (GEBufferFormat)id.Bits(FS_BIT_SHADER_DEPAL_FORMAT, 3);
|
||||
desc << GeBufferFormatToString(shaderDepalFormat) << ") ";
|
||||
desc.W(GeBufferFormatToString(shaderDepalFormat)).C(") ");
|
||||
break;
|
||||
}
|
||||
case ShaderDepalMode::SMOOTHED: desc << "SmoothDepal "; break;
|
||||
case ShaderDepalMode::CLUT8_8888: desc << "CLUT8From8888Depal"; break;
|
||||
case ShaderDepalMode::SMOOTHED: desc.C("SmoothDepal "); break;
|
||||
case ShaderDepalMode::CLUT8_8888: desc.C("CLUT8From8888Depal"); break;
|
||||
}
|
||||
|
||||
return desc.str();
|
||||
return desc.as_string();
|
||||
}
|
||||
|
||||
bool FragmentIdNeedsFramebufferRead(const FShaderID &id) {
|
||||
@@ -424,3 +437,24 @@ void ComputeFragmentShaderID(FShaderID *id_out, const ComputedPipelineState &pip
|
||||
|
||||
*id_out = id;
|
||||
}
|
||||
|
||||
std::vector<std::string> ToSortedDebugShaderIdVec(std::vector<uint64_t> ids) {
|
||||
// Reverse the bits so that the sort order matches the importance order.
|
||||
for (auto &id : ids) {
|
||||
id = ReverseBits64(id);
|
||||
}
|
||||
std::sort(ids.begin(), ids.end());
|
||||
// Reverse the bits back to get the original IDs.
|
||||
for (auto &id : ids) {
|
||||
id = ReverseBits64(id);
|
||||
}
|
||||
std::vector<std::string> strIds;
|
||||
for (auto &id : ids) {
|
||||
ShaderID shaderId;
|
||||
shaderId.FromUint64(id);
|
||||
std::string idStr;
|
||||
shaderId.ToString(&idStr);
|
||||
strIds.push_back(idStr);
|
||||
}
|
||||
return strIds;
|
||||
}
|
||||
|
||||
+88
-104
@@ -24,52 +24,47 @@ inline bool needFragmentDepthClamp() {
|
||||
// VS_BIT_LIGHT_UBERSHADER indicates that some groups of these will be
|
||||
// sent to the shader and processed there. This cuts down the number of shaders ("ubershader approach").
|
||||
enum VShaderBit : uint8_t {
|
||||
VS_BIT_LMODE = 0,
|
||||
VS_BIT_IS_THROUGH = 1,
|
||||
// bit 2 is free.
|
||||
VS_BIT_HAS_COLOR = 3,
|
||||
// bit 4 is free.
|
||||
VS_BIT_VERTEX_RANGE_CULLING = 5,
|
||||
VS_BIT_SIMPLE_STEREO = 6,
|
||||
// bit 7 is free,
|
||||
VS_BIT_USE_HW_TRANSFORM = 8,
|
||||
VS_BIT_HAS_NORMAL = 9, // conditioned on hw transform
|
||||
VS_BIT_NORM_REVERSE = 10,
|
||||
VS_BIT_HAS_TEXCOORD = 11,
|
||||
// 4 bits free: 12-15
|
||||
VS_BIT_UVGEN_MODE = 16,
|
||||
VS_BIT_UVPROJ_MODE = 18, // 2, can overlap with LS0
|
||||
VS_BIT_LS0 = 18, // 2
|
||||
VS_BIT_LS1 = 20, // 2
|
||||
VS_BIT_BONES = 22, // 3 should be enough, not 8
|
||||
// 25 - 29 are free.
|
||||
VS_BIT_ENABLE_BONES = 30,
|
||||
VS_BIT_IS_THROUGH = 0,
|
||||
VS_BIT_USE_HW_TRANSFORM = 1,
|
||||
VS_BIT_HAS_NORMAL = 2, // conditioned on hw transform
|
||||
VS_BIT_HAS_TEXCOORD = 3,
|
||||
VS_BIT_HAS_COLOR = 4,
|
||||
VS_BIT_LMODE = 5,
|
||||
VS_BIT_NORM_REVERSE = 6,
|
||||
VS_BIT_FLATSHADE = 7,
|
||||
VS_BIT_MATERIAL_UPDATE = 8, // 3 bits
|
||||
// Free bit: 11
|
||||
VS_BIT_UVGEN_MODE = 12, // 2 bits
|
||||
VS_BIT_UVPROJ_MODE = 14, // 2 bits
|
||||
VS_BIT_ENABLE_BONES = 16,
|
||||
VS_BIT_WEIGHT_FMTSCALE = 17, // only two bits
|
||||
VS_BIT_BONES = 19, // 3 should be enough to represent 1-8 bones.
|
||||
VS_BIT_FS_MINMAX_DISCARD = 22, // Do min/max and/or depth clamp in the fragment shader. It just means we need to forward Z and W to the fragment shader.
|
||||
VS_BIT_FS_DEPTH_CLAMP = 23, // Do depth clamp in the fragment shader.
|
||||
VS_BIT_LIGHTING_ENABLE = 24,
|
||||
VS_BIT_LS0 = 25, // 2 bits
|
||||
VS_BIT_LS1 = 27, // 2 bits
|
||||
|
||||
// If this is set along with LIGHTING_ENABLE, all other lighting bits below
|
||||
// are passed to the shader directly instead.
|
||||
VS_BIT_LIGHT_UBERSHADER = 31,
|
||||
VS_BIT_LIGHT_UBERSHADER = 29,
|
||||
|
||||
VS_BIT_LIGHT0_COMP = 32, // 2 bits
|
||||
VS_BIT_LIGHT0_TYPE = 34, // 2 bits
|
||||
VS_BIT_LIGHT1_COMP = 36, // 2 bits
|
||||
VS_BIT_LIGHT1_TYPE = 38, // 2 bits
|
||||
VS_BIT_LIGHT2_COMP = 40, // 2 bits
|
||||
VS_BIT_LIGHT2_TYPE = 42, // 2 bits
|
||||
VS_BIT_LIGHT3_COMP = 44, // 2 bits
|
||||
VS_BIT_LIGHT3_TYPE = 46, // 2 bits
|
||||
VS_BIT_MATERIAL_UPDATE = 48, // 3 bits
|
||||
// Bit 51 is free.
|
||||
VS_BIT_LIGHT0_ENABLE = 52,
|
||||
VS_BIT_LIGHT1_ENABLE = 53,
|
||||
VS_BIT_LIGHT2_ENABLE = 54,
|
||||
VS_BIT_LIGHT3_ENABLE = 55,
|
||||
VS_BIT_LIGHTING_ENABLE = 56,
|
||||
VS_BIT_WEIGHT_FMTSCALE = 57, // only two bits
|
||||
// 59 - 61 are free.
|
||||
VS_BIT_FS_MINMAX_DISCARD = 59, // Do min/max and/or depth clamp in the fragment shader. It just means we need to forward Z and W to the fragment shader.
|
||||
VS_BIT_FS_DEPTH_CLAMP = 60, // Do depth clamp in the fragment shader.
|
||||
VS_BIT_FLATSHADE = 62, // 1 bit
|
||||
// Bit 63 is free.
|
||||
VS_BIT_LIGHT0_COMP = 30, // 2 bits
|
||||
VS_BIT_LIGHT0_TYPE = 32, // 2 bits
|
||||
VS_BIT_LIGHT1_COMP = 34, // 2 bits
|
||||
VS_BIT_LIGHT1_TYPE = 36, // 2 bits
|
||||
VS_BIT_LIGHT2_COMP = 38, // 2 bits
|
||||
VS_BIT_LIGHT2_TYPE = 40, // 2 bits
|
||||
VS_BIT_LIGHT3_COMP = 42, // 2 bits
|
||||
VS_BIT_LIGHT3_TYPE = 44, // 2 bits
|
||||
VS_BIT_LIGHT0_ENABLE = 46,
|
||||
VS_BIT_LIGHT1_ENABLE = 47,
|
||||
VS_BIT_LIGHT2_ENABLE = 48,
|
||||
VS_BIT_LIGHT3_ENABLE = 49,
|
||||
|
||||
VS_BIT_VERTEX_RANGE_CULLING = 50,
|
||||
VS_BIT_SIMPLE_STEREO = 51,
|
||||
// bits 52-63 are free.
|
||||
};
|
||||
|
||||
static inline VShaderBit operator +(VShaderBit bit, int i) {
|
||||
@@ -80,20 +75,23 @@ static inline VShaderBit operator +(VShaderBit bit, int i) {
|
||||
enum FShaderBit : uint8_t {
|
||||
FS_BIT_CLEARMODE = 0,
|
||||
FS_BIT_DO_TEXTURE = 1,
|
||||
FS_BIT_TEXFUNC = 2, // 3 bits
|
||||
FS_BIT_SHADER_TEX_CLAMP = 5,
|
||||
FS_BIT_CLAMP_S = 6,
|
||||
FS_BIT_CLAMP_T = 7,
|
||||
FS_BIT_SHADER_DEPAL_FORMAT = 8, // 3 bits (GEBufferFormat), connected to FS_BIT_SHADER_DEPAL_MODE
|
||||
FS_BIT_3D_TEXTURE = 2,
|
||||
FS_BIT_DO_TEXTURE_PROJ = 3,
|
||||
FS_BIT_TEXFUNC = 4, // 3 bits
|
||||
FS_BIT_LMODE = 7,
|
||||
FS_BIT_ENABLE_FOG = 8,
|
||||
FS_BIT_FLATSHADE = 9,
|
||||
FS_BIT_DEPTH_CLAMP = 10, // These both are connected to VS_BIT_MINMAX_DISCARD_OR_DEPTH_CLAMP in the vertex shader.
|
||||
FS_BIT_MINMAX_DISCARD = 11,
|
||||
FS_BIT_ALPHA_TEST = 12,
|
||||
FS_BIT_ALPHA_TEST_FUNC = 13, // 3 bits
|
||||
FS_BIT_ALPHA_AGAINST_ZERO = 16,
|
||||
FS_BIT_COLOR_TEST = 17,
|
||||
FS_BIT_COLOR_TEST_FUNC = 18, // 2 bits
|
||||
FS_BIT_COLOR_AGAINST_ZERO = 20,
|
||||
FS_BIT_ENABLE_FOG = 21,
|
||||
FS_BIT_DO_TEXTURE_PROJ = 22,
|
||||
FS_BIT_MINMAX_DISCARD = 23,
|
||||
FS_BIT_SHADER_TEX_CLAMP = 21,
|
||||
FS_BIT_CLAMP_S = 22,
|
||||
FS_BIT_CLAMP_T = 23,
|
||||
FS_BIT_STENCIL_TO_ALPHA = 24, // 2 bits
|
||||
FS_BIT_REPLACE_ALPHA_WITH_STENCIL_TYPE = 26, // 4 bits (ReplaceAlphaType)
|
||||
FS_BIT_SIMULATE_LOGIC_OP_TYPE = 30, // 2 bits
|
||||
@@ -101,20 +99,17 @@ enum FShaderBit : uint8_t {
|
||||
FS_BIT_BLENDEQ = 35, // 3 bits
|
||||
FS_BIT_BLENDFUNC_A = 38, // 4 bits
|
||||
FS_BIT_BLENDFUNC_B = 42, // 4 bits
|
||||
FS_BIT_FLATSHADE = 46,
|
||||
// Free bit 47
|
||||
FS_BIT_TEST_DISCARD_TO_ZERO = 48,
|
||||
FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 49,
|
||||
FS_BIT_COLOR_WRITEMASK = 50,
|
||||
FS_BIT_REPLACE_LOGIC_OP = 51, // 4 bits. GE_LOGIC_COPY means no-op/off.
|
||||
FS_BIT_SHADER_DEPAL_MODE = 55, // 2 bits (ShaderDepalMode)
|
||||
FS_BIT_SAMPLE_ARRAY_TEXTURE = 57, // For multiview, framebuffers are array textures and we need to sample the two layers correctly.
|
||||
FS_BIT_TEST_DISCARD_TO_ZERO = 46,
|
||||
FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL = 47,
|
||||
FS_BIT_COLOR_WRITEMASK = 48,
|
||||
FS_BIT_REPLACE_LOGIC_OP = 49, // 4 bits. GE_LOGIC_COPY means no-op/off.
|
||||
FS_BIT_SHADER_DEPAL_MODE = 53, // 2 bits (ShaderDepalMode)
|
||||
FS_BIT_SHADER_DEPAL_FORMAT = 55, // 3 bits (GEBufferFormat), connected to FS_BIT_SHADER_DEPAL_MODE
|
||||
FS_BIT_STEREO = 58,
|
||||
FS_BIT_USE_FRAMEBUFFER_FETCH = 59,
|
||||
FS_BIT_LMODE = 60,
|
||||
FS_BIT_DEPTH_TEST_NEVER = 61, // Only used on Mali. Set when depth == NEVER. We forcibly avoid writing to depth in this case, since it crashes the driver.
|
||||
FS_BIT_DEPTH_CLAMP = 62, // These both are connected to VS_BIT_MINMAX_DISCARD_OR_DEPTH_CLAMP in the vertex shader.
|
||||
FS_BIT_3D_TEXTURE = 63,
|
||||
FS_BIT_DEPTH_TEST_NEVER = 60, // Only used on Mali. Set when depth == NEVER. We forcibly avoid writing to depth in this case, since it crashes the driver.
|
||||
FS_BIT_SAMPLE_ARRAY_TEXTURE = 61, // For multiview, framebuffers are array textures and we need to sample the two layers correctly.
|
||||
// Free bits: 62-63
|
||||
};
|
||||
|
||||
static inline FShaderBit operator +(FShaderBit bit, int i) {
|
||||
@@ -126,87 +121,73 @@ struct ShaderID {
|
||||
clear();
|
||||
}
|
||||
void clear() {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(d); i++) {
|
||||
d[i] = 0;
|
||||
}
|
||||
d = 0;
|
||||
}
|
||||
void set_invalid() {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(d); i++) {
|
||||
d[i] = 0xFFFFFFFF;
|
||||
}
|
||||
d = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
bool is_invalid() const {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(d); i++) {
|
||||
if (d[i] != 0xFFFFFFFF)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return d == 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
uint32_t d[2];
|
||||
bool operator < (const ShaderID &other) const {
|
||||
for (size_t i = 0; i < sizeof(d) / sizeof(uint32_t); i++) {
|
||||
if (d[i] < other.d[i])
|
||||
return true;
|
||||
if (d[i] > other.d[i])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return d < other.d;
|
||||
}
|
||||
bool operator == (const ShaderID &other) const {
|
||||
for (size_t i = 0; i < sizeof(d) / sizeof(uint32_t); i++) {
|
||||
if (d[i] != other.d[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return d == other.d;
|
||||
}
|
||||
bool operator != (const ShaderID &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
uint32_t Word(int word) const {
|
||||
return d[word];
|
||||
}
|
||||
|
||||
// Note: This is a binary copy to string-as-bytes, not a human-readable representation.
|
||||
void ToString(std::string *dest) const {
|
||||
dest->resize(sizeof(d));
|
||||
memcpy(&(*dest)[0], d, sizeof(d));
|
||||
memcpy(&(*dest)[0], &d, sizeof(d));
|
||||
}
|
||||
// Note: This is a binary copy from string-as-bytes, not a human-readable representation.
|
||||
void FromString(std::string src) {
|
||||
memcpy(d, &(src)[0], sizeof(d));
|
||||
memcpy(&d, &(src)[0], sizeof(d));
|
||||
}
|
||||
|
||||
uint64_t ToUint64() const {
|
||||
return d;
|
||||
}
|
||||
void FromUint64(uint64_t src) {
|
||||
d = src;
|
||||
}
|
||||
|
||||
std::string ToDebugString() const;
|
||||
uint64_t d;
|
||||
protected:
|
||||
bool Bit(int bit) const {
|
||||
return (d[bit >> 5] >> (bit & 31)) & 1;
|
||||
return (d >> bit) & 1;
|
||||
}
|
||||
// Does not handle crossing 32-bit boundaries. count must be 30 or smaller.
|
||||
int Bits(int bit, int count) const {
|
||||
const int mask = (1 << count) - 1;
|
||||
return (d[bit >> 5] >> (bit & 31)) & mask;
|
||||
return (d >> bit) & mask;
|
||||
}
|
||||
void SetBit(int bit, bool value = true) {
|
||||
if (value) {
|
||||
d[bit >> 5] |= 1 << (bit & 31);
|
||||
d |= 1ULL << bit;
|
||||
} else {
|
||||
d[bit >> 5] &= ~(1 << (bit & 31));
|
||||
d &= ~(1ULL << bit);
|
||||
}
|
||||
}
|
||||
void SetBits(int bit, int count, int value) {
|
||||
const int mask = (1 << count) - 1;
|
||||
const int shifted_mask = mask << (bit & 31);
|
||||
d[bit >> 5] = (d[bit >> 5] & ~shifted_mask) | ((value & mask) << (bit & 31));
|
||||
const uint64_t shifted_mask = uint64_t(mask) << bit;
|
||||
d = (d & ~shifted_mask) | (uint64_t(value & mask) << bit);
|
||||
}
|
||||
};
|
||||
|
||||
struct VShaderID : ShaderID {
|
||||
struct VShaderID : public ShaderID {
|
||||
VShaderID() : ShaderID() {
|
||||
}
|
||||
|
||||
explicit VShaderID(ShaderID &src) {
|
||||
memcpy(d, src.d, sizeof(d));
|
||||
explicit VShaderID(const ShaderID &src) {
|
||||
d = src.d;
|
||||
}
|
||||
|
||||
bool Bit(VShaderBit bit) const {
|
||||
@@ -226,12 +207,12 @@ struct VShaderID : ShaderID {
|
||||
}
|
||||
};
|
||||
|
||||
struct FShaderID : ShaderID {
|
||||
struct FShaderID : public ShaderID {
|
||||
FShaderID() : ShaderID() {
|
||||
}
|
||||
|
||||
explicit FShaderID(ShaderID &src) {
|
||||
memcpy(d, src.d, sizeof(d));
|
||||
explicit FShaderID(const ShaderID &src) {
|
||||
d = src.d;
|
||||
}
|
||||
|
||||
bool Bit(FShaderBit bit) const {
|
||||
@@ -266,3 +247,6 @@ std::string FragmentShaderDesc(const FShaderID &id);
|
||||
|
||||
// For sanity checking.
|
||||
bool FragmentIdNeedsFramebufferRead(const FShaderID &id);
|
||||
|
||||
// For the shader viewer.
|
||||
std::vector<std::string> ToSortedDebugShaderIdVec(std::vector<uint64_t> ids);
|
||||
|
||||
@@ -262,28 +262,26 @@ void ShaderManagerD3D11::GetShaders(int prim, u32 vertexType, D3D11VertexShader
|
||||
|
||||
std::vector<std::string> ShaderManagerD3D11::DebugGetShaderIDs(DebugShaderType type) {
|
||||
std::string id;
|
||||
std::vector<std::string> ids;
|
||||
std::vector<uint64_t> ids;
|
||||
switch (type) {
|
||||
case SHADER_TYPE_VERTEX:
|
||||
{
|
||||
for (auto iter : vsCache_) {
|
||||
iter.first.ToString(&id);
|
||||
ids.push_back(id);
|
||||
for (auto &iter : vsCache_) {
|
||||
ids.push_back(iter.first.ToUint64());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHADER_TYPE_FRAGMENT:
|
||||
{
|
||||
for (auto iter : fsCache_) {
|
||||
iter.first.ToString(&id);
|
||||
ids.push_back(id);
|
||||
for (auto &iter : fsCache_) {
|
||||
ids.push_back(iter.first.ToUint64());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ids;
|
||||
return ToSortedDebugShaderIdVec(ids);
|
||||
}
|
||||
|
||||
std::string ShaderManagerD3D11::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
|
||||
|
||||
@@ -673,7 +673,7 @@ Shader *ShaderManagerGLES::CompileFragmentShader(FShaderID FSID) {
|
||||
std::string errorString;
|
||||
FragmentShaderFlags flags;
|
||||
if (!GenerateFragmentShader(FSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &uniformMask, &flags, &errorString)) {
|
||||
ERROR_LOG_REPORT(Log::G3D, "FS shader gen error: %s (%s: %08x:%08x)", errorString.c_str(), "GLES", FSID.d[0], FSID.d[1]);
|
||||
ERROR_LOG_REPORT(Log::G3D, "FS shader gen error: %s (%s: %s)", errorString.c_str(), "GLES", FSID.ToDebugString().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
_assert_msg_(strlen(codeBuffer_) < CODE_BUFFER_SIZE, "FS length error: %d", (int)strlen(codeBuffer_));
|
||||
@@ -691,7 +691,7 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
|
||||
std::string errorString;
|
||||
VertexShaderFlags flags;
|
||||
if (!GenerateVertexShader(VSID, codeBuffer_, draw_->GetShaderLanguageDesc(), draw_->GetBugs(), &attrMask, &uniformMask, &flags, &errorString)) {
|
||||
ERROR_LOG_REPORT(Log::G3D, "VS shader gen error: %s (%s: %08x:%08x)", errorString.c_str(), "GLES", VSID.d[0], VSID.d[1]);
|
||||
ERROR_LOG_REPORT(Log::G3D, "VS shader gen error: %s (%s: %s)", errorString.c_str(), "GLES", VSID.ToDebugString().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
_assert_msg_(strlen(codeBuffer_) < CODE_BUFFER_SIZE, "VS length error: %d", (int)strlen(codeBuffer_));
|
||||
@@ -776,7 +776,7 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(VShaderID VSID, Shader *vs,
|
||||
// Could fail to generate, in which case we're kinda screwed.
|
||||
fs = CompileFragmentShader(FSID);
|
||||
if (!fs) {
|
||||
ERROR_LOG(Log::G3D, "Failed to generate fragment shader with ID %08x:%08x", FSID.d[0], FSID.d[1]);
|
||||
ERROR_LOG(Log::G3D, "Failed to generate fragment shader with ID %s", FSID.ToDebugString().c_str());
|
||||
// Still insert it so we don't end up spamming generation.
|
||||
}
|
||||
fsCache_.Insert(FSID, fs);
|
||||
@@ -834,26 +834,22 @@ std::string Shader::GetShaderString(DebugShaderStringType type, ShaderID id) con
|
||||
|
||||
std::vector<std::string> ShaderManagerGLES::DebugGetShaderIDs(DebugShaderType type) {
|
||||
std::string id;
|
||||
std::vector<std::string> ids;
|
||||
std::vector<uint64_t> ids;
|
||||
switch (type) {
|
||||
case SHADER_TYPE_VERTEX:
|
||||
vsCache_.Iterate([&](const VShaderID &id, Shader *shader) {
|
||||
std::string idstr;
|
||||
id.ToString(&idstr);
|
||||
ids.push_back(idstr);
|
||||
ids.push_back(id.ToUint64());
|
||||
});
|
||||
break;
|
||||
case SHADER_TYPE_FRAGMENT:
|
||||
fsCache_.Iterate([&](const FShaderID &id, Shader *shader) {
|
||||
std::string idstr;
|
||||
id.ToString(&idstr);
|
||||
ids.push_back(idstr);
|
||||
ids.push_back(id.ToUint64());
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ids;
|
||||
return ToSortedDebugShaderIdVec(ids);
|
||||
}
|
||||
|
||||
std::string ShaderManagerGLES::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
|
||||
@@ -900,7 +896,7 @@ enum class CacheDetectFlags {
|
||||
};
|
||||
|
||||
#define CACHE_HEADER_MAGIC 0x83277592
|
||||
#define CACHE_VERSION 40
|
||||
#define CACHE_VERSION 42
|
||||
|
||||
struct CacheHeader {
|
||||
uint32_t magic;
|
||||
|
||||
+7
-4
@@ -1780,9 +1780,7 @@ void GPUCommonHW::FormatGPUStatsCommon(StringWriter &w) {
|
||||
"block transfers: %d\n"
|
||||
"replacer: tracks %d references, %d unique textures\n"
|
||||
"Cpy: depth %d, color %d, reint %d, blend %d, self %d\n"
|
||||
"GPU cycles: %d (%0.1f per vertex)\n"
|
||||
"Z-rast: %0.2f+%0.2f+%0.2f (total %0.2f/%0.2f) ms\n"
|
||||
"Z-rast: %d prim, %d nopix, %d small, %d earlysize, %d zcull, %d box\n%s",
|
||||
"GPU cycles: %d (%0.1f per vertex)\n",
|
||||
gpuStats.perFrame.msProcessingDisplayLists * 1000.0f,
|
||||
gpuStats.perFrame.numEnqueue,
|
||||
gpuStats.perFrame.numUpdateStall,
|
||||
@@ -1823,7 +1821,11 @@ void GPUCommonHW::FormatGPUStatsCommon(StringWriter &w) {
|
||||
gpuStats.perFrame.numCopiesForShaderBlend,
|
||||
gpuStats.perFrame.numCopiesForSelfTex,
|
||||
gpuStats.perFrame.vertexGPUCycles + gpuStats.perFrame.otherGPUCycles,
|
||||
vertexAverageCycles,
|
||||
vertexAverageCycles);
|
||||
|
||||
if (PSP_CoreParameter().compat.flags().SoftwareRasterDepth) {
|
||||
w.F("Z-rast: %0.2f+%0.2f+%0.2f (total %0.2f/%0.2f) ms\n"
|
||||
"Z-rast: %d prim, %d nopix, %d small, %d earlysize, %d zcull, %d box\n%s",
|
||||
gpuStats.perFrame.msPrepareDepth * 1000.0,
|
||||
gpuStats.perFrame.msCullDepth * 1000.0,
|
||||
gpuStats.perFrame.msRasterizeDepth * 1000.0,
|
||||
@@ -1838,3 +1840,4 @@ void GPUCommonHW::FormatGPUStatsCommon(StringWriter &w) {
|
||||
debugRecording_ ? "(debug-recording)" : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,28 +318,23 @@ void ShaderManagerVulkan::GetShaders(int prim, u32 vertexType, VulkanVertexShade
|
||||
}
|
||||
|
||||
std::vector<std::string> ShaderManagerVulkan::DebugGetShaderIDs(DebugShaderType type) {
|
||||
std::vector<std::string> ids;
|
||||
std::vector<uint64_t> ids;
|
||||
switch (type) {
|
||||
case SHADER_TYPE_VERTEX:
|
||||
vsCache_.Iterate([&](const VShaderID &id, VulkanVertexShader *shader) {
|
||||
std::string idstr;
|
||||
id.ToString(&idstr);
|
||||
ids.push_back(idstr);
|
||||
ids.push_back(id.ToUint64());
|
||||
});
|
||||
break;
|
||||
case SHADER_TYPE_FRAGMENT:
|
||||
fsCache_.Iterate([&](const FShaderID &id, VulkanFragmentShader *shader) {
|
||||
std::string idstr;
|
||||
id.ToString(&idstr);
|
||||
ids.push_back(idstr);
|
||||
ids.push_back(id.ToUint64());
|
||||
});
|
||||
break;
|
||||
case SHADER_TYPE_GEOMETRY:
|
||||
return ids;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ids;
|
||||
|
||||
return ToSortedDebugShaderIdVec(ids);
|
||||
}
|
||||
|
||||
std::string ShaderManagerVulkan::DebugGetShaderString(std::string id, DebugShaderType type, DebugShaderStringType stringType) {
|
||||
@@ -408,7 +403,7 @@ enum class VulkanCacheDetectFlags {
|
||||
};
|
||||
|
||||
#define CACHE_HEADER_MAGIC 0xff51f420
|
||||
#define CACHE_VERSION 56
|
||||
#define CACHE_VERSION 58
|
||||
|
||||
struct VulkanCacheHeader {
|
||||
uint32_t magic;
|
||||
|
||||
@@ -187,7 +187,16 @@
|
||||
"location-emoji": "🇧🇷",
|
||||
"description": "Rede br para partidas online de jogos PSP.",
|
||||
"data_mode": "AemuPostoffice",
|
||||
"status_data_json": "http://pspbrasil.duckdns.org/data.json"
|
||||
"status_data_json": "https://pspbrasil.duckdns.org/data.json"
|
||||
},
|
||||
{
|
||||
"name": "Jeddah relay",
|
||||
"host": "jeddah-relay.ddns.net",
|
||||
"discord": "",
|
||||
"location": "Saudi Arabia",
|
||||
"location-emoji": "🇸🇦",
|
||||
"description": "For players looking to play any games",
|
||||
"data_mode": "AemuPostoffice"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1033,7 +1033,7 @@ No games in progress on this server = Keine Spiele auf diesem Server aktiv
|
||||
Other versions of this game that should work: = Andere Versionen dieses Spiels, die funktionieren sollten:
|
||||
P2P mode = P2P-Modus
|
||||
PacketRelayHint = Verfügbar auf Servern, die 'aemu_postoffice' Paketweiterleitung wie socom.cc anbieten. Deaktiviere dies für LAN- oder VPN-Spiel. Kann zuverlässiger sein, aber manchmal langsamer.
|
||||
Players waiting: %1 = Spieler warten:
|
||||
Players waiting: %1 = Spieler warten: %1
|
||||
players: %1 = Spieler: %1
|
||||
Please change your Port Offset = Bitte ändere deinen Port-Offset
|
||||
Open PPSSPP Multiplayer Wiki Page = PPSSPP-Ad-Hoc-Wiki-Seite
|
||||
|
||||
@@ -368,11 +368,9 @@ bool TestVertexShaders() {
|
||||
// Generate a bunch of random vertex shader IDs, try to generate shader source.
|
||||
// Then compile it and check that it's ok.
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t bottom = rng.R32();
|
||||
uint32_t top = rng.R32();
|
||||
uint64_t id64 = rng.R64();
|
||||
VShaderID id;
|
||||
id.d[0] = bottom;
|
||||
id.d[1] = top;
|
||||
id.FromUint64(id64);
|
||||
|
||||
// The generated bits need some adjustment:
|
||||
|
||||
@@ -453,11 +451,9 @@ bool TestFragmentShaders() {
|
||||
// Generate a bunch of random fragment shader IDs, try to generate shader source.
|
||||
// Then compile it and check that it's ok.
|
||||
for (int i = 0; i < count; i++) {
|
||||
uint32_t bottom = rng.R32();
|
||||
uint32_t top = rng.R32();
|
||||
uint64_t id64 = rng.R64();
|
||||
FShaderID id;
|
||||
id.d[0] = bottom;
|
||||
id.d[1] = top;
|
||||
id.FromUint64(id64);
|
||||
|
||||
// bits we don't need to test because they are irrelevant on d3d11
|
||||
id.SetBit(FS_BIT_NO_DEPTH_CANNOT_DISCARD_STENCIL, false);
|
||||
|
||||
Reference in New Issue
Block a user