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 {
|
class TessellationDataTransfer {
|
||||||
public:
|
public:
|
||||||
void CopyControlPoints(float *pos, float *tex, float *col, int posStride, int texStride, int colStride, const SimpleVertex *const *points, int size, u32 vertType);
|
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 {
|
class DrawEngineCommon {
|
||||||
|
|
|
@ -462,7 +462,7 @@ static void HardwareTessellation(OutputBuffers &output, const Patch &patch, u32
|
||||||
Weight2D weights(WeightType::weightsCache, key_u, key_v);
|
Weight2D weights(WeightType::weightsCache, key_u, key_v);
|
||||||
weights.size_u = WeightType::CalcSize(patch.tess_u, patch.count_u);
|
weights.size_u = WeightType::CalcSize(patch.tess_u, patch.count_u);
|
||||||
weights.size_v = WeightType::CalcSize(patch.tess_v, patch.count_v);
|
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.
|
// Generating simple input vertices for the spline-computing vertex shader.
|
||||||
float inv_u = 1.0f / (float)patch.tess_u;
|
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 {
|
struct TessData {
|
||||||
float pos[3]; float pad1;
|
float pos[3]; float pad1;
|
||||||
float uv[2]; float pad2[2];
|
float uv[2]; float pad2[2];
|
||||||
float color[4];
|
float color[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int size = size_u * size_v;
|
||||||
|
|
||||||
if (prevSize < size) {
|
if (prevSize < size) {
|
||||||
prevSize = size;
|
prevSize = size;
|
||||||
if (buf[0]) buf[0]->Release();
|
if (buf[0]) buf[0]->Release();
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device);
|
TessellationDataTransferD3D11(ID3D11DeviceContext *context, ID3D11Device *device);
|
||||||
~TessellationDataTransferD3D11();
|
~TessellationDataTransferD3D11();
|
||||||
// Send spline/bezier's control points and weights to vertex shader through structured shader buffer.
|
// 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.
|
// Handles transform, lighting and drawing.
|
||||||
|
|
|
@ -625,7 +625,7 @@ rotateVBO:
|
||||||
GPUDebug::NotifyDraw();
|
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
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ class TessellationDataTransferDX9 : public TessellationDataTransfer {
|
||||||
public:
|
public:
|
||||||
TessellationDataTransferDX9() {}
|
TessellationDataTransferDX9() {}
|
||||||
~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.
|
// Handles transform, lighting and drawing.
|
||||||
|
|
|
@ -653,35 +653,36 @@ bool DrawEngineGLES::IsCodePtrVertexDecoder(const u8 *ptr) const {
|
||||||
return decJitCache_->IsInSpace(ptr);
|
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 hasColor = (vertType & GE_VTYPE_COL_MASK) != 0;
|
||||||
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
|
bool hasTexCoord = (vertType & GE_VTYPE_TC_MASK) != 0;
|
||||||
|
|
||||||
|
int size = size_u * size_v;
|
||||||
float *pos = new float[size * 4];
|
float *pos = new float[size * 4];
|
||||||
float *tex = hasTexCoord ? new float[size * 4] : nullptr;
|
float *tex = hasTexCoord ? new float[size * 4] : nullptr;
|
||||||
float *col = hasColor ? new float[size * 4] : nullptr;
|
float *col = hasColor ? new float[size * 4] : nullptr;
|
||||||
int stride = 4;
|
int stride = 4;
|
||||||
|
|
||||||
CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType);
|
CopyControlPoints(pos, tex, col, stride, stride, stride, points, size, vertType);
|
||||||
|
|
||||||
// Removed the 1D texture support, it's unlikely to be relevant for performance.
|
// Removed the 1D texture support, it's unlikely to be relevant for performance.
|
||||||
// Control Points
|
// Control Points
|
||||||
if (prevSize < size) {
|
if (prevSizeU < size_u || prevSizeV < size_v) {
|
||||||
prevSize = size;
|
prevSizeU = size_u;
|
||||||
|
prevSizeV = size_v;
|
||||||
if (!data_tex[0])
|
if (!data_tex[0])
|
||||||
data_tex[0] = renderManager_->CreateTexture(GL_TEXTURE_2D);
|
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_->FinalizeTexture(data_tex[0], 0, false);
|
||||||
}
|
}
|
||||||
renderManager_->BindTexture(TEX_SLOT_SPLINE_POINTS, data_tex[0]);
|
renderManager_->BindTexture(TEX_SLOT_SPLINE_POINTS, data_tex[0]);
|
||||||
// Position
|
// 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
|
// Texcoord
|
||||||
if (hasTexCoord)
|
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
|
// Color
|
||||||
if (hasColor)
|
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
|
// Weight U
|
||||||
if (prevSizeWU < weights.size_u) {
|
if (prevSizeWU < weights.size_u) {
|
||||||
|
@ -713,5 +714,5 @@ void TessellationDataTransferGLES::EndFrame() {
|
||||||
data_tex[i] = nullptr;
|
data_tex[i] = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevSize = prevSizeWU = prevSizeWV = 0;
|
prevSizeU = prevSizeV = prevSizeWU = prevSizeWV = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,8 @@ public:
|
||||||
class TessellationDataTransferGLES : public TessellationDataTransfer {
|
class TessellationDataTransferGLES : public TessellationDataTransfer {
|
||||||
private:
|
private:
|
||||||
GLRTexture *data_tex[3]{};
|
GLRTexture *data_tex[3]{};
|
||||||
int prevSize = 0, prevSizeWU = 0, prevSizeWV = 0;
|
int prevSizeU = 0, prevSizeV = 0;
|
||||||
|
int prevSizeWU = 0, prevSizeWV = 0;
|
||||||
GLRenderManager *renderManager_;
|
GLRenderManager *renderManager_;
|
||||||
public:
|
public:
|
||||||
TessellationDataTransferGLES(GLRenderManager *renderManager)
|
TessellationDataTransferGLES(GLRenderManager *renderManager)
|
||||||
|
@ -122,7 +123,7 @@ public:
|
||||||
EndFrame();
|
EndFrame();
|
||||||
}
|
}
|
||||||
// Send spline/bezier's control points and weights to vertex shader through floating point texture.
|
// 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.
|
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, " vec3 _pos[16];\n");
|
||||||
WRITE(p, " vec2 _tex[16];\n");
|
WRITE(p, " vec2 _tex[16];\n");
|
||||||
WRITE(p, " vec4 _col[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 i = 0; i < 4; i++) {
|
||||||
for (int j = 0; j < 4; j++) {
|
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, " index_u = (%i + point_pos.x);\n", j);
|
||||||
WRITE(p, " _pos[%i] = %s(u_tess_points, ivec2(index, 0), 0).xyz;\n", i * 4 + j, texelFetch);
|
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)
|
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)
|
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
|
// 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.
|
// also need to be 16-byte aligned, hence the padding.
|
||||||
struct TessData {
|
struct TessData {
|
||||||
|
@ -1022,6 +1022,8 @@ void TessellationDataTransferVulkan::SendDataToShader(const SimpleVertex *const
|
||||||
float color[4];
|
float color[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int size = size_u * size_v;
|
||||||
|
|
||||||
int ssboAlignment = vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).limits.minStorageBufferOffsetAlignment;
|
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);
|
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);
|
bufInfo_[0].range = size * sizeof(TessData);
|
||||||
|
|
|
@ -123,7 +123,7 @@ public:
|
||||||
|
|
||||||
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
|
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
|
||||||
// Send spline/bezier's control points and weights to vertex shader through structured shader buffer.
|
// 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_; }
|
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
|
||||||
private:
|
private:
|
||||||
VulkanContext *vulkan_;
|
VulkanContext *vulkan_;
|
||||||
|
|
Loading…
Add table
Reference in a new issue