diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index d33806aea7..a0bdc4e2fa 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -5,34 +5,16 @@ #include "vectors.h" #include "hw_collision.h" #include "bounds.h" +#include "common/utility/matrix.h" #include #include typedef dp::rect_pack::RectPacker RectPacker; -struct SurfaceInfo // This is the structure of the buffer inside the shader -{ - FVector3 Normal; - float Sky; - float SamplingDistance; - uint32_t PortalIndex; - float Padding1, Padding2; -}; - -struct PortalInfo // This is the structure of the buffer inside the shader -{ - float transformation[16]; // mat4 -}; - namespace hwrenderer { -// Note: this is just the current layout needed to get VkLightmap/GPURaytracer from zdray to compile within this project. -// -// The surface actually class needs to be moved up DoomLevelMesh, since this can't otherwise be accessed in the common part of the codebase shared with Raze. -// Ideally, we'd undoomify it as much as possible, so Raze in theory also would be able to declare an raytracing acceleration structure for dynlights and lightmaps - class ThingLight { public: @@ -123,36 +105,22 @@ struct SmoothingGroup struct Portal { - float transformation[4][4] = { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1} - }; + Portal() { transformation.loadIdentity(); } + + VSMatrix transformation; int sourceSectorGroup = 0; int targetSectorGroup = 0; - inline FVector4 Mat4Vec4Mul(const FVector4& vec) const - { - FVector4 result(0.0f, 0.0f, 0.0f, 0.0f); - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - result[i] += transformation[i][j] * vec[j]; - } - } - return result; - } - inline FVector3 TransformPosition(const FVector3& pos) const { - auto v = Mat4Vec4Mul(FVector4(pos, 1.0)); + auto v = transformation * FVector4(pos, 1.0); return FVector3(v.X, v.Y, v.Z); } inline FVector3 TransformRotation(const FVector3& dir) const { - auto v = Mat4Vec4Mul(FVector4(dir, 0.0)); + auto v = transformation * FVector4(dir, 0.0); return FVector3(v.X, v.Y, v.Z); } @@ -189,15 +157,8 @@ public: LevelMesh() { // Default portal - PortalInfo portalInfo; hwrenderer::Portal portal; - - for (int i = 0; i < 16; ++i) - { - portalInfo.transformation[i] = (&portal.transformation[0][0])[i]; - } - - this->portalInfo.Push(portalInfo); + portals.Push(portal); } virtual ~LevelMesh() = default; @@ -207,9 +168,6 @@ public: TArray MeshElements; TArray MeshSurfaceIndexes; - TArray surfaceInfo; - TArray portalInfo; - std::unique_ptr Collision; TArray Surfaces; diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp index eb30000e4d..718722ca73 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -85,7 +85,7 @@ void VkRaytrace::Reset() void VkRaytrace::CreateVulkanObjects() { - CreateVertexAndIndexBuffers(); + CreateBuffers(); if (useRayQuery) { CreateBottomLevelAccelerationStructure(); @@ -93,7 +93,7 @@ void VkRaytrace::CreateVulkanObjects() } } -void VkRaytrace::CreateVertexAndIndexBuffers() +void VkRaytrace::CreateBuffers() { std::vector nodes = CreateCollisionNodes(); @@ -106,6 +106,25 @@ void VkRaytrace::CreateVertexAndIndexBuffers() CollisionNodeBufferHeader nodesHeader; nodesHeader.root = Mesh->Collision->get_root(); + TArray portalInfo; + for (auto& portal : Mesh->portals) + { + PortalInfo info; + info.transformation = portal.transformation; + portalInfo.Push(info); + } + + TArray surfaceInfo; + for (auto& surface : Mesh->Surfaces) + { + SurfaceInfo info; + info.Normal = surface.plane.XYZ(); + info.PortalIndex = 0; + info.SamplingDistance = (float)surface.sampleDimension; + info.Sky = surface.bSky; + surfaceInfo.Push(info); + } + vertexBuffer = BufferBuilder() .Usage( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | @@ -144,13 +163,13 @@ void VkRaytrace::CreateVertexAndIndexBuffers() surfaceBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) - .Size(Mesh->surfaceInfo.Size() * sizeof(SurfaceInfo)) + .Size(surfaceInfo.Size() * sizeof(SurfaceInfo)) .DebugName("surfaceBuffer") .Create(fb->GetDevice()); portalBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) - .Size(Mesh->portalInfo.Size() * sizeof(PortalInfo)) + .Size(portalInfo.Size() * sizeof(PortalInfo)) .DebugName("portalBuffer") .Create(fb->GetDevice()); @@ -159,8 +178,8 @@ void VkRaytrace::CreateVertexAndIndexBuffers() .AddBuffer(indexBuffer.get(), Mesh->MeshElements.Data(), (size_t)Mesh->MeshElements.Size() * sizeof(uint32_t)) .AddBuffer(nodesBuffer.get(), &nodesHeader, sizeof(CollisionNodeBufferHeader), nodes.data(), nodes.size() * sizeof(CollisionNode)) .AddBuffer(surfaceIndexBuffer.get(), Mesh->MeshSurfaceIndexes.Data(), Mesh->MeshSurfaceIndexes.Size() * sizeof(int)) - .AddBuffer(surfaceBuffer.get(), Mesh->surfaceInfo.Data(), Mesh->surfaceInfo.Size() * sizeof(SurfaceInfo)) - .AddBuffer(portalBuffer.get(), Mesh->portalInfo.Data(), Mesh->portalInfo.Size() * sizeof(PortalInfo)) + .AddBuffer(surfaceBuffer.get(), surfaceInfo.Data(), surfaceInfo.Size() * sizeof(SurfaceInfo)) + .AddBuffer(portalBuffer.get(), portalInfo.Data(), portalInfo.Size() * sizeof(PortalInfo)) .Execute(fb->GetDevice(), fb->GetCommands()->GetTransferCommands()); PipelineBarrier() diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h index 8ca43891ee..487ca129ec 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h @@ -3,6 +3,7 @@ #include "zvulkan/vulkanobjects.h" #include "hw_levelmesh.h" +#include "common/utility/matrix.h" class VulkanRenderDevice; @@ -26,6 +27,20 @@ struct CollisionNode int padding3; }; +struct SurfaceInfo +{ + FVector3 Normal; + float Sky; + float SamplingDistance; + uint32_t PortalIndex; + float Padding1, Padding2; +}; + +struct PortalInfo +{ + VSMatrix transformation; +}; + class VkRaytrace { public: @@ -44,7 +59,7 @@ public: private: void Reset(); void CreateVulkanObjects(); - void CreateVertexAndIndexBuffers(); + void CreateBuffers(); void CreateBottomLevelAccelerationStructure(); void CreateTopLevelAccelerationStructure(); diff --git a/src/common/utility/matrix.h b/src/common/utility/matrix.h index 0ed4f7bfd8..a38b17146f 100644 --- a/src/common/utility/matrix.h +++ b/src/common/utility/matrix.h @@ -29,6 +29,10 @@ typedef double FLOATTYPE; typedef float FLOATTYPE; #endif +#ifndef NO_SSE +#include +#endif + class VSMatrix { public: @@ -102,6 +106,32 @@ class VSMatrix { bool inverseMatrix(VSMatrix &result); void transpose(); + FVector4 operator *(const FVector4& v) const + { + #ifdef NO_SSE + FVector4 result; + result.x = mMatrix[0 * 4 + 0] * v.X + mMatrix[1 * 4 + 0] * v.Y + mMatrix[2 * 4 + 0] * v.Z + mMatrix[3 * 4 + 0] * v.W; + result.y = mMatrix[0 * 4 + 1] * v.X + mMatrix[1 * 4 + 1] * v.Y + mMatrix[2 * 4 + 1] * v.Z + mMatrix[3 * 4 + 1] * v.W; + result.z = mMatrix[0 * 4 + 2] * v.X + mMatrix[1 * 4 + 2] * v.Y + mMatrix[2 * 4 + 2] * v.Z + mMatrix[3 * 4 + 2] * v.W; + result.w = mMatrix[0 * 4 + 3] * v.X + mMatrix[1 * 4 + 3] * v.Y + mMatrix[2 * 4 + 3] * v.Z + mMatrix[3 * 4 + 3] * v.W; + return result; + #else + __m128 m0 = _mm_loadu_ps(mMatrix); + __m128 m1 = _mm_loadu_ps(mMatrix + 4); + __m128 m2 = _mm_loadu_ps(mMatrix + 8); + __m128 m3 = _mm_loadu_ps(mMatrix + 12); + __m128 mv = _mm_loadu_ps(&v.X); + m0 = _mm_mul_ps(m0, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(0, 0, 0, 0))); + m1 = _mm_mul_ps(m1, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(1, 1, 1, 1))); + m2 = _mm_mul_ps(m2, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(2, 2, 2, 2))); + m3 = _mm_mul_ps(m3, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(3, 3, 3, 3))); + mv = _mm_add_ps(_mm_add_ps(_mm_add_ps(m0, m1), m2), m3); + FVector4 result; + _mm_storeu_ps(&result.X, mv); + return result; + #endif + } + protected: static void crossProduct(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res); static FLOATTYPE dotProduct(const FLOATTYPE *a, const FLOATTYPE * b); @@ -184,7 +214,7 @@ public: *this = (*this) * m1; } - Matrix3x4 operator *(const Matrix3x4 &other) + Matrix3x4 operator *(const Matrix3x4 &other) const { Matrix3x4 result; @@ -206,7 +236,7 @@ public: return result; } - FVector3 operator *(const FVector3 &vec) + FVector3 operator *(const FVector3 &vec) const { FVector3 result; diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 852dfda07c..b0e478c12d 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -636,13 +636,6 @@ void DoomLevelMesh::SetupLightmapUvs() } surface.texPixels.resize(surface.texWidth * surface.texHeight); - - SurfaceInfo info; - info.Normal = surface.plane.XYZ(); - info.PortalIndex = 0; - info.SamplingDistance = (float)surface.sampleDimension; - info.Sky = surface.bSky; - surfaceInfo.Push(info); } {