Further centralization of EstimatePerVertexCost, now moved to GPUCommon

This commit is contained in:
Henrik Rydgard 2017-01-23 21:00:44 +01:00
parent daf02f1de6
commit ae37df0a8c
7 changed files with 39 additions and 68 deletions

View File

@ -58,35 +58,6 @@ public:
std::vector<std::string> DebugGetVertexLoaderIDs();
std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType);
int EstimatePerVertexCost() {
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
// runs in parallel with transform.
// Also, this is all pure guesswork. If we can find a way to do measurements, that would be great.
// GTA wants a low value to run smooth, GoW wants a high value (otherwise it thinks things
// went too fast and starts doing all the work over again).
int cost = 20;
if (gstate.isLightingEnabled()) {
cost += 10;
for (int i = 0; i < 4; i++) {
if (gstate.isLightChanEnabled(i))
cost += 10;
}
}
if (gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_COORDS) {
cost += 20;
}
int morphCount = gstate.getNumMorphWeights();
if (morphCount > 1) {
cost += 5 * morphCount;
}
return cost;
}
protected:
// Preprocessing for spline/bezier
u32 NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr, int lowerBound, int upperBound, u32 vertType);

View File

@ -756,8 +756,7 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) {
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
drawEngine_.SetupVertexDecoder(gstate.vertType);
// Rough estimate, not sure what's correct.
int vertexCost = drawEngine_.EstimatePerVertexCost();
cyclesExecuted += vertexCost * count;
cyclesExecuted += EstimatePerVertexCost() * count;
return;
}
@ -788,7 +787,7 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) {
int bytesRead = 0;
drawEngine_.SubmitPrim(verts, inds, prim, count, vertexType, &bytesRead);
int vertexCost = drawEngine_.EstimatePerVertexCost() * count;
int vertexCost = EstimatePerVertexCost() * count;
gpuStats.vertexGPUCycles += vertexCost;
cyclesExecuted += vertexCost;

View File

@ -924,8 +924,7 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) {
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
drawEngine_.SetupVertexDecoder(gstate.vertType);
// Rough estimate, not sure what's correct.
int vertexCost = drawEngine_.EstimatePerVertexCost();
cyclesExecuted += vertexCost * count;
cyclesExecuted += EstimatePerVertexCost() * count;
return;
}
@ -953,7 +952,7 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) {
int bytesRead = 0;
drawEngine_.SubmitPrim(verts, inds, prim, count, gstate.vertType, &bytesRead);
int vertexCost = drawEngine_.EstimatePerVertexCost();
int vertexCost = EstimatePerVertexCost();
gpuStats.vertexGPUCycles += vertexCost * count;
cyclesExecuted += vertexCost * count;

View File

@ -88,6 +88,35 @@ void GPUCommon::Reinitialize() {
ScheduleEvent(GPU_EVENT_REINITIALIZE);
}
int GPUCommon::EstimatePerVertexCost() {
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
// runs in parallel with transform.
// Also, this is all pure guesswork. If we can find a way to do measurements, that would be great.
// GTA wants a low value to run smooth, GoW wants a high value (otherwise it thinks things
// went too fast and starts doing all the work over again).
int cost = 20;
if (gstate.isLightingEnabled()) {
cost += 10;
for (int i = 0; i < 4; i++) {
if (gstate.isLightChanEnabled(i))
cost += 10;
}
}
if (gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_COORDS) {
cost += 20;
}
int morphCount = gstate.getNumMorphWeights();
if (morphCount > 1) {
cost += 5 * morphCount;
}
return cost;
}
void GPUCommon::PopDLQueue() {
easy_guard guard(listLock);
if(!dlQueue.empty()) {

View File

@ -96,6 +96,8 @@ public:
void Execute_BoneMtxNum(u32 op, u32 diff);
void Execute_BoneMtxData(u32 op, u32 diff);
int EstimatePerVertexCost();
// Note: Not virtual!
inline void Flush();

View File

@ -283,40 +283,12 @@ void SoftGPU::FastRunLoop(DisplayList &list) {
}
}
int EstimatePerVertexCost() {
// TODO: This is transform cost, also account for rasterization cost somehow... although it probably
// runs in parallel with transform.
// Also, this is all pure guesswork. If we can find a way to do measurements, that would be great.
// GTA wants a low value to run smooth, GoW wants a high value (otherwise it thinks things
// went too fast and starts doing all the work over again).
int cost = 20;
if (gstate.isLightingEnabled()) {
cost += 10;
}
for (int i = 0; i < 4; i++) {
if (gstate.isLightChanEnabled(i))
cost += 10;
}
if (gstate.getUVGenMode() != GE_TEXMAP_TEXTURE_COORDS) {
cost += 20;
}
// TODO: morphcount
return cost;
}
void SoftGPU::ExecuteOp(u32 op, u32 diff)
{
void SoftGPU::ExecuteOp(u32 op, u32 diff) {
u32 cmd = op >> 24;
u32 data = op & 0xFFFFFF;
// Handle control and drawing commands here directly. The others we delegate.
switch (cmd)
{
switch (cmd) {
case GE_CMD_BASE:
break;

View File

@ -784,8 +784,7 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {
if (gstate_c.skipDrawReason & (SKIPDRAW_SKIPFRAME | SKIPDRAW_NON_DISPLAYED_FB)) {
drawEngine_.SetupVertexDecoder(gstate.vertType);
// Rough estimate, not sure what's correct.
int vertexCost = drawEngine_.EstimatePerVertexCost();
cyclesExecuted += vertexCost * count;
cyclesExecuted += EstimatePerVertexCost() * count;
return;
}
@ -813,7 +812,7 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {
int bytesRead = 0;
drawEngine_.SubmitPrim(verts, inds, prim, count, gstate.vertType, &bytesRead);
int vertexCost = drawEngine_.EstimatePerVertexCost();
int vertexCost = EstimatePerVertexCost();
gpuStats.vertexGPUCycles += vertexCost * count;
cyclesExecuted += vertexCost * count;