[spline/bezier]Unify hardware tessellation of bezier and spline.

This commit is contained in:
xebra 2018-07-13 18:35:44 +09:00
parent 3c0fb44f2e
commit a48a5b32f0
11 changed files with 153 additions and 187 deletions

View file

@ -741,7 +741,7 @@ void DrawEngineCommon::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim,
}
}
void DrawEngineCommon::TessellationDataTransfer::CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType) {
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;

View file

@ -53,6 +53,12 @@ inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) {
struct SimpleVertex;
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, u32 vertType, const Weight2D &weights) = 0;
};
class DrawEngineCommon {
public:
DrawEngineCommon();
@ -173,12 +179,5 @@ protected:
// Hardware tessellation
int numPatches;
class TessellationDataTransfer {
public:
virtual ~TessellationDataTransfer() {}
void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType);
// Send spline/bezier's control points to vertex shader through floating point texture.
virtual void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) = 0;
};
TessellationDataTransfer *tessDataTransfer;
};

View file

@ -89,6 +89,10 @@ public:
u32 ToKey(int tess, int count, int type) {
return tess;
}
int CalcSize(int tess, int count) {
return tess + 1;
}
};
class Spline3DWeight {
@ -231,6 +235,10 @@ public:
void FromKey(u32 key, int &tess, int &count, int &type) {
tess = key & 0xFF; count = (key >> 8) & 0xFF; type = (key >> 16) & 0xFF;
}
int CalcSize(int tess, int count) {
return (count - 3) * tess + 1;
}
};
static WeightCache<Bezier3DWeight> bezierWeightsCache;
@ -248,28 +256,6 @@ bool CanUseHardwareTessellation(GEPatchPrimType prim) {
return false;
}
// Prepare mesh of one patch for "Instanced Tessellation".
static void TessellateSplinePatchHardware(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch) {
SimpleVertex *&vertices = (SimpleVertex*&)dest;
float inv_u = 1.0f / (float)spatch.tess_u;
float inv_v = 1.0f / (float)spatch.tess_v;
// Generating simple input vertices for the spline-computing vertex shader.
for (int tile_v = 0; tile_v < spatch.tess_v + 1; ++tile_v) {
for (int tile_u = 0; tile_u < spatch.tess_u + 1; ++tile_u) {
SimpleVertex &vert = vertices[tile_v * (spatch.tess_u + 1) + tile_u];
vert.pos.x = (float)tile_u;
vert.pos.y = (float)tile_v;
// For texcoord generation
vert.nrm.x = (float)tile_u * inv_u;
vert.nrm.y = (float)tile_v * inv_v;
}
}
BuildIndex(indices, count, spatch.tess_u, spatch.tess_v, spatch.primType);
}
// Tessellate single patch (4x4 control points)
template<typename T>
class Tessellator {
@ -309,29 +295,6 @@ public:
}
};
// Prepare mesh of one patch for "Instanced Tessellation".
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;
float inv_v = 1.0f / (float)tess_v;
// Generating simple input vertices for the bezier-computing vertex shader.
for (int tile_v = 0; tile_v < tess_v + 1; ++tile_v) {
for (int tile_u = 0; tile_u < tess_u + 1; ++tile_u) {
SimpleVertex &vert = vertices[tile_v * (tess_u + 1) + tile_u];
vert.pos.x = (float)tile_u;
vert.pos.y = (float)tile_v;
// For texcoord generation
vert.nrm.x = (float)tile_u * inv_u;
vert.nrm.y = (float)tile_v * inv_v;
}
}
BuildIndex(indices, count, tess_u, tess_v, primType);
}
class SimpleBufferManager {
private:
u8 *buf_;
@ -466,7 +429,8 @@ public:
};
template<class Patch, class Cache>
static void SoftwareTessellation(SimpleVertex *vertices, u16 *indices, int &count, const Patch &patch, int origVertType, const SimpleVertex *const *points, SimpleBufferManager &managedBuf, Cache &weightsCache) {
static void SoftwareTessellation(SimpleVertex *vertices, u16 *indices, int &count, const Patch &patch, u32 origVertType,
const SimpleVertex *const *points, SimpleBufferManager &managedBuf, Cache &weightsCache) {
u32 key_u = weightsCache.ToKey(patch.tess_u, patch.count_u, patch.type_u);
u32 key_v = weightsCache.ToKey(patch.tess_v, patch.count_v, patch.type_v);
Weight2D weights(weightsCache, key_u, key_v);
@ -475,8 +439,31 @@ static void SoftwareTessellation(SimpleVertex *vertices, u16 *indices, int &coun
surface.Tessellate(vertices, indices, count, origVertType);
}
// This maps GEPatchPrimType to GEPrimitiveType.
const GEPrimitiveType primType[] = { GE_PRIM_TRIANGLES, GE_PRIM_LINES, GE_PRIM_POINTS, GE_PRIM_POINTS };
template<class Patch, class Cache>
static void HardwareTessellation(SimpleVertex *vertices, u16 *indices, int &count, const Patch &patch, u32 origVertType,
const SimpleVertex *const *points, Cache &weightsCache, TessellationDataTransfer *tessDataTransfer) {
u32 key_u = weightsCache.ToKey(patch.tess_u, patch.count_u, patch.type_u);
u32 key_v = weightsCache.ToKey(patch.tess_v, patch.count_v, patch.type_v);
Weight2D weights(weightsCache, key_u, key_v);
weights.size_u = weightsCache.CalcSize(patch.tess_u, patch.count_u);
weights.size_v = weightsCache.CalcSize(patch.tess_v, patch.count_v);
tessDataTransfer->SendDataToShader(points, patch.count_u * patch.count_v, origVertType, weights);
// Generating simple input vertices for the spline-computing vertex shader.
float inv_u = 1.0f / (float)patch.tess_u;
float inv_v = 1.0f / (float)patch.tess_v;
for (int tile_v = 0; tile_v <= patch.tess_v; ++tile_v) {
for (int tile_u = 0; tile_u <= patch.tess_u; ++tile_u) {
SimpleVertex &vert = vertices[tile_v * (patch.tess_u + 1) + tile_u];
vert.pos.x = (float)tile_u;
vert.pos.y = (float)tile_v;
// For texcoord generation
vert.nrm.x = (float)tile_u * inv_u;
vert.nrm.y = (float)tile_v * inv_v;
}
}
BuildIndex(indices, count, patch.tess_u, patch.tess_v, patch.primType);
}
void DrawEngineCommon::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) {
PROFILE_THIS_SCOPE("spline");
@ -536,14 +523,8 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
patch.patchFacing = patchFacing;
if (CanUseHardwareTessellation(prim_type)) {
const u32 key_u = splineWeightsCache.ToKey(tess_u, count_u, type_u);
const u32 key_v = splineWeightsCache.ToKey(tess_v, count_v, type_v);
Weight2D weights(splineWeightsCache, key_u, key_v);
weights.size_u = (count_u - 3) * tess_u + 1;
weights.size_v = (count_v - 3) * tess_v + 1;
tessDataTransfer->SendDataToShader(points, count_u * count_v, origVertType, weights);
TessellateSplinePatchHardware(dest, quadIndices_, count, patch);
numPatches = (count_u - 3) * (count_v - 3);
HardwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, splineWeightsCache, tessDataTransfer);
numPatches = patch.num_patches_u * patch.num_patches_v;
} else {
patch.Init(SPLINE_BUFFER_SIZE / vertexSize);
SoftwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, managedBuf, splineWeightsCache);
@ -621,27 +602,20 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
u8 *dest = splineBuffer;
u16 *inds = quadIndices_;
// Bezier patches share less control points than spline patches. Otherwise they are pretty much the same (except bezier don't support the open/close thing)
int num_patches_u = (count_u - 1) / 3;
int num_patches_v = (count_v - 1) / 3;
if (CanUseHardwareTessellation(prim_type)) {
Weight2D weights(bezierWeightsCache, tess_u, tess_v);
weights.size_u = tess_u + 1;
weights.size_v = tess_v + 1;
tessDataTransfer->SendDataToShader(points, count_u * count_v, origVertType, weights);
TessellateBezierPatchHardware(dest, inds, count, tess_u, tess_v, prim_type);
numPatches = num_patches_u * num_patches_v;
} else {
BezierPatch patch;
patch.tess_u = tess_u;
patch.tess_v = tess_v;
patch.count_u = count_u;
patch.count_v = count_v;
patch.num_patches_u = (count_u - 1) / 3;
patch.num_patches_v = (count_v - 1) / 3;
patch.primType = prim_type;
patch.patchFacing = patchFacing;
BezierPatch patch;
patch.tess_u = tess_u;
patch.tess_v = tess_v;
patch.count_u = count_u;
patch.count_v = count_v;
patch.num_patches_u = (count_u - 1) / 3;
patch.num_patches_v = (count_v - 1) / 3;
patch.primType = prim_type;
patch.patchFacing = patchFacing;
if (CanUseHardwareTessellation(prim_type)) {
HardwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, bezierWeightsCache, tessDataTransfer);
numPatches = patch.num_patches_u * patch.num_patches_v;
} else {
patch.Init(SPLINE_BUFFER_SIZE / vertexSize);
SoftwareTessellation((SimpleVertex *)splineBuffer, quadIndices_, count, patch, origVertType, points, managedBuf, bezierWeightsCache);
}

View file

@ -111,7 +111,8 @@ void DrawEngineD3D11::InitDeviceObjects() {
pushVerts_ = new PushBufferD3D11(device_, VERTEX_PUSH_SIZE, D3D11_BIND_VERTEX_BUFFER);
pushInds_ = new PushBufferD3D11(device_, INDEX_PUSH_SIZE, D3D11_BIND_INDEX_BUFFER);
tessDataTransfer = new TessellationDataTransferD3D11(context_, device_);
tessDataTransferD3D11 = new TessellationDataTransferD3D11(context_, device_);
tessDataTransfer = tessDataTransferD3D11;
}
void DrawEngineD3D11::ClearTrackedVertexArrays() {
@ -137,7 +138,7 @@ void DrawEngineD3D11::Resized() {
void DrawEngineD3D11::DestroyDeviceObjects() {
ClearTrackedVertexArrays();
ClearInputLayoutMap();
delete tessDataTransfer;
delete tessDataTransferD3D11;
delete pushVerts_;
delete pushInds_;
depthStencilCache_.Iterate([&](const uint64_t &key, ID3D11DepthStencilState *ds) {
@ -692,7 +693,22 @@ rotateVBO:
GPUDebug::NotifyDraw();
}
void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
TessellationDataTransferD3D11::TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device)
: context_(context), device_(device) {
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
}
TessellationDataTransferD3D11::~TessellationDataTransferD3D11() {
for (int i = 0; i < 3; ++i) {
if (buf[i]) buf[i]->Release();
if (view[i]) view[i]->Release();
}
}
void TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
struct TessData {
float pos[3]; float pad1;
float uv[2]; float pad2[2];
@ -701,13 +717,11 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const Simp
if (prevSize < size) {
prevSize = size;
if (buf[0]) {
buf[0]->Release();
view[0]->Release();
}
if (buf[0]) buf[0]->Release();
if (view[0]) view[0]->Release();
desc.ByteWidth = size * sizeof(TessData);
desc.StructureByteStride = sizeof(TessData);
device_->CreateBuffer(&desc, nullptr, &buf[0]);
device_->CreateShaderResourceView(buf[0], nullptr, &view[0]);
context_->VSSetShaderResources(0, 1, &view[0]);
@ -727,17 +741,14 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const Simp
context_->Unmap(buf[0], 0);
// Weights U
if (prevSizeWeights[0] < weights.size_u) {
prevSizeWeights[0] = weights.size_u;
if (buf[1]) {
buf[1]->Release();
view[1]->Release();
}
if (prevSizeWU < weights.size_u) {
prevSizeWU = weights.size_u;
if (buf[1]) buf[1]->Release();
if (view[1]) view[1]->Release();
desc.ByteWidth = weights.size_u * sizeof(Weight);
desc.StructureByteStride = sizeof(Weight);
device_->CreateBuffer(&desc, nullptr, &buf[1]);
device_->CreateShaderResourceView(buf[1], nullptr, &view[1]);
context_->VSSetShaderResources(1, 1, &view[1]);
@ -747,15 +758,13 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const Simp
context_->Unmap(buf[1], 0);
// Weights V
if (prevSizeWeights[1] < weights.size_v) {
prevSizeWeights[1] = weights.size_v;
if (buf[2]) {
buf[2]->Release();
view[2]->Release();
}
if (prevSizeWV < weights.size_v) {
prevSizeWV = weights.size_v;
if (buf[2]) buf[2]->Release();
if (view[2]) view[2]->Release();
desc.ByteWidth = weights.size_v * sizeof(Weight);
desc.StructureByteStride = sizeof(Weight);
device_->CreateBuffer(&desc, nullptr, &buf[2]);
device_->CreateShaderResourceView(buf[2], nullptr, &view[2]);
context_->VSSetShaderResources(2, 1, &view[2]);

View file

@ -99,6 +99,22 @@ public:
u8 flags;
};
class TessellationDataTransferD3D11 : public TessellationDataTransfer {
private:
ID3D11DeviceContext *context_;
ID3D11Device *device_;
ID3D11Buffer *buf[3]{};
ID3D11ShaderResourceView *view[3]{};
D3D11_BUFFER_DESC desc{};
int prevSize = 0;
int prevSizeWU = 0, prevSizeWV = 0;
public:
TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device);
~TessellationDataTransferD3D11();
// Send spline/bezier's control points and weights to vertex shader through structured shader buffer.
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
};
// Handles transform, lighting and drawing.
class DrawEngineD3D11 : public DrawEngineCommon {
public:
@ -199,32 +215,5 @@ private:
D3D11DynamicState dynState_{};
// Hardware tessellation
class TessellationDataTransferD3D11 : public TessellationDataTransfer {
private:
ID3D11DeviceContext *context_;
ID3D11Device *device_;
ID3D11Buffer *buf[3];
ID3D11ShaderResourceView *view[3];
D3D11_BUFFER_DESC desc;
int prevSize = 0;
int prevSizeWeights[2] = {};
public:
TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device)
: TessellationDataTransfer(), context_(context), device_(device), buf(), view(), desc() {
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
}
~TessellationDataTransferD3D11() {
for (int i = 0; i < 3; ++i) {
if (buf[i]) {
buf[i]->Release();
view[i]->Release();
}
}
}
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
};
TessellationDataTransferD3D11 *tessDataTransferD3D11;
};

View file

@ -101,7 +101,8 @@ DrawEngineDX9::DrawEngineDX9(Draw::DrawContext *draw) : vai_(256), vertexDeclMap
InitDeviceObjects();
tessDataTransfer = new TessellationDataTransferDX9();
tessDataTransferDX9 = new TessellationDataTransferDX9();
tessDataTransfer = tessDataTransferDX9;
device_->CreateVertexDeclaration(TransformedVertexElements, &transformedVertexDecl_);
}
@ -121,7 +122,7 @@ DrawEngineDX9::~DrawEngineDX9() {
}
});
vertexDeclMap_.Clear();
delete tessDataTransfer;
delete tessDataTransferDX9;
}
void DrawEngineDX9::InitDeviceObjects() {
@ -624,7 +625,8 @@ rotateVBO:
GPUDebug::NotifyDraw();
}
void DrawEngineDX9::TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
void TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
// TODO
}
} // namespace

View file

@ -97,6 +97,13 @@ public:
u8 flags;
};
class TessellationDataTransferDX9 : public TessellationDataTransfer {
public:
TessellationDataTransferDX9() {}
~TessellationDataTransferDX9() {}
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
};
// Handles transform, lighting and drawing.
class DrawEngineDX9 : public DrawEngineCommon {
public:
@ -158,16 +165,7 @@ private:
FramebufferManagerDX9 *framebufferManager_ = nullptr;
// Hardware tessellation
class TessellationDataTransferDX9 : public TessellationDataTransfer {
private:
int data_tex[3];
public:
TessellationDataTransferDX9() : TessellationDataTransfer(), data_tex() {
}
~TessellationDataTransferDX9() {
}
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
};
TessellationDataTransferDX9 *tessDataTransferDX9;
};
} // namespace

View file

@ -97,7 +97,7 @@ DrawEngineGLES::~DrawEngineGLES() {
FreeMemoryPages(decIndex, DECODED_INDEX_BUFFER_SIZE);
FreeMemoryPages(splineBuffer, SPLINE_BUFFER_SIZE);
delete tessDataTransfer;
delete tessDataTransferGLES;
}
void DrawEngineGLES::DeviceLost() {
@ -656,7 +656,7 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const {
return decJitCache_->IsInSpace(ptr);
}
void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
void TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
int sizeColor = hasColor ? size : 1;
@ -703,7 +703,7 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const Simple
}
void DrawEngineGLES::TessellationDataTransferGLES::EndFrame() {
void TessellationDataTransferGLES::EndFrame() {
for (int i = 0; i < 3; i++) {
if (data_tex[i]) {
renderManager_->DeleteTexture(data_tex[i]);

View file

@ -110,6 +110,21 @@ public:
u8 flags;
};
class TessellationDataTransferGLES : public TessellationDataTransfer {
private:
GLRTexture *data_tex[3]{};
GLRenderManager *renderManager_;
public:
TessellationDataTransferGLES(GLRenderManager *renderManager)
: renderManager_(renderManager) { }
~TessellationDataTransferGLES() {
EndFrame();
}
// Send spline/bezier's control points and weights to vertex shader through floating point texture.
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
void EndFrame(); // Queues textures for deletion.
};
// Handles transform, lighting and drawing.
class DrawEngineGLES : public DrawEngineCommon {
public:
@ -208,18 +223,5 @@ private:
int bufferDecimationCounter_ = 0;
// Hardware tessellation
class TessellationDataTransferGLES : public TessellationDataTransfer {
private:
GLRTexture *data_tex[3]{};
GLRenderManager *renderManager_;
public:
TessellationDataTransferGLES(GLRenderManager *renderManager)
: renderManager_(renderManager) { }
~TessellationDataTransferGLES() {
EndFrame();
}
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
void EndFrame(); // Queues textures for deletion.
};
TessellationDataTransferGLES *tessDataTransferGLES;
};

View file

@ -212,7 +212,7 @@ void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) {
}
void DrawEngineVulkan::DestroyDeviceObjects() {
delete tessDataTransfer;
delete tessDataTransferVulkan;
tessDataTransfer = tessDataTransferVulkan = nullptr;
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
@ -1014,14 +1014,7 @@ void DrawEngineVulkan::UpdateUBOs(FrameData *frame) {
}
}
DrawEngineVulkan::TessellationDataTransferVulkan::TessellationDataTransferVulkan(VulkanContext *vulkan)
: TessellationDataTransfer(), vulkan_(vulkan) {
}
DrawEngineVulkan::TessellationDataTransferVulkan::~TessellationDataTransferVulkan() {
}
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
// SSBOs that are not simply float1 or float2 need to be padded up to a float4 size. vec3 members
// also need to be 16-byte aligned, hence the padding.
struct TessData {

View file

@ -117,6 +117,20 @@ public:
class VulkanRenderManager;
class TessellationDataTransferVulkan : public TessellationDataTransfer {
public:
TessellationDataTransferVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {}
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
// Send spline/bezier's control points and weights to vertex shader through structured shader buffer.
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
private:
VulkanContext *vulkan_;
VulkanPushBuffer *push_; // Updated each frame.
VkDescriptorBufferInfo bufInfo_[3]{};
};
// Handles transform, lighting and drawing.
class DrawEngineVulkan : public DrawEngineCommon {
public:
@ -278,19 +292,5 @@ private:
int tessOffset_ = 0;
// Hardware tessellation
class TessellationDataTransferVulkan : public TessellationDataTransfer {
public:
TessellationDataTransferVulkan(VulkanContext *vulkan);
~TessellationDataTransferVulkan();
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
private:
VulkanContext *vulkan_;
VulkanPushBuffer *push_; // Updated each frame.
VkDescriptorBufferInfo bufInfo_[3] = {};
};
TessellationDataTransferVulkan *tessDataTransferVulkan;
};