Merge pull request #9491 from xebra/improve_hwtess

Improve hwtess
This commit is contained in:
Henrik Rydgård 2017-03-24 10:19:08 +01:00 committed by GitHub
commit e50df0c4a6
7 changed files with 44 additions and 33 deletions

View File

@ -111,6 +111,7 @@ protected:
virtual ~TessellationDataTransfer() {}
// Send spline/bezier's control points to vertex shader through floating point texture.
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;
};

View File

@ -926,16 +926,18 @@ void DrawEngineCommon::SubmitSpline(const void *control_points, const void *indi
patch.patchFacing = patchFacing;
if (g_Config.bHardwareTessellation && g_Config.bHardwareTransform && !g_Config.bSoftwareRendering) {
float *pos = (float*)(decoded + 65536 * 18); // Size 3 float
float *tex = pos + count_u * count_v * 3; // Size 3 float
float *col = tex + count_u * count_v * 3; // Size 4 float
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
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);
for (int idx = 0; idx < count_u * count_v; idx++) {
memcpy(pos + idx * 3, points[idx]->pos.AsArray(), 3 * sizeof(float));
memcpy(pos + idx * 4, points[idx]->pos.AsArray(), 3 * sizeof(float));
if (hasTexCoords)
memcpy(tex + idx * 3, points[idx]->uv, 2 * sizeof(float));
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));
}
@ -1008,9 +1010,10 @@ 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 3 float
float *tex = pos + count_u * count_v * 3; // Size 3 float
float *col = tex + count_u * count_v * 3; // Size 4 float
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
const bool hasColor = (origVertType & GE_VTYPE_COL_MASK) != 0;
const bool hasTexCoords = (origVertType & GE_VTYPE_TC_MASK) != 0;
@ -1019,11 +1022,12 @@ 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);
for (int idx = 0; idx < count_u * count_v; idx++) {
SimpleVertex *point = simplified_control_points + (indices ? idxConv.convert(idx) : idx);
memcpy(pos + idx * 3, point->pos.AsArray(), 3 * sizeof(float));
memcpy(pos + idx * 4, point->pos.AsArray(), 3 * sizeof(float));
if (hasTexCoords)
memcpy(tex + idx * 3, point->uv, 2 * sizeof(float));
memcpy(tex + idx * 4, point->uv, 2 * sizeof(float));
if (hasColor)
memcpy(col + idx * 4, Vec4f::FromRGBA(point->color_32).AsArray(), 4 * sizeof(float));
}

View File

@ -975,7 +975,7 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const floa
view[0]->Release();
}
desc.Width = size;
desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
HRESULT hr = device_->CreateTexture1D(&desc, nullptr, &data_tex[0]);
if (FAILED(hr)) {
INFO_LOG(G3D, "Failed to create D3D texture for HW tessellation");
@ -998,7 +998,7 @@ void DrawEngineD3D11::TessellationDataTransferD3D11::SendDataToShader(const floa
view[1]->Release();
}
desc.Width = size;
desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
HRESULT hr = device_->CreateTexture1D(&desc, nullptr, &data_tex[1]);
if (FAILED(hr)) {
INFO_LOG(G3D, "Failed to create D3D texture for HW tessellation");

View File

@ -1118,10 +1118,10 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (prevSize < size) {
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, size, 0, GL_RGB, GL_FLOAT, (GLfloat*)pos);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, size, 0, GL_RGBA, GL_FLOAT, (GLfloat*)pos);
prevSize = size;
} else {
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGB, GL_FLOAT, (GLfloat*)pos);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGBA, GL_FLOAT, (GLfloat*)pos);
}
// Texcoords
@ -1133,10 +1133,10 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (prevSizeTex < size) {
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, size, 0, GL_RGB, GL_FLOAT, (GLfloat*)tex);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, size, 0, GL_RGBA, GL_FLOAT, (GLfloat*)tex);
prevSizeTex = size;
} else {
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGB, GL_FLOAT, (GLfloat*)tex);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size, GL_RGBA, GL_FLOAT, (GLfloat*)tex);
}
}
@ -1165,10 +1165,10 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (prevSize < size) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, size, 1, 0, GL_RGB, GL_FLOAT, (GLfloat*)pos);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, size, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)pos);
prevSize = size;
} else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGB, GL_FLOAT, (GLfloat*)pos);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (GLfloat*)pos);
}
// Texcoords
@ -1180,10 +1180,10 @@ void DrawEngineGLES::TessellationDataTransferGLES::SendDataToShader(const float
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (prevSizeTex < size) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, size, 1, 0, GL_RGB, GL_FLOAT, (GLfloat*)tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, size, 1, 0, GL_RGBA, GL_FLOAT, (GLfloat*)tex);
prevSizeTex = size;
} else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGB, GL_FLOAT, (GLfloat*)tex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, 1, GL_RGBA, GL_FLOAT, (GLfloat*)tex);
}
}

View File

@ -937,30 +937,25 @@ bool DrawEngineVulkan::IsCodePtrVertexDecoder(const u8 *ptr) const {
return decJitCache_->IsInSpace(ptr);
}
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const float * pos, const float * tex, const float * col, int size, bool hasColor, bool hasTexCoords) {
void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&pos, float *&tex, float *&col, int size, bool hasColor, bool hasTexCoords) {
int rowPitch;
u8 *data;
// Position
if (prevSize < size) {
prevSize = size;
data_tex[0]->CreateDirect(size, 1, 1, VK_FORMAT_R32G32B32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
data_tex[0]->CreateDirect(size, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
}
data = data_tex[0]->Lock(0, &rowPitch);
memcpy(data, pos, size * 3 * sizeof(float));
data_tex[0]->Unlock();
pos = (float *)data_tex[0]->Lock(0, &rowPitch);
// Texcoords
if (hasTexCoords) {
if (prevSizeTex < size) {
prevSizeTex = size;
data_tex[1]->CreateDirect(size, 1, 1, VK_FORMAT_R32G32B32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
data_tex[1]->CreateDirect(size, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
}
data = data_tex[1]->Lock(0, &rowPitch);
memcpy(data, tex, size * 3 * sizeof(float));
data_tex[1]->Unlock();
tex = (float *)data_tex[1]->Lock(0, &rowPitch);
}
// Color
@ -970,7 +965,17 @@ void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const fl
data_tex[2]->CreateDirect(sizeColor, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
}
data = data_tex[2]->Lock(0, &rowPitch);
memcpy(data, col, sizeColor * 4 * sizeof(float));
col = (float *)data_tex[2]->Lock(0, &rowPitch);
}
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) {
// Position
data_tex[0]->Unlock();
// Texcoords
if (hasTexCoords)
data_tex[1]->Unlock();
// Color
data_tex[2]->Unlock();
}

View File

@ -262,6 +262,7 @@ private:
vulkan->Delete().QueueDeleteSampler(sampler);
}
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;
VulkanTexture *GetTexture(int i) const { return data_tex[i]; }
VkSampler GetSampler() const { return sampler; }
void CreateSampler() {

2
ffmpeg

@ -1 +1 @@
Subproject commit a2e98d7ba4c7c5cac08608732c3058cb46e3e0ef
Subproject commit 0757f14d86f1574c02d7f7b9b1c7cd10aad79f75