Permalink
Browse files

Make the interface to hw tess slightly more flexible.

  • Loading branch information...
hrydgard committed Nov 12, 2017
1 parent ebac014 commit da09e10aa37a09d43d90972178f87f81d4bc90a0
Showing with 47 additions and 16 deletions.
  1. +5 −1 GPU/Common/DrawEngineCommon.h
  2. +30 −13 GPU/Common/SplineCommon.cpp
  3. +11 −1 GPU/Vulkan/DrawEngineVulkan.cpp
  4. +1 −1 GPU/Vulkan/DrawEngineVulkan.h
@@ -162,8 +162,12 @@ class DrawEngineCommon {
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 PrepareBuffers(float *&pos, float *&tex, float *&col, int size, bool hasColor, bool hasTexCoords) {};
};
TessellationDataTransfer *tessDataTransfer;
};
@@ -908,13 +908,22 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
const bool hasColor = (origVertType & GE_VTYPE_COL_MASK) != 0;
const bool hasTexCoords = (origVertType & GE_VTYPE_TC_MASK) != 0;
tessDataTransfer->PrepareBuffers(pos, tex, col, count_u * count_v, hasColor, hasTexCoords);
int posStride, texStride, colStride;
tessDataTransfer->PrepareBuffers(pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
float *p = pos;
float *t = tex;
float *c = col;
for (int idx = 0; idx < count_u * count_v; idx++) {
memcpy(pos + idx * 4, points[idx]->pos.AsArray(), 3 * sizeof(float));
if (hasTexCoords)
memcpy(tex + idx * 4, points[idx]->uv, 2 * sizeof(float));
if (hasColor)
memcpy(col + idx * 4, Vec4f::FromRGBA(points[idx]->color_32).AsArray(), 4 * sizeof(float));
memcpy(p, points[idx]->pos.AsArray(), 3 * sizeof(float));
p += posStride;
if (hasTexCoords) {
memcpy(t, points[idx]->uv, 2 * sizeof(float));
t += texStride;
}
if (hasColor) {
memcpy(c, Vec4f::FromRGBA(points[idx]->color_32).AsArray(), 4 * sizeof(float));
c += colStride;
}
}
if (!hasColor)
memcpy(col, Vec4f::FromRGBA(points[0]->color_32).AsArray(), 4 * sizeof(float));
@@ -985,7 +994,6 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
ERROR_LOG(G3D, "Something went really wrong, vertex size: %i vs %i", vertexSize, (int)sizeof(SimpleVertex));
}
float *pos = (float*)(decoded + 65536 * 18); // Size 4 float
float *tex = pos + count_u * count_v * 4; // Size 4 float
float *col = tex + count_u * count_v * 4; // Size 4 float
@@ -997,14 +1005,23 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
int num_patches_v = (count_v - 1) / 3;
BezierPatch *patches = nullptr;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
tessDataTransfer->PrepareBuffers(pos, tex, col, count_u * count_v, hasColor, hasTexCoords);
int posStride, texStride, colStride;
tessDataTransfer->PrepareBuffers(pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
float *p = pos;
float *t = tex;
float *c = col;
for (int idx = 0; idx < count_u * count_v; idx++) {
SimpleVertex *point = simplified_control_points + (indices ? idxConv.convert(idx) : idx);
memcpy(pos + idx * 4, point->pos.AsArray(), 3 * sizeof(float));
if (hasTexCoords)
memcpy(tex + idx * 4, point->uv, 2 * sizeof(float));
if (hasColor)
memcpy(col + idx * 4, Vec4f::FromRGBA(point->color_32).AsArray(), 4 * sizeof(float));
memcpy(p, point->pos.AsArray(), 3 * sizeof(float));
p += posStride;
if (hasTexCoords) {
memcpy(t, point->uv, 2 * sizeof(float));
t += texStride;
}
if (hasColor) {
memcpy(c, Vec4f::FromRGBA(point->color_32).AsArray(), 4 * sizeof(float));
c += colStride;
}
}
if (!hasColor) {
SimpleVertex *point = simplified_control_points + (indices ? idxConv.convert(0) : 0);
@@ -1111,7 +1111,9 @@ DrawEngineVulkan::TessellationDataTransferVulkan::~TessellationDataTransferVulka
// TODO: Consolidate the three textures into one, with height 3.
// This can be done for all the backends.
// TODO: Actually, even better, avoid the usage of textures altogether and just use shader storage buffers from the current pushbuffer.
void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&pos, float *&tex, float *&col, int size, bool hasColor, bool hasTexCoords) {
void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) {
colStride = 4;
assert(size > 0);
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
@@ -1122,6 +1124,7 @@ void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&po
assert(success);
pos = (float *)push_->Push(size * sizeof(float) * 4, &posOffset_, &posBuf_);
posStride = 4;
posSize_ = size;
// Texcoords
@@ -1132,15 +1135,22 @@ void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&po
assert(success);
tex = (float *)push_->Push(size * sizeof(float) * 4, &texOffset_, &texBuf_);
texStride = 4;
texSize_ = size;
} else {
data_tex[1] = nullptr;
tex = nullptr;
texStride = 0;
texSize_ = 0;
}
// Color
colSize_ = hasColor ? size : 1;
if (colSize_ == 1)
colStride = 0;
else
colStride = 4;
delete data_tex[2];
data_tex[2] = new VulkanTexture(vulkan_, &tessAlloc_);
success = data_tex[2]->CreateDirect(cmd, colSize_, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
@@ -270,7 +270,7 @@ class DrawEngineVulkan : public DrawEngineCommon {
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override;
void PrepareBuffers(float *&pos, float *&tex, float *&col, int size, bool hasColor, bool hasTexCoords) override;
void PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) override;
VulkanTexture *GetTexture(int i) const { return data_tex[i]; }

0 comments on commit da09e10

Please sign in to comment.