Skip to content
Permalink
Browse files

Merge pull request #11425 from xebra/refactor_spline_bezier

[Refactoring] Improve spline/bezier.
  • Loading branch information...
hrydgard committed Nov 4, 2018
2 parents 886a1e0 + 0d7a5cd commit 22c066515efc9ffede6f06d964dcb41c1b772981
@@ -34,7 +34,6 @@ enum {
};

DrawEngineCommon::DrawEngineCommon() : decoderMap_(16) {
quadIndices_ = new u16[6 * QUAD_INDICES_MAX];
decJitCache_ = new VertexDecoderJitCache();
transformed = (TransformedVertex *)AllocateMemoryPages(TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
transformedExpanded = (TransformedVertex *)AllocateMemoryPages(3 * TRANSFORMED_VERTEX_BUFFER_SIZE, MEM_PROT_READ | MEM_PROT_WRITE);
@@ -43,11 +42,11 @@ DrawEngineCommon::DrawEngineCommon() : decoderMap_(16) {
DrawEngineCommon::~DrawEngineCommon() {
FreeMemoryPages(transformed, TRANSFORMED_VERTEX_BUFFER_SIZE);
FreeMemoryPages(transformedExpanded, 3 * TRANSFORMED_VERTEX_BUFFER_SIZE);
delete[] quadIndices_;
delete decJitCache_;
decoderMap_.Iterate([&](const uint32_t vtype, VertexDecoder *decoder) {
delete decoder;
});
ClearSplineBezierWeights();
}

VertexDecoder *DrawEngineCommon::GetVertexDecoder(u32 vtype) {
@@ -739,3 +738,25 @@ void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim,
}
}
}

void TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) {
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;

for (int i = 0; i < size; ++i) {
memcpy(pos, points[i]->pos.AsArray(), 3 * sizeof(float));
pos += posStride;
}
if (hasTexCoord) {
for (int i = 0; i < size; ++i) {
memcpy(tex, points[i]->uv, 2 * sizeof(float));
tex += texStride;
}
}
if (hasColor) {
for (int i = 0; i < size; ++i) {
memcpy(col, Vec4f::FromRGBA(points[i]->color_32).AsArray(), 4 * sizeof(float));
col += colStride;
}
}
}
@@ -34,7 +34,6 @@ 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 * 26, // At least, this buffer needs greater than 1679616 bytes for Mist Dragon morphing in FF4CC.
};

// Avoiding the full include of TextureDecoder.h.
@@ -50,6 +49,15 @@ inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) {
return (vertType & 0xFFFFFF) | (uvGenMode << 24);
}

struct SimpleVertex;
namespace Spline { struct Weight2D; }

class TessellationDataTransfer {
public:
void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType);
virtual void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) = 0;
};

class DrawEngineCommon {
public:
DrawEngineCommon();
@@ -75,6 +83,7 @@ class DrawEngineCommon {
void SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertTypeID, int cullMode, int *bytesRead);
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, int *bytesRead);
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);
void ClearSplineBezierWeights();

std::vector<std::string> DebugGetVertexLoaderIDs();
std::string DebugGetVertexLoaderString(std::string id, DebugShaderStringType stringType);
@@ -160,31 +169,10 @@ class DrawEngineCommon {
int decodedVerts_ = 0;
GEPrimitiveType prevPrim_ = GE_PRIM_INVALID;

// Fixed index buffer for easy quad generation from spline/bezier
u16 *quadIndices_ = nullptr;

// Shader blending state
bool fboTexNeedBind_ = false;
bool fboTexBound_ = false;

// Hardware tessellation
int numPatches;
class TessellationDataTransfer {
protected:
// TODO: These aren't used by all backends.
int prevSize;
int prevSizeTex;
int prevSizeCol;
public:
virtual ~TessellationDataTransfer() {}
// Send spline/bezier's control points to vertex shader through floating point texture.
virtual void PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) {
posStride = 4;
texStride = 4;
colStride = 4;
}
virtual void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) = 0;
virtual void EndFrame() {}
};
TessellationDataTransfer *tessDataTransfer;
};
@@ -53,6 +53,7 @@ std::string VertexShaderDesc(const ShaderID &id) {
if (id.Bit(VS_BIT_SPLINE)) desc << "Spline ";
if (id.Bit(VS_BIT_HAS_COLOR_TESS)) desc << "TessC ";
if (id.Bit(VS_BIT_HAS_TEXCOORD_TESS)) desc << "TessT ";
if (id.Bit(VS_BIT_HAS_NORMAL_TESS)) desc << "TessN ";
if (id.Bit(VS_BIT_NORM_REVERSE_TESS)) desc << "TessRevN ";

return desc.str();
@@ -73,6 +74,7 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform)
bool doSpline = gstate_c.spline;
bool hasColorTess = (gstate.vertType & GE_VTYPE_COL_MASK) != 0 && (doBezier || doSpline);
bool hasTexcoordTess = (gstate.vertType & GE_VTYPE_TC_MASK) != 0 && (doBezier || doSpline);
bool hasNormalTess = (gstate.vertType & GE_VTYPE_NRM_MASK) != 0 && (doBezier || doSpline);

bool enableFog = gstate.isFogEnabled() && !isModeThrough && !gstate.isModeClear();
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !isModeThrough;
@@ -139,6 +141,7 @@ void ComputeVertexShaderID(ShaderID *id_out, u32 vertType, bool useHWTransform)
id.SetBit(VS_BIT_SPLINE, doSpline);
id.SetBit(VS_BIT_HAS_COLOR_TESS, hasColorTess);
id.SetBit(VS_BIT_HAS_TEXCOORD_TESS, hasTexcoordTess);
id.SetBit(VS_BIT_HAS_NORMAL_TESS, hasNormalTess);
id.SetBit(VS_BIT_NORM_REVERSE_TESS, gstate.isPatchNormalsReversed());
}
}
@@ -24,7 +24,7 @@ enum {
VS_BIT_HAS_COLOR_TESS = 12, // 1 bit
VS_BIT_HAS_TEXCOORD_TESS = 13, // 1 bit
VS_BIT_NORM_REVERSE_TESS = 14, // 1 bit
// 15 is free.
VS_BIT_HAS_NORMAL_TESS = 15, // 1 bit
VS_BIT_UVGEN_MODE = 16,
VS_BIT_UVPROJ_MODE = 18, // 2, can overlap with LS0
VS_BIT_LS0 = 18, // 2
@@ -240,7 +240,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
}

if (dirtyUniforms & DIRTY_BEZIERSPLINE) {
ub->spline_counts = BytesToUint32(gstate_c.spline_count_u, gstate_c.spline_count_v, gstate_c.spline_type_u, gstate_c.spline_type_v);
ub->spline_counts = gstate_c.spline_num_points_u;
}

if (dirtyUniforms & DIRTY_DEPAL) {
Oops, something went wrong.

1 comment on commit 22c0665

@ThePhoenixRises

This comment has been minimized.

Copy link

ThePhoenixRises commented on 22c0665 Nov 4, 2018

I am seeing improvements in Dirt 2, the dark glitches are nearly all gone, just a few tiny ones behind the cars now, and not right across the screen, any more.
Well done guys.

Please sign in to comment.
You can’t perform that action at this time.