mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Workaround the lack of support for software skinning in Vulkan
This commit is contained in:
parent
69267d4cd6
commit
f111767315
@ -1542,23 +1542,6 @@ void GPU_DX9::Execute_Generic(u32 op, u32 diff) {
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_DX9::FastLoadBoneMatrix(u32 target) {
|
||||
const int num = gstate.boneMatrixNumber & 0x7F;
|
||||
const int mtxNum = num / 12;
|
||||
uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum;
|
||||
if ((num - 12 * mtxNum) != 0) {
|
||||
uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7);
|
||||
}
|
||||
|
||||
if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
|
||||
Flush();
|
||||
shaderManager_->DirtyUniform(uniformsToDirty);
|
||||
} else {
|
||||
gstate_c.deferredVertTypeDirty |= uniformsToDirty;
|
||||
}
|
||||
gstate.FastLoadBoneMatrix(target);
|
||||
}
|
||||
|
||||
void GPU_DX9::GetStats(char *buffer, size_t bufsize) {
|
||||
float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f;
|
||||
snprintf(buffer, bufsize - 1,
|
||||
|
@ -131,7 +131,6 @@ public:
|
||||
|
||||
protected:
|
||||
void FastRunLoop(DisplayList &list) override;
|
||||
void FastLoadBoneMatrix(u32 target) override;
|
||||
void FinishDeferred() override;
|
||||
|
||||
private:
|
||||
|
@ -664,6 +664,7 @@ void GPU_GLES::DeviceLost() {
|
||||
void GPU_GLES::DeviceRestore() {
|
||||
ILOG("GPU_GLES: DeviceRestore");
|
||||
|
||||
UpdateCmdInfo();
|
||||
UpdateVsyncInterval(true);
|
||||
}
|
||||
|
||||
@ -1821,23 +1822,6 @@ void GPU_GLES::Execute_Generic(u32 op, u32 diff) {
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_GLES::FastLoadBoneMatrix(u32 target) {
|
||||
const int num = gstate.boneMatrixNumber & 0x7F;
|
||||
const int mtxNum = num / 12;
|
||||
uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum;
|
||||
if ((num - 12 * mtxNum) != 0) {
|
||||
uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7);
|
||||
}
|
||||
|
||||
if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
|
||||
Flush();
|
||||
shaderManager_->DirtyUniform(uniformsToDirty);
|
||||
} else {
|
||||
gstate_c.deferredVertTypeDirty |= uniformsToDirty;
|
||||
}
|
||||
gstate.FastLoadBoneMatrix(target);
|
||||
}
|
||||
|
||||
void GPU_GLES::GetStats(char *buffer, size_t bufsize) {
|
||||
float vertexAverageCycles = gpuStats.numVertsSubmitted > 0 ? (float)gpuStats.vertexGPUCycles / (float)gpuStats.numVertsSubmitted : 0.0f;
|
||||
snprintf(buffer, bufsize - 1,
|
||||
|
@ -137,7 +137,6 @@ public:
|
||||
|
||||
protected:
|
||||
void FastRunLoop(DisplayList &list) override;
|
||||
void FastLoadBoneMatrix(u32 target) override;
|
||||
void FinishDeferred() override;
|
||||
|
||||
private:
|
||||
|
@ -1468,6 +1468,19 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) {
|
||||
}
|
||||
|
||||
void GPUCommon::FastLoadBoneMatrix(u32 target) {
|
||||
const int num = gstate.boneMatrixNumber & 0x7F;
|
||||
const int mtxNum = num / 12;
|
||||
uint32_t uniformsToDirty = DIRTY_BONEMATRIX0 << mtxNum;
|
||||
if ((num - 12 * mtxNum) != 0) {
|
||||
uniformsToDirty |= DIRTY_BONEMATRIX0 << ((mtxNum + 1) & 7);
|
||||
}
|
||||
|
||||
if (!g_Config.bSoftwareSkinning || (gstate.vertType & GE_VTYPE_MORPHCOUNT_MASK) != 0) {
|
||||
Flush();
|
||||
shaderManager_->DirtyUniform(uniformsToDirty);
|
||||
} else {
|
||||
gstate_c.deferredVertTypeDirty |= uniformsToDirty;
|
||||
}
|
||||
gstate.FastLoadBoneMatrix(target);
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,7 @@ static const CommandTableEntry commandTable[] = {
|
||||
{ GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BJump }, // EXECUTE
|
||||
{ GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to?
|
||||
|
||||
// Changing the vertex type requires us to flush.
|
||||
// Changing the vertex type requires us to flush.
|
||||
{ GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_Vulkan::Execute_VertexType },
|
||||
|
||||
{ GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Bezier },
|
||||
@ -348,8 +348,8 @@ static const CommandTableEntry commandTable[] = {
|
||||
{ GE_CMD_PROJMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ProjMtxData },
|
||||
{ GE_CMD_TGENMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_TgenMtxNum },
|
||||
{ GE_CMD_TGENMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_TgenMtxData },
|
||||
{ GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BoneMtxNum },
|
||||
{ GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoneMtxData },
|
||||
{ GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPU_Vulkan::Execute_BoneMtxNum },
|
||||
{ GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_BoneMtxData },
|
||||
|
||||
// Vertex Screen/Texture/Color
|
||||
{ GE_CMD_VSCX, FLAG_EXECUTE },
|
||||
@ -1097,6 +1097,52 @@ void GPU_Vulkan::Execute_ColorRef(u32 op, u32 diff) {
|
||||
shaderManager_->DirtyUniform(DIRTY_ALPHACOLORREF);
|
||||
}
|
||||
|
||||
void GPU_Vulkan::Execute_BoneMtxNum(u32 op, u32 diff) {
|
||||
// This is almost always followed by GE_CMD_BONEMATRIXDATA.
|
||||
const u32_le *src = (const u32_le *)Memory::GetPointerUnchecked(currentList->pc + 4);
|
||||
u32 *dst = (u32 *)(gstate.boneMatrix + (op & 0x7F));
|
||||
const int end = 12 * 8 - (op & 0x7F);
|
||||
int i = 0;
|
||||
|
||||
// If we can't use software skinning, we have to flush and dirty.
|
||||
while ((src[i] >> 24) == GE_CMD_BONEMATRIXDATA) {
|
||||
const u32 newVal = src[i] << 8;
|
||||
if (dst[i] != newVal) {
|
||||
Flush();
|
||||
dst[i] = newVal;
|
||||
}
|
||||
if (++i >= end) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const int numPlusCount = (op & 0x7F) + i;
|
||||
for (int num = op & 0x7F; num < numPlusCount; num += 12) {
|
||||
shaderManager_->DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12));
|
||||
}
|
||||
|
||||
const int count = i;
|
||||
gstate.boneMatrixNumber = (GE_CMD_BONEMATRIXNUMBER << 24) | ((op + count) & 0x7F);
|
||||
|
||||
// Skip over the loaded data, it's done now.
|
||||
UpdatePC(currentList->pc, currentList->pc + count * 4);
|
||||
currentList->pc += count * 4;
|
||||
}
|
||||
|
||||
void GPU_Vulkan::Execute_BoneMtxData(u32 op, u32 diff) {
|
||||
// Note: it's uncommon to get here now, see above.
|
||||
int num = gstate.boneMatrixNumber & 0x7F;
|
||||
u32 newVal = op << 8;
|
||||
if (num < 96 && newVal != ((const u32 *)gstate.boneMatrix)[num]) {
|
||||
// Bone matrices should NOT flush when software skinning is enabled!
|
||||
Flush();
|
||||
shaderManager_->DirtyUniform(DIRTY_BONEMATRIX0 << (num / 12));
|
||||
((u32 *)gstate.boneMatrix)[num] = newVal;
|
||||
}
|
||||
num++;
|
||||
gstate.boneMatrixNumber = (GE_CMD_BONEMATRIXNUMBER << 24) | (num & 0x7F);
|
||||
}
|
||||
|
||||
void GPU_Vulkan::Execute_Generic(u32 op, u32 diff) {
|
||||
u32 cmd = op >> 24;
|
||||
u32 data = op & 0xFFFFFF;
|
||||
|
@ -117,6 +117,8 @@ public:
|
||||
void Execute_AlphaTest(u32 op, u32 diff);
|
||||
void Execute_StencilTest(u32 op, u32 diff);
|
||||
void Execute_ColorRef(u32 op, u32 diff);
|
||||
void Execute_BoneMtxNum(u32 op, u32 diff);
|
||||
void Execute_BoneMtxData(u32 op, u32 diff);
|
||||
|
||||
// Using string because it's generic - makes no assumptions on the size of the shader IDs of this backend.
|
||||
std::vector<std::string> DebugGetShaderIDs(DebugShaderType shader) override;
|
||||
|
Loading…
Reference in New Issue
Block a user