Merge pull request #8689 from unknownbrackets/bezier

Advance vertex/index pointers on bezier submit
This commit is contained in:
Henrik Rydgård committed 2016-04-10 22:30:08 +02:00
commit 9a11cfb7a3
9 files changed
+57 -56

No files matched your search

+1 -1
View File
@@ -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);
+12 -8
View File
@@ -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();
+9 -12
View File
@@ -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
View File
@@ -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) {
+13
View File
@@ -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;
}
}
+2
View File
@@ -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:
+1 -10
View File
@@ -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;
+9 -12
View File
@@ -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) {
+1 -1
View File
@@ -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);