diff --git a/GPU/Common/DrawEngineCommon.h b/GPU/Common/DrawEngineCommon.h index 84e6ed274..7f3edf383 100644 --- a/GPU/Common/DrawEngineCommon.h +++ b/GPU/Common/DrawEngineCommon.h @@ -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; }; diff --git a/GPU/Common/SplineCommon.cpp b/GPU/Common/SplineCommon.cpp index ed4ecc5cc..53486ed3e 100644 --- a/GPU/Common/SplineCommon.cpp +++ b/GPU/Common/SplineCommon.cpp @@ -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)); } diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 15f2d18bd..61a04ac1a 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -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"); diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 2455f257f..dc0f451e4 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -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); } } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 3d8d5ede4..d87530af7 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -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(); } diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 553099dd8..4032bb61b 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -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() { diff --git a/ffmpeg b/ffmpeg index a2e98d7ba..0757f14d8 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit a2e98d7ba4c7c5cac08608732c3058cb46e3e0ef +Subproject commit 0757f14d86f1574c02d7f7b9b1c7cd10aad79f75