mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 02:32:18 +00:00
VertexCache: enforce cache alignment without read beyond buffer boundary during allocation and update
This commit is contained in:
parent
341b90bc05
commit
ad046923f5
4 changed files with 50 additions and 43 deletions
|
@ -661,7 +661,7 @@ void idInteraction::CreateStaticInteraction( nvrhi::ICommandList* commandList )
|
|||
{
|
||||
// make a static index cache
|
||||
sint->numLightTrisIndexes = lightTris->numIndexes;
|
||||
sint->lightTrisIndexCache = vertexCache.AllocStaticIndex( lightTris->indexes, ALIGN( lightTris->numIndexes * sizeof( lightTris->indexes[0] ), INDEX_CACHE_ALIGN ), commandList );
|
||||
sint->lightTrisIndexCache = vertexCache.AllocStaticIndex( lightTris->indexes, lightTris->numIndexes * sizeof( lightTris->indexes[0] ), commandList );
|
||||
|
||||
interactionGenerated = true;
|
||||
R_FreeStaticTriSurf( lightTris );
|
||||
|
|
|
@ -30,6 +30,9 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
#include "../RenderCommon.h"
|
||||
#include "../VertexCache.h"
|
||||
|
||||
extern idVertexCache vertexCache;
|
||||
|
||||
#include "sys/DeviceManager.h"
|
||||
|
||||
|
@ -185,24 +188,23 @@ bool idVertexBuffer::AllocBufferObject( const void* data, int allocSize, bufferU
|
|||
idLib::Error( "idVertexBuffer::AllocBufferObject: allocSize = %i", allocSize );
|
||||
}
|
||||
|
||||
size = allocSize;
|
||||
size = ALIGN( allocSize, VERTEX_CACHE_ALIGN );
|
||||
usage = _usage;
|
||||
|
||||
int numBytes = GetAllocedSize();
|
||||
const int numBytes = GetAllocedSize();
|
||||
|
||||
nvrhi::BufferDesc vertexBufferDesc;
|
||||
vertexBufferDesc.byteSize = numBytes;
|
||||
vertexBufferDesc.isVertexBuffer = true;
|
||||
vertexBufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
|
||||
|
||||
if( usage == BU_DYNAMIC )
|
||||
{
|
||||
vertexBufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
|
||||
vertexBufferDesc.cpuAccess = nvrhi::CpuAccessMode::Write;
|
||||
vertexBufferDesc.debugName = "Mapped idDrawVert vertex buffer";
|
||||
}
|
||||
else
|
||||
{
|
||||
vertexBufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
|
||||
vertexBufferDesc.keepInitialState = true;
|
||||
vertexBufferDesc.debugName = "Static idDrawVert vertex buffer";
|
||||
}
|
||||
|
@ -307,14 +309,15 @@ void idVertexBuffer::Update( const void* data, int updateSize, int offset, bool
|
|||
assert( bufferHandle );
|
||||
assert_16_byte_aligned( data );
|
||||
assert( ( GetOffset() & 15 ) == 0 );
|
||||
assert( ( offset & VERTEX_CACHE_ALIGN - 1 ) == 0 );
|
||||
|
||||
if( updateSize > GetSize() )
|
||||
const int numBytes = ( updateSize + 15 ) & ~15;
|
||||
|
||||
if( offset + numBytes > GetSize() )
|
||||
{
|
||||
idLib::FatalError( "idVertexBuffer::Update: size overrun, %i > %i\n", updateSize, GetSize() );
|
||||
idLib::FatalError( "idVertexBuffer::Update: size overrun, %i + %i > %i\n", offset, numBytes, GetSize() );
|
||||
}
|
||||
|
||||
int numBytes = ( updateSize + 15 ) & ~15;
|
||||
|
||||
if( usage == BU_DYNAMIC )
|
||||
{
|
||||
assert( IsMapped() );
|
||||
|
@ -450,10 +453,10 @@ bool idIndexBuffer::AllocBufferObject( const void* data, int allocSize, bufferUs
|
|||
idLib::Error( "idIndexBuffer::AllocBufferObject: allocSize = %i", allocSize );
|
||||
}
|
||||
|
||||
size = allocSize;
|
||||
size = ALIGN( allocSize, INDEX_CACHE_ALIGN );
|
||||
usage = _usage;
|
||||
|
||||
int numBytes = GetAllocedSize();
|
||||
const int numBytes = GetAllocedSize();
|
||||
|
||||
nvrhi::BufferDesc indexBufferDesc;
|
||||
indexBufferDesc.byteSize = numBytes;
|
||||
|
@ -573,14 +576,15 @@ void idIndexBuffer::Update( const void* data, int updateSize, int offset, bool i
|
|||
assert( bufferHandle );
|
||||
assert_16_byte_aligned( data );
|
||||
assert( ( GetOffset() & 15 ) == 0 );
|
||||
|
||||
if( updateSize > GetSize() )
|
||||
{
|
||||
idLib::FatalError( "idIndexBuffer::Update: size overrun, %i > %i\n", updateSize, GetSize() );
|
||||
}
|
||||
assert( ( offset & INDEX_CACHE_ALIGN - 1 ) == 0 );
|
||||
|
||||
const int numBytes = ( updateSize + 15 ) & ~15;
|
||||
|
||||
if( offset + numBytes > GetSize() )
|
||||
{
|
||||
idLib::FatalError( "idIndexBuffer::Update: size overrun, %i + %i > %i\n", offset, numBytes, GetSize() );
|
||||
}
|
||||
|
||||
if( usage == BU_DYNAMIC )
|
||||
{
|
||||
assert( IsMapped() );
|
||||
|
@ -717,7 +721,7 @@ bool idUniformBuffer::AllocBufferObject( const void* data, int allocSize, buffer
|
|||
idLib::Error( "idUniformBuffer::AllocBufferObject: allocSize = %i", allocSize );
|
||||
}
|
||||
|
||||
size = allocSize;
|
||||
size = ALIGN( allocSize, vertexCache.uniformBufferOffsetAlignment );
|
||||
usage = allocatedUsage;
|
||||
|
||||
const int numBytes = GetAllocedSize();
|
||||
|
@ -725,14 +729,9 @@ bool idUniformBuffer::AllocBufferObject( const void* data, int allocSize, buffer
|
|||
// This buffer is a shader resource as opposed to a constant buffer due to
|
||||
// constant buffers not being able to be sub-ranged.
|
||||
nvrhi::BufferDesc bufferDesc;
|
||||
//bufferDesc.initialState = nvrhi::ResourceStates::ConstantBuffer; // SRS - shouldn't this be initialized to CopyDest?
|
||||
bufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
|
||||
//bufferDesc.keepInitialState = true; // SRS - shouldn't this be set for BU_STATIC only?
|
||||
bufferDesc.canHaveTypedViews = true;
|
||||
bufferDesc.canHaveRawViews = true;
|
||||
bufferDesc.byteSize = numBytes;
|
||||
bufferDesc.structStride = sizeof( idVec4 );
|
||||
bufferDesc.isConstantBuffer = true;
|
||||
bufferDesc.structStride = sizeof( idVec4 ); // SRS - this defines a structured storage buffer vs. a constant buffer
|
||||
bufferDesc.initialState = nvrhi::ResourceStates::Common;
|
||||
|
||||
if( usage == BU_DYNAMIC )
|
||||
{
|
||||
|
@ -845,14 +844,15 @@ void idUniformBuffer::Update( const void* data, int updateSize, int offset, bool
|
|||
assert( bufferHandle );
|
||||
assert_16_byte_aligned( data );
|
||||
assert( ( GetOffset() & 15 ) == 0 );
|
||||
assert( ( offset & vertexCache.uniformBufferOffsetAlignment - 1 ) == 0 );
|
||||
|
||||
if( updateSize > GetSize() )
|
||||
const int numBytes = ( updateSize + 15 ) & ~15;
|
||||
|
||||
if( offset + numBytes > GetSize() )
|
||||
{
|
||||
idLib::FatalError( "idUniformBuffer::Update: size overrun, %i > %i\n", updateSize, GetSize() );
|
||||
idLib::FatalError( "idUniformBuffer::Update: size overrun, %i + %i > %i\n", offset, numBytes, GetSize() );
|
||||
}
|
||||
|
||||
int numBytes = ( updateSize + 15 ) & ~15;
|
||||
|
||||
if( usage == BU_DYNAMIC )
|
||||
{
|
||||
assert( IsMapped() );
|
||||
|
|
|
@ -215,7 +215,8 @@ vertCacheHandle_t idVertexCache::ActuallyAlloc( geoBufferSet_t& vcs, const void*
|
|||
assert( ( ( ( uintptr_t )( data ) ) & 15 ) == 0 );
|
||||
// RB end
|
||||
|
||||
assert( ( bytes & 15 ) == 0 );
|
||||
// SRS - enforce cache alignment without read beyond boundary for each cache type below
|
||||
//assert( ( bytes & 15 ) == 0 );
|
||||
|
||||
int endPos = 0;
|
||||
int offset = 0;
|
||||
|
@ -224,13 +225,15 @@ vertCacheHandle_t idVertexCache::ActuallyAlloc( geoBufferSet_t& vcs, const void*
|
|||
{
|
||||
case CACHE_INDEX:
|
||||
{
|
||||
endPos = vcs.indexMemUsed.Add( bytes );
|
||||
// SRS - calculate alignedBytes retaining original to prevent read beyond data boundary during update
|
||||
int alignedBytes = ALIGN( bytes, INDEX_CACHE_ALIGN );
|
||||
endPos = vcs.indexMemUsed.Add( alignedBytes );
|
||||
if( endPos > vcs.indexBuffer.GetAllocedSize() )
|
||||
{
|
||||
idLib::Error( "Out of index cache" );
|
||||
}
|
||||
|
||||
offset = endPos - bytes;
|
||||
offset = endPos - alignedBytes;
|
||||
|
||||
if( data != NULL )
|
||||
{
|
||||
|
@ -245,13 +248,15 @@ vertCacheHandle_t idVertexCache::ActuallyAlloc( geoBufferSet_t& vcs, const void*
|
|||
}
|
||||
case CACHE_VERTEX:
|
||||
{
|
||||
endPos = vcs.vertexMemUsed.Add( bytes );
|
||||
// SRS - calculate alignedBytes retaining original to prevent read beyond data boundary during update
|
||||
int alignedBytes = ALIGN( bytes, VERTEX_CACHE_ALIGN );
|
||||
endPos = vcs.vertexMemUsed.Add( alignedBytes );
|
||||
if( endPos > vcs.vertexBuffer.GetAllocedSize() )
|
||||
{
|
||||
idLib::Error( "Out of vertex cache" );
|
||||
}
|
||||
|
||||
offset = endPos - bytes;
|
||||
offset = endPos - alignedBytes;
|
||||
|
||||
if( data != NULL )
|
||||
{
|
||||
|
@ -266,13 +271,15 @@ vertCacheHandle_t idVertexCache::ActuallyAlloc( geoBufferSet_t& vcs, const void*
|
|||
}
|
||||
case CACHE_JOINT:
|
||||
{
|
||||
endPos = vcs.jointMemUsed.Add( bytes );
|
||||
// SRS - calculate alignedBytes retaining original to prevent read beyond data boundary during update
|
||||
int alignedBytes = ALIGN( bytes, uniformBufferOffsetAlignment );
|
||||
endPos = vcs.jointMemUsed.Add( alignedBytes );
|
||||
if( endPos > vcs.jointBuffer.GetAllocedSize() )
|
||||
{
|
||||
idLib::Error( "Out of joint buffer cache" );
|
||||
}
|
||||
|
||||
offset = endPos - bytes;
|
||||
offset = endPos - alignedBytes;
|
||||
|
||||
if( data != NULL )
|
||||
{
|
||||
|
@ -308,7 +315,7 @@ idVertexCache::AllocVertex
|
|||
*/
|
||||
vertCacheHandle_t idVertexCache::AllocVertex( const void* data, int num, size_t size /*= sizeof( idDrawVert ) */, nvrhi::ICommandList* commandList )
|
||||
{
|
||||
return ActuallyAlloc( frameData[ listNum ], data, ALIGN( num * size, VERTEX_CACHE_ALIGN ), CACHE_VERTEX, commandList );
|
||||
return ActuallyAlloc( frameData[ listNum ], data, num * size, CACHE_VERTEX, commandList );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -318,7 +325,7 @@ idVertexCache::AllocIndex
|
|||
*/
|
||||
vertCacheHandle_t idVertexCache::AllocIndex( const void* data, int num, size_t size /*= sizeof( triIndex_t ) */, nvrhi::ICommandList* commandList )
|
||||
{
|
||||
return ActuallyAlloc( frameData[ listNum ], data, ALIGN( num * size, INDEX_CACHE_ALIGN ), CACHE_INDEX, commandList );
|
||||
return ActuallyAlloc( frameData[ listNum ], data, num * size, CACHE_INDEX, commandList );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,7 +335,7 @@ idVertexCache::AllocJoint
|
|||
*/
|
||||
vertCacheHandle_t idVertexCache::AllocJoint( const void* data, int num, size_t size /*= sizeof( idJointMat ) */, nvrhi::ICommandList* commandList )
|
||||
{
|
||||
return ActuallyAlloc( frameData[ listNum ], data, ALIGN( num * size, uniformBufferOffsetAlignment ), CACHE_JOINT, commandList );
|
||||
return ActuallyAlloc( frameData[ listNum ], data, num * size, CACHE_JOINT, commandList );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1819,8 +1819,8 @@ Uploads static vertices to the vertex cache.
|
|||
*/
|
||||
void R_CreateDeformStaticVertices( deformInfo_t* deform, nvrhi::ICommandList* commandList )
|
||||
{
|
||||
deform->staticAmbientCache = vertexCache.AllocStaticVertex( deform->verts, ALIGN( deform->numOutputVerts * sizeof( idDrawVert ), VERTEX_CACHE_ALIGN ), commandList );
|
||||
deform->staticIndexCache = vertexCache.AllocStaticIndex( deform->indexes, ALIGN( deform->numIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ), commandList );
|
||||
deform->staticAmbientCache = vertexCache.AllocStaticVertex( deform->verts, deform->numOutputVerts * sizeof( idDrawVert ), commandList );
|
||||
deform->staticIndexCache = vertexCache.AllocStaticIndex( deform->indexes, deform->numIndexes * sizeof( triIndex_t ), commandList );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1948,13 +1948,13 @@ void R_CreateStaticBuffersForTri( srfTriangles_t& tri, nvrhi::ICommandList* comm
|
|||
// index cache
|
||||
if( tri.indexes != NULL )
|
||||
{
|
||||
tri.indexCache = vertexCache.AllocStaticIndex( tri.indexes, ALIGN( tri.numIndexes * sizeof( tri.indexes[0] ), INDEX_CACHE_ALIGN ), commandList );
|
||||
tri.indexCache = vertexCache.AllocStaticIndex( tri.indexes, tri.numIndexes * sizeof( tri.indexes[0] ), commandList );
|
||||
}
|
||||
|
||||
// vertex cache
|
||||
if( tri.verts != NULL )
|
||||
{
|
||||
tri.ambientCache = vertexCache.AllocStaticVertex( tri.verts, ALIGN( tri.numVerts * sizeof( tri.verts[0] ), VERTEX_CACHE_ALIGN ), commandList );
|
||||
tri.ambientCache = vertexCache.AllocStaticVertex( tri.verts, tri.numVerts * sizeof( tri.verts[0] ), commandList );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2128,4 +2128,4 @@ idVec3 R_ClosestPointPointTriangle( const idVec3& point, const idVec3& vertex1,
|
|||
result = vertex1 + ab * v2 + ac * w2; //= u*vertex1 + v*vertex2 + w*vertex3, u = va * denom = 1.0f - v - w
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue