Move SurfaceInfo and PortalInfo to vk_raytrace

Add VSMatrix * FVector4 operator
This commit is contained in:
Magnus Norddahl 2023-09-02 12:54:07 +02:00 committed by Christoph Oelckers
parent 87c21f99fe
commit ab609d7708
5 changed files with 80 additions and 65 deletions

View file

@ -5,34 +5,16 @@
#include "vectors.h"
#include "hw_collision.h"
#include "bounds.h"
#include "common/utility/matrix.h"
#include <memory>
#include <dp_rect_pack.h>
typedef dp::rect_pack::RectPacker<int> 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<uint32_t> MeshElements;
TArray<int> MeshSurfaceIndexes;
TArray<SurfaceInfo> surfaceInfo;
TArray<PortalInfo> portalInfo;
std::unique_ptr<TriangleMeshShape> Collision;
TArray<hwrenderer::Surface> Surfaces;

View file

@ -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<CollisionNode> nodes = CreateCollisionNodes();
@ -106,6 +106,25 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
CollisionNodeBufferHeader nodesHeader;
nodesHeader.root = Mesh->Collision->get_root();
TArray<PortalInfo> portalInfo;
for (auto& portal : Mesh->portals)
{
PortalInfo info;
info.transformation = portal.transformation;
portalInfo.Push(info);
}
TArray<SurfaceInfo> 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()

View file

@ -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();

View file

@ -29,6 +29,10 @@ typedef double FLOATTYPE;
typedef float FLOATTYPE;
#endif
#ifndef NO_SSE
#include <emmintrin.h>
#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;

View file

@ -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);
}
{