mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
[spline/bezier]Improve the logic of copying control-points.
This commit is contained in:
parent
485260c937
commit
966ff32ee7
11 changed files with 74 additions and 71 deletions
|
@ -739,3 +739,27 @@ 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) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
memcpy(col, Vec4f::FromRGBA(points[0]->color_32).AsArray(), 4 * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ inline uint32_t GetVertTypeID(uint32_t vertType, int uvGenMode) {
|
|||
return (vertType & 0xFFFFFF) | (uvGenMode << 24);
|
||||
}
|
||||
|
||||
struct SimpleVertex;
|
||||
|
||||
class DrawEngineCommon {
|
||||
public:
|
||||
DrawEngineCommon();
|
||||
|
@ -177,13 +179,9 @@ protected:
|
|||
int prevSizeCol;
|
||||
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 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 SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) = 0;
|
||||
virtual void EndFrame() {}
|
||||
};
|
||||
TessellationDataTransfer *tessDataTransfer;
|
||||
|
|
|
@ -940,16 +940,7 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
|
|||
patch.patchFacing = patchFacing;
|
||||
|
||||
if (CanUseHardwareTessellation(prim_type)) {
|
||||
float *pos = (float*)managedBuf.Allocate(sizeof(float) * count_u * count_v * 4); // Size 4 float
|
||||
float *tex = (float*)managedBuf.Allocate(sizeof(float) * count_u * count_v * 4); // Size 4 float
|
||||
float *col = (float*)managedBuf.Allocate(sizeof(float) * count_u * count_v * 4); // Size 4 float
|
||||
const bool hasColor = (origVertType & GE_VTYPE_COL_MASK) != 0;
|
||||
const bool hasTexCoords = (origVertType & GE_VTYPE_TC_MASK) != 0;
|
||||
|
||||
int posStride, texStride, colStride;
|
||||
tessDataTransfer->PrepareBuffers(pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
|
||||
CopyControlPoints(points, pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
|
||||
tessDataTransfer->SendDataToShader(pos, tex, col, count_u * count_v, hasColor, hasTexCoords);
|
||||
tessDataTransfer->SendDataToShader(points, count_u * count_v, origVertType);
|
||||
TessellateSplinePatchHardware(dest, quadIndices_, count, patch);
|
||||
numPatches = (count_u - 3) * (count_v - 3);
|
||||
} else {
|
||||
|
@ -1033,16 +1024,7 @@ void DrawEngineCommon::SubmitBezier(const void *control_points, const void *indi
|
|||
int num_patches_u = (count_u - 1) / 3;
|
||||
int num_patches_v = (count_v - 1) / 3;
|
||||
if (CanUseHardwareTessellation(prim_type)) {
|
||||
float *pos = (float*)managedBuf.Allocate(sizeof(float) * count_u * count_v * 4); // Size 4 float
|
||||
float *tex = (float*)managedBuf.Allocate(sizeof(float) * count_u * count_v * 4); // Size 4 float
|
||||
float *col = (float*)managedBuf.Allocate(sizeof(float) * count_u * count_v * 4); // Size 4 float
|
||||
const bool hasColor = (origVertType & GE_VTYPE_COL_MASK) != 0;
|
||||
const bool hasTexCoords = (origVertType & GE_VTYPE_TC_MASK) != 0;
|
||||
|
||||
int posStride, texStride, colStride;
|
||||
tessDataTransfer->PrepareBuffers(pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
|
||||
CopyControlPoints(points, pos, tex, col, posStride, texStride, colStride, count_u * count_v, hasColor, hasTexCoords);
|
||||
tessDataTransfer->SendDataToShader(pos, tex, col, count_u * count_v, hasColor, hasTexCoords);
|
||||
tessDataTransfer->SendDataToShader(points, count_u * count_v, origVertType);
|
||||
TessellateBezierPatchHardware(dest, inds, count, tess_u, tess_v, prim_type);
|
||||
numPatches = num_patches_u * num_patches_v;
|
||||
} else {
|
||||
|
|
|
@ -692,7 +692,7 @@ rotateVBO:
|
|||
GPUDebug::NotifyDraw();
|
||||
}
|
||||
|
||||
void DrawEngineD3D11::TessellationDataTransferD3D11::PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) {
|
||||
void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) {
|
||||
struct TessData {
|
||||
float pos[3]; float pad1;
|
||||
float uv[2]; float pad2[2];
|
||||
|
@ -716,14 +716,14 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::PrepareBuffers(float *&pos,
|
|||
context_->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
|
||||
uint8_t *data = (uint8_t *)map.pData;
|
||||
|
||||
pos = (float *)(data);
|
||||
tex = (float *)(data + offsetof(TessData, uv));
|
||||
col = (float *)(data + offsetof(TessData, color));
|
||||
posStride = sizeof(TessData) / sizeof(float);
|
||||
colStride = hasColor ? (sizeof(TessData) / sizeof(float)) : 0;
|
||||
texStride = sizeof(TessData) / sizeof(float);
|
||||
}
|
||||
float *pos = (float *)(data);
|
||||
float *tex = (float *)(data + offsetof(TessData, uv));
|
||||
float *col = (float *)(data + offsetof(TessData, color));
|
||||
int stride = sizeof(TessData) / sizeof(float);
|
||||
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
|
||||
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
|
||||
|
||||
CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType);
|
||||
|
||||
void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const float * pos, const float * tex, const float * col, int size, bool hasColor, bool hasTexCoords) {
|
||||
context_->Unmap(buf, 0);
|
||||
}
|
||||
|
|
|
@ -221,7 +221,6 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) override;
|
||||
void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) override;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -624,8 +624,7 @@ rotateVBO:
|
|||
GPUDebug::NotifyDraw();
|
||||
}
|
||||
|
||||
void DrawEngineDX9::TessellationDataTransferDX9::SendDataToShader(const float * pos, const float * tex, const float * col, int size, bool hasColor, bool hasTexCoords)
|
||||
{
|
||||
void DrawEngineDX9::TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) {
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -166,7 +166,7 @@ private:
|
|||
}
|
||||
~TessellationDataTransferDX9() {
|
||||
}
|
||||
void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) override;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -655,37 +655,45 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const {
|
|||
return decJitCache_->IsInSpace(ptr);
|
||||
}
|
||||
|
||||
void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) {
|
||||
void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) {
|
||||
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
|
||||
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
|
||||
int sizeColor = hasColor ? size : 1;
|
||||
|
||||
float *pos = new float[size * 4];
|
||||
float *tex = nullptr;
|
||||
if (hasTexCoord)
|
||||
tex = new float[size * 4];
|
||||
float *col = new float[sizeColor * 4];
|
||||
int stride = 4;
|
||||
|
||||
CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType);
|
||||
|
||||
// Removed the 1D texture support, it's unlikely to be relevant for performance.
|
||||
|
||||
// Position
|
||||
if (data_tex[0])
|
||||
renderManager_->DeleteTexture(data_tex[0]);
|
||||
uint8_t *pos_data = new uint8_t[size * sizeof(float) * 4];
|
||||
memcpy(pos_data, pos, size * sizeof(float) * 4);
|
||||
data_tex[0] = renderManager_->CreateTexture(GL_TEXTURE_2D);
|
||||
renderManager_->TextureImage(data_tex[0], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, pos_data, GLRAllocType::NEW, false);
|
||||
renderManager_->TextureImage(data_tex[0], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, (u8 *)pos, GLRAllocType::NEW, false);
|
||||
renderManager_->FinalizeTexture(data_tex[0], 0, false);
|
||||
renderManager_->BindTexture(TEX_SLOT_SPLINE_POS, data_tex[0]);
|
||||
|
||||
// Texcoords
|
||||
if (hasTexCoords) {
|
||||
// Texcoord
|
||||
if (hasTexCoord) {
|
||||
if (data_tex[1])
|
||||
renderManager_->DeleteTexture(data_tex[1]);
|
||||
uint8_t *tex_data = new uint8_t[size * sizeof(float) * 4];
|
||||
memcpy(tex_data, tex, size * sizeof(float) * 4);
|
||||
data_tex[1] = renderManager_->CreateTexture(GL_TEXTURE_2D);
|
||||
renderManager_->TextureImage(data_tex[1], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, tex_data, GLRAllocType::NEW, false);
|
||||
renderManager_->TextureImage(data_tex[1], 0, size, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, (u8 *)tex, GLRAllocType::NEW, false);
|
||||
renderManager_->FinalizeTexture(data_tex[1], 0, false);
|
||||
renderManager_->BindTexture(TEX_SLOT_SPLINE_NRM, data_tex[1]);
|
||||
renderManager_->BindTexture(TEX_SLOT_SPLINE_TEX, data_tex[1]);
|
||||
}
|
||||
|
||||
// Color
|
||||
if (data_tex[2])
|
||||
renderManager_->DeleteTexture(data_tex[2]);
|
||||
data_tex[2] = renderManager_->CreateTexture(GL_TEXTURE_2D);
|
||||
int sizeColor = hasColor ? size : 1;
|
||||
uint8_t *col_data = new uint8_t[sizeColor * sizeof(float) * 4];
|
||||
memcpy(col_data, col, sizeColor * sizeof(float) * 4);
|
||||
|
||||
renderManager_->TextureImage(data_tex[2], 0, sizeColor, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, col_data, GLRAllocType::NEW, false);
|
||||
renderManager_->TextureImage(data_tex[2], 0, sizeColor, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT, (u8 *)col, GLRAllocType::NEW, false);
|
||||
renderManager_->FinalizeTexture(data_tex[2], 0, false);
|
||||
renderManager_->BindTexture(TEX_SLOT_SPLINE_COL, data_tex[2]);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ enum {
|
|||
TEX_SLOT_ALPHATEST = 2,
|
||||
TEX_SLOT_CLUT = 3,
|
||||
TEX_SLOT_SPLINE_POS = 4,
|
||||
TEX_SLOT_SPLINE_NRM = 5,
|
||||
TEX_SLOT_SPLINE_TEX = 5,
|
||||
TEX_SLOT_SPLINE_COL = 6,
|
||||
};
|
||||
|
||||
|
@ -218,7 +218,7 @@ private:
|
|||
~TessellationDataTransferGLES() {
|
||||
EndFrame();
|
||||
}
|
||||
void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) override;
|
||||
void EndFrame() override; // Queues textures for deletion.
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1001,9 +1001,7 @@ DrawEngineVulkan::TessellationDataTransferVulkan::TessellationDataTransferVulkan
|
|||
DrawEngineVulkan::TessellationDataTransferVulkan::~TessellationDataTransferVulkan() {
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&pos, float *&tex, float *&col, int &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) {
|
||||
colStride = 4;
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) {
|
||||
// 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 {
|
||||
|
@ -1016,14 +1014,10 @@ void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&po
|
|||
uint8_t *data = (uint8_t *)push_->PushAligned(size * sizeof(TessData), &offset_, &buf_, ssboAlignment);
|
||||
range_ = size * sizeof(TessData);
|
||||
|
||||
pos = (float *)(data);
|
||||
tex = (float *)(data + offsetof(TessData, uv));
|
||||
col = (float *)(data + offsetof(TessData, color));
|
||||
posStride = sizeof(TessData) / sizeof(float);
|
||||
colStride = hasColor ? (sizeof(TessData) / sizeof(float)) : 0;
|
||||
texStride = sizeof(TessData) / sizeof(float);
|
||||
}
|
||||
float *pos = (float *)(data);
|
||||
float *tex = (float *)(data + offsetof(TessData, uv));
|
||||
float *col = (float *)(data + offsetof(TessData, color));
|
||||
int stride = sizeof(TessData) / sizeof(float);
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) {
|
||||
// Nothing to do here! The caller will write directly to the pushbuffer through the pointers it got through PrepareBuffers.
|
||||
CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType);
|
||||
}
|
||||
|
|
|
@ -284,8 +284,7 @@ private:
|
|||
~TessellationDataTransferVulkan();
|
||||
|
||||
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 &posStride, int &texStride, int &colStride, int size, bool hasColor, bool hasTexCoords) override;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType) override;
|
||||
|
||||
void GetBufferAndOffset(VkBuffer *buf, VkDeviceSize *offset, VkDeviceSize *range) {
|
||||
*buf = buf_;
|
||||
|
|
Loading…
Add table
Reference in a new issue