mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-11 08:39:28 +01:00
Merge pull request #8689 from unknownbrackets/bezier
Advance vertex/index pointers on bezier submit
This commit is contained in:
commit
9a11cfb7a3
9 files changed
+57
-56
No files matched your search
@@ -52,7 +52,7 @@ public:
|
||||
virtual void DispatchSubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) = 0;
|
||||
|
||||
void SubmitSpline(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType);
|
||||
void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType);
|
||||
void SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead);
|
||||
|
||||
std::vector<std::string> DebugGetVertexLoaderIDs();
|
||||
std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType);
|
||||
|
||||
@@ -874,16 +874,11 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
|
||||
}
|
||||
}
|
||||
|
||||
void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType) {
|
||||
void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indices, int tess_u, int tess_v, int count_u, int count_v, GEPatchPrimType prim_type, bool computeNormals, bool patchFacing, u32 vertType, int *bytesRead) {
|
||||
PROFILE_THIS_SCOPE("bezier");
|
||||
|
||||
DispatchFlush();
|
||||
|
||||
// Real hardware seems to draw nothing when given < 4 either U or V.
|
||||
// This would result in num_patches_u / num_patches_v being 0.
|
||||
if (count_u < 4 || count_v < 4)
|
||||
return;
|
||||
|
||||
u16 index_lower_bound = 0;
|
||||
u16 index_upper_bound = count_u * count_v - 1;
|
||||
bool indices_16bit = (vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT;
|
||||
@@ -894,6 +889,15 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
||||
if (indices)
|
||||
GetIndexBounds(indices, count_u*count_v, vertType, &index_lower_bound, &index_upper_bound);
|
||||
|
||||
VertexDecoder *origVDecoder = GetVertexDecoder((vertType & 0xFFFFFF) | (gstate.getUVGenMode() << 24));
|
||||
*bytesRead = count_u * count_v * origVDecoder->VertexSize();
|
||||
|
||||
// Real hardware seems to draw nothing when given < 4 either U or V.
|
||||
// This would result in num_patches_u / num_patches_v being 0.
|
||||
if (count_u < 4 || count_v < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Simplify away bones and morph before proceeding
|
||||
// There are normally not a lot of control points so just splitting decoded should be reasonably safe, although not great.
|
||||
SimpleVertex *simplified_control_points = (SimpleVertex *)(decoded + 65536 * 12);
|
||||
@@ -967,8 +971,8 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
||||
gstate_c.uv.vOff = 0;
|
||||
}
|
||||
|
||||
int bytesRead;
|
||||
DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeWithIndex16, &bytesRead);
|
||||
int generatedBytesRead;
|
||||
DispatchSubmitPrim(splineBuffer, quadIndices_, primType[prim_type], count, vertTypeWithIndex16, &generatedBytesRead);
|
||||
|
||||
DispatchFlush();
|
||||
|
||||
|
||||
@@ -776,7 +776,8 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) {
|
||||
|
||||
u32 data = op & 0xFFFFFF;
|
||||
u32 count = data & 0xFFFF;
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>(data >> 16);
|
||||
// Upper bits are ignored.
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>((data >> 16) & 7);
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
@@ -836,16 +837,7 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) {
|
||||
// After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed).
|
||||
// Some games rely on this, they don't bother reloading VADDR and IADDR.
|
||||
// The VADDR/IADDR registers are NOT updated.
|
||||
if (inds) {
|
||||
int indexSize = 1;
|
||||
if ((vertexType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((vertexType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
}
|
||||
AdvanceVerts(vertexType, count, bytesRead);
|
||||
}
|
||||
|
||||
void GPU_DX9::Execute_Bezier(u32 op, u32 diff) {
|
||||
@@ -883,7 +875,12 @@ void GPU_DX9::Execute_Bezier(u32 op, u32 diff) {
|
||||
int bz_vcount = (op >> 8) & 0xFF;
|
||||
bool computeNormals = gstate.isLightingEnabled();
|
||||
bool patchFacing = gstate.patchfacing & 1;
|
||||
drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType);
|
||||
int bytesRead = 0;
|
||||
drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead);
|
||||
|
||||
// After drawing, we advance pointers - see SubmitPrim which does the same.
|
||||
int count = bz_ucount * bz_vcount;
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
void GPU_DX9::Execute_Spline(u32 op, u32 diff) {
|
||||
|
||||
+9
-12
@@ -948,7 +948,8 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) {
|
||||
|
||||
u32 data = op & 0xFFFFFF;
|
||||
u32 count = data & 0xFFFF;
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>(data >> 16);
|
||||
// Upper bits are ignored.
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>((data >> 16) & 7);
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
@@ -1005,16 +1006,7 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) {
|
||||
// After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed).
|
||||
// Some games rely on this, they don't bother reloading VADDR and IADDR.
|
||||
// The VADDR/IADDR registers are NOT updated.
|
||||
if (inds) {
|
||||
int indexSize = 1;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
}
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
void GPU_GLES::Execute_VertexType(u32 op, u32 diff) {
|
||||
@@ -1076,7 +1068,12 @@ void GPU_GLES::Execute_Bezier(u32 op, u32 diff) {
|
||||
int bz_vcount = (op >> 8) & 0xFF;
|
||||
bool computeNormals = gstate.isLightingEnabled();
|
||||
bool patchFacing = gstate.patchfacing & 1;
|
||||
drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType);
|
||||
int bytesRead = 0;
|
||||
drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead);
|
||||
|
||||
// After drawing, we advance pointers - see SubmitPrim which does the same.
|
||||
int count = bz_ucount * bz_vcount;
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
void GPU_GLES::Execute_Spline(u32 op, u32 diff) {
|
||||
|
||||
@@ -1299,3 +1299,16 @@ void GPUCommon::SetCmdValue(u32 op) {
|
||||
gstate.cmdmem[cmd] = op;
|
||||
ExecuteOp(op, diff);
|
||||
}
|
||||
|
||||
void GPUCommon::AdvanceVerts(u32 vertType, int count, int bytesRead) {
|
||||
if ((vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) {
|
||||
int indexSize = 1;
|
||||
if ((vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
}
|
||||
}
|
||||
@@ -156,6 +156,8 @@ protected:
|
||||
virtual void FinishDeferred() {
|
||||
}
|
||||
|
||||
void AdvanceVerts(u32 vertType, int count, int bytesRead);
|
||||
|
||||
// Allows early unlocking with a guard. Do not double unlock.
|
||||
class easy_guard {
|
||||
public:
|
||||
|
||||
@@ -332,16 +332,7 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
||||
// After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed).
|
||||
// Some games rely on this, they don't bother reloading VADDR and IADDR.
|
||||
// The VADDR/IADDR registers are NOT updated.
|
||||
if (indices) {
|
||||
int indexSize = 1;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
}
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -822,7 +822,8 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {
|
||||
|
||||
u32 data = op & 0xFFFFFF;
|
||||
u32 count = data & 0xFFFF;
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>(data >> 16);
|
||||
// Upper bits are ignored.
|
||||
GEPrimitiveType prim = static_cast<GEPrimitiveType>((data >> 16) & 7);
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
@@ -880,16 +881,7 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) {
|
||||
// After drawing, we advance the vertexAddr (when non indexed) or indexAddr (when indexed).
|
||||
// Some games rely on this, they don't bother reloading VADDR and IADDR.
|
||||
// The VADDR/IADDR registers are NOT updated.
|
||||
if (inds) {
|
||||
int indexSize = 1;
|
||||
if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_16BIT)
|
||||
indexSize = 2;
|
||||
else if ((gstate.vertType & GE_VTYPE_IDX_MASK) == GE_VTYPE_IDX_32BIT)
|
||||
indexSize = 4;
|
||||
gstate_c.indexAddr += count * indexSize;
|
||||
} else {
|
||||
gstate_c.vertexAddr += bytesRead;
|
||||
}
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
void GPU_Vulkan::Execute_VertexType(u32 op, u32 diff) {
|
||||
@@ -933,7 +925,12 @@ void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) {
|
||||
int bz_vcount = (op >> 8) & 0xFF;
|
||||
bool computeNormals = gstate.isLightingEnabled();
|
||||
bool patchFacing = gstate.patchfacing & 1;
|
||||
drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType);
|
||||
int bytesRead = 0;
|
||||
drawEngine_.SubmitBezier(control_points, indices, gstate.getPatchDivisionU(), gstate.getPatchDivisionV(), bz_ucount, bz_vcount, patchPrim, computeNormals, patchFacing, gstate.vertType, &bytesRead);
|
||||
|
||||
// After drawing, we advance pointers - see SubmitPrim which does the same.
|
||||
int count = bz_ucount * bz_vcount;
|
||||
AdvanceVerts(gstate.vertType, count, bytesRead);
|
||||
}
|
||||
|
||||
void GPU_Vulkan::Execute_Spline(u32 op, u32 diff) {
|
||||
|
||||
@@ -152,7 +152,7 @@ static void ExpandRectangles(std::vector<GPUDebugVertex> &vertices, std::vector<
|
||||
}
|
||||
|
||||
void CGEDebugger::UpdatePrimPreview(u32 op) {
|
||||
const u32 prim_type = (op >> 16) & 0xFF;
|
||||
const u32 prim_type = (op >> 16) & 0x7;
|
||||
int count = op & 0xFFFF;
|
||||
if (prim_type >= 7) {
|
||||
ERROR_LOG(COMMON, "Unsupported prim type: %x", op);
|
||||
|
||||
Reference in new issue
Block a user