mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
[spline/bezier]Fix GLES texture resolution of HW tess to real 2D to avoid huge width in FF4CC mist dragon morphing.
This commit is contained in:
parent
89786b943d
commit
41823f8780
11 changed files with 31 additions and 24 deletions
|
@ -56,7 +56,7 @@ 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;
|
||||
virtual void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) = 0;
|
||||
};
|
||||
|
||||
class DrawEngineCommon {
|
||||
|
|
|
@ -462,7 +462,7 @@ static void HardwareTessellation(OutputBuffers &output, const Patch &patch, u32
|
|||
Weight2D weights(WeightType::weightsCache, key_u, key_v);
|
||||
weights.size_u = WeightType::CalcSize(patch.tess_u, patch.count_u);
|
||||
weights.size_v = WeightType::CalcSize(patch.tess_v, patch.count_v);
|
||||
tessDataTransfer->SendDataToShader(points, patch.count_u * patch.count_v, origVertType, weights);
|
||||
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;
|
||||
|
|
|
@ -702,13 +702,15 @@ TessellationDataTransferD3D11::~TessellationDataTransferD3D11() {
|
|||
}
|
||||
}
|
||||
|
||||
void TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
|
||||
void TessellationDataTransferD3D11::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) {
|
||||
struct TessData {
|
||||
float pos[3]; float pad1;
|
||||
float uv[2]; float pad2[2];
|
||||
float color[4];
|
||||
};
|
||||
|
||||
int size = size_u * size_v;
|
||||
|
||||
if (prevSize < size) {
|
||||
prevSize = size;
|
||||
if (buf[0]) buf[0]->Release();
|
||||
|
|
|
@ -112,7 +112,7 @@ 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;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) override;
|
||||
};
|
||||
|
||||
// Handles transform, lighting and drawing.
|
||||
|
|
|
@ -625,7 +625,7 @@ rotateVBO:
|
|||
GPUDebug::NotifyDraw();
|
||||
}
|
||||
|
||||
void TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
|
||||
void TessellationDataTransferDX9::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ class TessellationDataTransferDX9 : public TessellationDataTransfer {
|
|||
public:
|
||||
TessellationDataTransferDX9() {}
|
||||
~TessellationDataTransferDX9() {}
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) override;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) override;
|
||||
};
|
||||
|
||||
// Handles transform, lighting and drawing.
|
||||
|
|
|
@ -653,35 +653,36 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const {
|
|||
return decJitCache_->IsInSpace(ptr);
|
||||
}
|
||||
|
||||
void TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
|
||||
void TessellationDataTransferGLES::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) {
|
||||
bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
|
||||
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
|
||||
|
||||
int size = size_u * size_v;
|
||||
float *pos = new float[size * 4];
|
||||
float *tex = hasTexCoord ? new float[size * 4] : nullptr;
|
||||
float *col = hasColor ? new float[size * 4] : nullptr;
|
||||
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.
|
||||
// Control Points
|
||||
if (prevSize < size) {
|
||||
prevSize = size;
|
||||
if (prevSizeU < size_u || prevSizeV < size_v) {
|
||||
prevSizeU = size_u;
|
||||
prevSizeV = size_v;
|
||||
if (!data_tex[0])
|
||||
data_tex[0] = renderManager_->CreateTexture(GL_TEXTURE_2D);
|
||||
renderManager_->TextureImage(data_tex[0], 0, size, 3, GL_RGBA32F, GL_RGBA, GL_FLOAT, nullptr, GLRAllocType::NONE, false);
|
||||
renderManager_->TextureImage(data_tex[0], 0, size_u * 3, size_v, GL_RGBA32F, GL_RGBA, GL_FLOAT, nullptr, GLRAllocType::NONE, false);
|
||||
renderManager_->FinalizeTexture(data_tex[0], 0, false);
|
||||
}
|
||||
renderManager_->BindTexture(TEX_SLOT_SPLINE_POINTS, data_tex[0]);
|
||||
// Position
|
||||
renderManager_->TextureSubImage(data_tex[0], 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (u8 *)pos, GLRAllocType::NEW);
|
||||
renderManager_->TextureSubImage(data_tex[0], 0, 0, 0, size_u, size_v, GL_RGBA, GL_FLOAT, (u8 *)pos, GLRAllocType::NEW);
|
||||
// Texcoord
|
||||
if (hasTexCoord)
|
||||
renderManager_->TextureSubImage(data_tex[0], 0, 0, 1, size, 1, GL_RGBA, GL_FLOAT, (u8 *)tex, GLRAllocType::NEW);
|
||||
renderManager_->TextureSubImage(data_tex[0], 0, size_u, 0, size_u, size_v, GL_RGBA, GL_FLOAT, (u8 *)tex, GLRAllocType::NEW);
|
||||
// Color
|
||||
if (hasColor)
|
||||
renderManager_->TextureSubImage(data_tex[0], 0, 0, 2, size, 1, GL_RGBA, GL_FLOAT, (u8 *)col, GLRAllocType::NEW);
|
||||
renderManager_->TextureSubImage(data_tex[0], 0, size_u * 2, 0, size_u, size_v, GL_RGBA, GL_FLOAT, (u8 *)col, GLRAllocType::NEW);
|
||||
|
||||
// Weight U
|
||||
if (prevSizeWU < weights.size_u) {
|
||||
|
@ -713,5 +714,5 @@ void TessellationDataTransferGLES::EndFrame() {
|
|||
data_tex[i] = nullptr;
|
||||
}
|
||||
}
|
||||
prevSize = prevSizeWU = prevSizeWV = 0;
|
||||
prevSizeU = prevSizeV = prevSizeWU = prevSizeWV = 0;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,8 @@ public:
|
|||
class TessellationDataTransferGLES : public TessellationDataTransfer {
|
||||
private:
|
||||
GLRTexture *data_tex[3]{};
|
||||
int prevSize = 0, prevSizeWU = 0, prevSizeWV = 0;
|
||||
int prevSizeU = 0, prevSizeV = 0;
|
||||
int prevSizeWU = 0, prevSizeWV = 0;
|
||||
GLRenderManager *renderManager_;
|
||||
public:
|
||||
TessellationDataTransferGLES(GLRenderManager *renderManager)
|
||||
|
@ -122,7 +123,7 @@ public:
|
|||
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 SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) override;
|
||||
void EndFrame(); // Queues textures for deletion.
|
||||
};
|
||||
|
||||
|
|
|
@ -422,15 +422,16 @@ void GenerateVertexShader(const VShaderID &id, char *buffer, uint32_t *attrMask,
|
|||
WRITE(p, " vec3 _pos[16];\n");
|
||||
WRITE(p, " vec2 _tex[16];\n");
|
||||
WRITE(p, " vec4 _col[16];\n");
|
||||
WRITE(p, " int index;\n");
|
||||
WRITE(p, " int index_u, index_v;\n");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
WRITE(p, " index = (%i + point_pos.y) * u_spline_counts + (%i + point_pos.x);\n", i, j);
|
||||
WRITE(p, " _pos[%i] = %s(u_tess_points, ivec2(index, 0), 0).xyz;\n", i * 4 + j, texelFetch);
|
||||
WRITE(p, " index_u = (%i + point_pos.x);\n", j);
|
||||
WRITE(p, " index_v = (%i + point_pos.y);\n", i);
|
||||
WRITE(p, " _pos[%i] = %s(u_tess_points, ivec2(index_u, index_v), 0).xyz;\n", i * 4 + j, texelFetch);
|
||||
if (doTexture && hasTexcoordTess)
|
||||
WRITE(p, " _tex[%i] = %s(u_tess_points, ivec2(index, 1), 0).xy;\n", i * 4 + j, texelFetch);
|
||||
WRITE(p, " _tex[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts, index_v), 0).xy;\n", i * 4 + j, texelFetch);
|
||||
if (hasColorTess)
|
||||
WRITE(p, " _col[%i] = %s(u_tess_points, ivec2(index, 2), 0).rgba;\n", i * 4 + j, texelFetch);
|
||||
WRITE(p, " _col[%i] = %s(u_tess_points, ivec2(index_u + u_spline_counts * 2, index_v), 0).rgba;\n", i * 4 + j, texelFetch);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1013,7 +1013,7 @@ void DrawEngineVulkan::UpdateUBOs(FrameData *frame) {
|
|||
}
|
||||
}
|
||||
|
||||
void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size, u32 vertType, const Weight2D &weights) {
|
||||
void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, 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 {
|
||||
|
@ -1022,6 +1022,8 @@ void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const
|
|||
float color[4];
|
||||
};
|
||||
|
||||
int size = size_u * size_v;
|
||||
|
||||
int ssboAlignment = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.minStorageBufferOffsetAlignment;
|
||||
uint8_t *data = (uint8_t *)push_->PushAligned(size * sizeof(TessData), (uint32_t *)&bufInfo_[0].offset, &bufInfo_[0].buffer, ssboAlignment);
|
||||
bufInfo_[0].range = size * sizeof(TessData);
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
|
||||
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;
|
||||
void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Weight2D &weights) override;
|
||||
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
|
||||
private:
|
||||
VulkanContext *vulkan_;
|
||||
|
|
Loading…
Add table
Reference in a new issue