Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #9405 from xebra/cleanup_spline_bezier
Browse files Browse the repository at this point in the history
Fixed some bugs in spline/bezier.
  • Loading branch information
hrydgard committed Mar 9, 2017
2 parents ca85716 + 56f80ac commit c7cb368
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 24 deletions.
6 changes: 3 additions & 3 deletions GPU/Common/DrawEngineCommon.cpp
Expand Up @@ -407,7 +407,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
float bnrm[3], bpos[3];

if (vertType & GE_VTYPE_NRM_MASK) {
// Normals are generated during tesselation anyway, not sure if any need to supply
// Normals are generated during tessellation anyway, not sure if any need to supply
reader.ReadNrm(nrm);
} else {
nrm[0] = 0;
Expand Down Expand Up @@ -443,7 +443,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
if (vertType & GE_VTYPE_TC_MASK) {
reader.ReadUV(sv.uv);
} else {
sv.uv[0] = 0.0f; // This will get filled in during tesselation
sv.uv[0] = 0.0f; // This will get filled in during tessellation
sv.uv[1] = 0.0f;
}
if (vertType & GE_VTYPE_COL_MASK) {
Expand All @@ -452,7 +452,7 @@ u32 DrawEngineCommon::NormalizeVertices(u8 *outPtr, u8 *bufPtr, const u8 *inPtr,
memcpy(sv.color, defaultColor, 4);
}
if (vertType & GE_VTYPE_NRM_MASK) {
// Normals are generated during tesselation anyway, not sure if any need to supply
// Normals are generated during tessellation anyway, not sure if any need to supply
reader.ReadNrm((float *)&sv.nrm);
} else {
sv.nrm.x = 0.0f;
Expand Down
2 changes: 1 addition & 1 deletion GPU/Common/DrawEngineCommon.h
Expand Up @@ -32,7 +32,7 @@ enum {
VERTEX_BUFFER_MAX = 65536,
DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 64,
DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 16,
SPLINE_BUFFER_SIZE = VERTEX_BUFFER_MAX * 20,
SPLINE_BUFFER_SIZE = VERTEX_BUFFER_MAX * 26, // At least, this buffer needs greater than 1679616 bytes for Mist Dragon morphing in FF4CC.
};

class DrawEngineCommon {
Expand Down
35 changes: 17 additions & 18 deletions GPU/Common/SplineCommon.cpp
Expand Up @@ -354,7 +354,7 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp
spline_knot(spatch.count_u - 1, spatch.type_u, knot_u);
spline_knot(spatch.count_v - 1, spatch.type_v, knot_v);

// Increase tesselation based on the size. Should be approximately right?
// Increase tessellation based on the size. Should be approximately right?
int patch_div_s = (spatch.count_u - 3) * spatch.tess_u;
int patch_div_t = (spatch.count_v - 3) * spatch.tess_v;
if (quality > 1) {
Expand All @@ -367,7 +367,7 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp
}
}

// Downsample until it fits, in case crazy tesselation factors are sent.
// Downsample until it fits, in case crazy tessellation factors are sent.
while ((patch_div_s + 1) * (patch_div_t + 1) > maxVertices) {
patch_div_s /= 2;
patch_div_t /= 2;
Expand Down Expand Up @@ -543,7 +543,7 @@ static void SplinePatchFullQuality(u8 *&dest, u16 *indices, int &count, const Sp
}

GEPatchPrimType prim_type = spatch.primType;
// Tesselate.
// Tessellate.
for (int tile_v = 0; tile_v < patch_div_t; ++tile_v) {
for (int tile_u = 0; tile_u < patch_div_s; ++tile_u) {
int idx0 = tile_v * (patch_div_s + 1) + tile_u;
Expand Down Expand Up @@ -594,7 +594,7 @@ static void SplinePatchFullQualityDispatch(u8 *&dest, u16 *indices, int &count,
SplinePatchFullQualityDispatch2<false>(dest, indices, count, spatch, origVertType, quality, maxVertices);
}

void TesselateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertexCount) {
void TessellateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertexCount) {
switch (g_Config.iSplineBezierQuality) {
case LOW_QUALITY:
_SplinePatchLowQuality(dest, indices, count, spatch, origVertType);
Expand Down Expand Up @@ -694,15 +694,9 @@ struct PrecomputedCurves {
T *horiz4;
};

static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType, int maxVertices) {
static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) {
const float third = 1.0f / 3.0f;

// Downsample until it fits, in case crazy tesselation factors are sent.
while ((tess_u + 1) * (tess_v + 1) > maxVertices) {
tess_u /= 2;
tess_v /= 2;
}

// First compute all the vertices and put them in an array
SimpleVertex *&vertices = (SimpleVertex*&)dest;

Expand Down Expand Up @@ -803,7 +797,7 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
}

// Prepare mesh of one patch for "Instanced Tessellation".
static void TesselateBezierPatchHardware(u8 *&dest, u16 *indices, int &count, int tess_u, int tess_v, GEPatchPrimType primType) {
static void TessellateBezierPatchHardware(u8 *&dest, u16 *indices, int &count, int tess_u, int tess_v, GEPatchPrimType primType) {
SimpleVertex *&vertices = (SimpleVertex*&)dest;

float inv_u = 1.0f / (float)tess_u;
Expand Down Expand Up @@ -833,16 +827,16 @@ static void TesselateBezierPatchHardware(u8 *&dest, u16 *indices, int &count, in
}
}

void TesselateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType, int maxVertices) {
void TessellateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) {
switch (g_Config.iSplineBezierQuality) {
case LOW_QUALITY:
_BezierPatchLowQuality(dest, indices, count, tess_u, tess_v, patch, origVertType);
break;
case MEDIUM_QUALITY:
_BezierPatchHighQuality(dest, indices, count, tess_u / 2, tess_v / 2, patch, origVertType, maxVertices);
_BezierPatchHighQuality(dest, indices, count, tess_u / 2, tess_v / 2, patch, origVertType);
break;
case HIGH_QUALITY:
_BezierPatchHighQuality(dest, indices, count, tess_u, tess_v, patch, origVertType, maxVertices);
_BezierPatchHighQuality(dest, indices, count, tess_u, tess_v, patch, origVertType);
break;
}
}
Expand Down Expand Up @@ -953,7 +947,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
numPatches = (count_u - 3) * (count_v - 3);
} else {
int maxVertexCount = SPLINE_BUFFER_SIZE / vertexSize;
TesselateSplinePatch(dest, quadIndices_, count, patch, origVertType, maxVertexCount);
TessellateSplinePatch(dest, quadIndices_, count, patch, origVertType, maxVertexCount);
}
delete[] points;

Expand Down Expand Up @@ -1073,13 +1067,18 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
u16 *inds = quadIndices_;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
tessDataTransfer->SendDataToShader(pos, tex, col, count_u * count_v, hasColor, hasTexCoords);
TesselateBezierPatchHardware(dest, inds, count, tess_u, tess_v, prim_type);
TessellateBezierPatchHardware(dest, inds, count, tess_u, tess_v, prim_type);
numPatches = num_patches_u * num_patches_v;
} else {
int maxVertices = SPLINE_BUFFER_SIZE / vertexSize;
// Downsample until it fits, in case crazy tessellation factors are sent.
while ((tess_u + 1) * (tess_v + 1) * num_patches_u * num_patches_v > maxVertices) {
tess_u /= 2;
tess_v /= 2;
}
for (int patch_idx = 0; patch_idx < num_patches_u*num_patches_v; ++patch_idx) {
const BezierPatch &patch = patches[patch_idx];
TesselateBezierPatch(dest, inds, count, tess_u, tess_v, patch, origVertType, maxVertices);
TessellateBezierPatch(dest, inds, count, tess_u, tess_v, patch, origVertType);
}
delete[] patches;
}
Expand Down
4 changes: 2 additions & 2 deletions GPU/Common/SplineCommon.h
Expand Up @@ -65,5 +65,5 @@ enum SplineQuality {
HIGH_QUALITY = 2,
};

void TesselateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertices);
void TesselateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType, int maxVertices);
void TessellateSplinePatch(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType, int maxVertices);
void TessellateBezierPatch(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType, int maxVertices);

1 comment on commit c7cb368

@tausifj15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sir all builts which starts from 800 sucks in performancse

Please sign in to comment.