NVRHI merge by Stephen Pridham part 2

This commit is contained in:
Robert Beckebans 2022-02-21 17:59:13 +01:00
parent 16a21fdeb8
commit c37dc4e04e
23 changed files with 8377 additions and 299 deletions

View file

@ -0,0 +1,645 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
Copyright (C) 2016-2017 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "precompiled.h"
#pragma hdrstop
#include "../RenderCommon.h"
#include "sys/DeviceManager.h"
#include <stddef.h>
extern idCVar r_showBuffers;
//static const GLenum bufferUsage = GL_STATIC_DRAW;
static const GLenum bufferUsage = GL_DYNAMIC_DRAW;
extern DeviceManager* deviceManager;
/*
================================================================================================
Buffer Objects
================================================================================================
*/
/*
========================
UnbindBufferObjects
========================
*/
void UnbindBufferObjects()
{
//glBindBuffer( GL_ARRAY_BUFFER, 0 );
//glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
}
/*
================================================================================================
idVertexBuffer
================================================================================================
*/
/*
========================
idVertexBuffer::idVertexBuffer
========================
*/
idVertexBuffer::idVertexBuffer()
{
size = 0;
offsetInOtherBuffer = OWNS_BUFFER_FLAG;
bufferHandle.Reset();
SetUnmapped();
}
/*
========================
idVertexBuffer::AllocBufferObject
========================
*/
bool idVertexBuffer::AllocBufferObject( const void* data, int allocSize, bufferUsageType_t _usage, nvrhi::ICommandList* commandList )
{
assert( !bufferHandle );
assert_16_byte_aligned( data );
if( allocSize <= 0 )
{
idLib::Error( "idVertexBuffer::AllocBufferObject: allocSize = %i", allocSize );
}
size = allocSize;
usage = _usage;
bool allocationFailed = false;
int numBytes = GetAllocedSize();
nvrhi::BufferDesc vertexBufferDesc;
vertexBufferDesc.byteSize = numBytes;
vertexBufferDesc.isVertexBuffer = true;
vertexBufferDesc.debugName = "VertexBuffer";
if( usage == BU_DYNAMIC )
{
vertexBufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
vertexBufferDesc.cpuAccess = nvrhi::CpuAccessMode::Write;
}
else
{
vertexBufferDesc.initialState = nvrhi::ResourceStates::Common;
vertexBufferDesc.keepInitialState = true;
}
bufferHandle = deviceManager->GetDevice()->createBuffer( vertexBufferDesc );
if( r_showBuffers.GetBool() )
{
idLib::Printf( "vertex buffer alloc %p, api %p (%i bytes)\n", this, bufferHandle.Get(), GetSize() );
}
// copy the data
if( data != NULL )
{
Update( data, allocSize, 0, true, commandList );
}
return !allocationFailed;
}
/*
========================
idVertexBuffer::FreeBufferObject
========================
*/
void idVertexBuffer::FreeBufferObject()
{
if( IsMapped() )
{
UnmapBuffer();
}
// if this is a sub-allocation inside a larger buffer, don't actually free anything.
if( OwnsBuffer() == false )
{
ClearWithoutFreeing();
return;
}
if( !bufferHandle )
{
return;
}
if( r_showBuffers.GetBool() )
{
idLib::Printf( "vertex buffer free %p, api %p (%i bytes)\n", this, bufferHandle.Get(), GetSize() );
}
bufferHandle.Reset();
ClearWithoutFreeing();
}
/*
========================
idVertexBuffer::Update
========================
*/
void idVertexBuffer::Update( const void* data, int updateSize, int offset, bool initialUpdate, nvrhi::ICommandList* commandList ) const
{
assert( bufferHandle );
assert_16_byte_aligned( data );
assert( ( GetOffset() & 15 ) == 0 );
if( updateSize > GetSize() )
{
idLib::FatalError( "idVertexBuffer::Update: size overrun, %i > %i\n", updateSize, GetSize() );
}
int numBytes = ( updateSize + 15 ) & ~15;
if( usage == BU_DYNAMIC )
{
CopyBuffer( ( byte* )buffer + offset, ( const byte* )data, numBytes );
}
else
{
if( initialUpdate )
{
commandList->beginTrackingBufferState( bufferHandle, nvrhi::ResourceStates::Common );
commandList->writeBuffer( bufferHandle, data, numBytes, GetOffset() + offset );
commandList->setPermanentBufferState( bufferHandle, nvrhi::ResourceStates::ShaderResource | nvrhi::ResourceStates::VertexBuffer );
}
else
{
commandList->writeBuffer( bufferHandle, data, numBytes, GetOffset() + offset );
}
}
}
/*
========================
idVertexBuffer::MapBuffer
========================
*/
void* idVertexBuffer::MapBuffer( bufferMapType_t mapType )
{
assert( bufferHandle );
assert( IsMapped() == false );
nvrhi::CpuAccessMode accessMode = nvrhi::CpuAccessMode::Write;
if( mapType == bufferMapType_t::BM_READ )
{
accessMode = nvrhi::CpuAccessMode::Read;
}
buffer = deviceManager->GetDevice()->mapBuffer( bufferHandle, accessMode );
SetMapped();
if( buffer == NULL )
{
idLib::FatalError( "idVertexBuffer::MapBuffer: failed" );
}
return buffer;
}
/*
========================
idVertexBuffer::UnmapBuffer
========================
*/
void idVertexBuffer::UnmapBuffer()
{
assert( bufferHandle );
assert( IsMapped() );
if( deviceManager && deviceManager->GetDevice() )
{
deviceManager->GetDevice()->unmapBuffer( bufferHandle );
}
SetUnmapped();
}
/*
========================
idVertexBuffer::ClearWithoutFreeing
========================
*/
void idVertexBuffer::ClearWithoutFreeing()
{
size = 0;
offsetInOtherBuffer = OWNS_BUFFER_FLAG;
bufferHandle.Reset();
}
/*
================================================================================================
idIndexBuffer
================================================================================================
*/
/*
========================
idIndexBuffer::idIndexBuffer
========================
*/
idIndexBuffer::idIndexBuffer()
{
size = 0;
offsetInOtherBuffer = OWNS_BUFFER_FLAG;
bufferHandle.Reset();
SetUnmapped();
}
/*
========================
idIndexBuffer::AllocBufferObject
========================
*/
bool idIndexBuffer::AllocBufferObject( const void* data, int allocSize, bufferUsageType_t _usage, nvrhi::ICommandList* commandList )
{
assert( !bufferHandle );
assert_16_byte_aligned( data );
if( allocSize <= 0 )
{
idLib::Error( "idIndexBuffer::AllocBufferObject: allocSize = %i", allocSize );
}
size = allocSize;
usage = _usage;
int numBytes = GetAllocedSize();
nvrhi::BufferDesc indexBufferDesc;
indexBufferDesc.byteSize = numBytes;
indexBufferDesc.isIndexBuffer = true;
indexBufferDesc.initialState = nvrhi::ResourceStates::Common;
indexBufferDesc.canHaveRawViews = true;
indexBufferDesc.canHaveTypedViews = true;
indexBufferDesc.format = nvrhi::Format::R16_UINT;
if( _usage == BU_STATIC )
{
indexBufferDesc.debugName = "VertexCache Static Index Buffer";
indexBufferDesc.keepInitialState = true;
}
else if( _usage == BU_DYNAMIC )
{
indexBufferDesc.debugName = "VertexCache Mapped Index Buffer";
indexBufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
indexBufferDesc.cpuAccess = nvrhi::CpuAccessMode::Write;
}
bufferHandle = deviceManager->GetDevice()->createBuffer( indexBufferDesc );
if( data )
{
Update( data, allocSize, 0, true, commandList );
}
return true;
}
/*
========================
idIndexBuffer::FreeBufferObject
========================
*/
void idIndexBuffer::FreeBufferObject()
{
if( IsMapped() )
{
UnmapBuffer();
}
// if this is a sub-allocation inside a larger buffer, don't actually free anything.
if( OwnsBuffer() == false )
{
ClearWithoutFreeing();
return;
}
if( !bufferHandle )
{
return;
}
if( r_showBuffers.GetBool() )
{
idLib::Printf( "index buffer free %p, api %p (%i bytes)\n", this, bufferHandle.Get(), GetSize() );
}
bufferHandle.Reset();
ClearWithoutFreeing();
}
/*
========================
idIndexBuffer::Update
========================
*/
void idIndexBuffer::Update( const void* data, int updateSize, int offset, bool initialUpdate, nvrhi::ICommandList* commandList ) const
{
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() );
}
int numBytes = ( updateSize + 15 ) & ~15;
if( usage == BU_DYNAMIC )
{
void* buffer = deviceManager->GetDevice()->mapBuffer( bufferHandle, nvrhi::CpuAccessMode::Write );
CopyBuffer( ( byte* )buffer + offset, ( const byte* )data, numBytes );
}
else
{
if( initialUpdate )
{
commandList->beginTrackingBufferState( bufferHandle, nvrhi::ResourceStates::Common );
commandList->writeBuffer( bufferHandle, data, numBytes, GetOffset() + offset );
commandList->setPermanentBufferState( bufferHandle, nvrhi::ResourceStates::IndexBuffer | nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
}
else
{
commandList->writeBuffer( bufferHandle, data, numBytes, GetOffset() + offset );
}
}
}
/*
========================
idIndexBuffer::MapBuffer
========================
*/
void* idIndexBuffer::MapBuffer( bufferMapType_t mapType )
{
assert( bufferHandle );
assert( IsMapped() == false );
nvrhi::CpuAccessMode accessMode = nvrhi::CpuAccessMode::Write;
if( mapType == bufferMapType_t::BM_READ )
{
accessMode = nvrhi::CpuAccessMode::Read;
}
buffer = deviceManager->GetDevice()->mapBuffer( bufferHandle, accessMode );
SetMapped();
if( buffer == NULL )
{
idLib::FatalError( "idVertexBuffer::MapBuffer: failed" );
}
return buffer;
}
/*
========================
idIndexBuffer::UnmapBuffer
========================
*/
void idIndexBuffer::UnmapBuffer()
{
assert( bufferHandle );
assert( IsMapped() );
if( deviceManager && deviceManager->GetDevice() )
{
deviceManager->GetDevice()->unmapBuffer( bufferHandle );
}
SetUnmapped();
}
/*
========================
idIndexBuffer::ClearWithoutFreeing
========================
*/
void idIndexBuffer::ClearWithoutFreeing()
{
size = 0;
offsetInOtherBuffer = OWNS_BUFFER_FLAG;
bufferHandle.Reset();
}
/*
================================================================================================
idUniformBuffer
================================================================================================
*/
/*
========================
idUniformBuffer::idUniformBuffer
========================
*/
idUniformBuffer::idUniformBuffer()
{
size = 0;
offsetInOtherBuffer = OWNS_BUFFER_FLAG;
bufferHandle.Reset();
SetUnmapped();
}
/*
========================
idUniformBuffer::AllocBufferObject
========================
*/
bool idUniformBuffer::AllocBufferObject( const void* data, int allocSize, bufferUsageType_t _usage, nvrhi::ICommandList* commandList )
{
assert( !bufferHandle );
assert_16_byte_aligned( data );
if( allocSize <= 0 )
{
idLib::Error( "idIndexBuffer::AllocBufferObject: allocSize = %i", allocSize );
}
size = allocSize;
usage = _usage;
bool allocationFailed = false;
int numBytes = GetAllocedSize();
nvrhi::BufferDesc bufferDesc;
bufferDesc.byteSize = numBytes;
bufferDesc.isConstantBuffer = true;
bufferDesc.initialState = nvrhi::ResourceStates::Common;
if( usage == BU_DYNAMIC )
{
bufferDesc.debugName = "ConstantBuffer";
bufferDesc.initialState = nvrhi::ResourceStates::CopyDest;
bufferDesc.cpuAccess = nvrhi::CpuAccessMode::Write;
}
else
{
bufferDesc.keepInitialState = true;
}
bufferHandle = deviceManager->GetDevice()->createBuffer( bufferDesc );
// copy the data
if( data != NULL )
{
Update( data, allocSize, 0, true, commandList );
}
return !allocationFailed;
}
/*
========================
idUniformBuffer::FreeBufferObject
========================
*/
void idUniformBuffer::FreeBufferObject()
{
}
/*
========================
idUniformBuffer::Update
========================
*/
void idUniformBuffer::Update( const void* data, int updateSize, int offset, bool initialUpdate, nvrhi::ICommandList* commandList ) const
{
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() );
}
int numBytes = ( updateSize + 15 ) & ~15;
if( usage == BU_DYNAMIC )
{
void* buffer = deviceManager->GetDevice()->mapBuffer( bufferHandle, nvrhi::CpuAccessMode::Write );
CopyBuffer( ( byte* )buffer + offset, ( const byte* )data, numBytes );
}
else
{
if( initialUpdate )
{
commandList->beginTrackingBufferState( bufferHandle, nvrhi::ResourceStates::Common );
commandList->writeBuffer( bufferHandle, data, numBytes, GetOffset() + offset );
commandList->setPermanentBufferState( bufferHandle, nvrhi::ResourceStates::ConstantBuffer | nvrhi::ResourceStates::ShaderResource );
}
else
{
commandList->writeBuffer( bufferHandle, data, numBytes, GetOffset() + offset );
}
}
}
/*
========================
idUniformBuffer::MapBuffer
========================
*/
void* idUniformBuffer::MapBuffer( bufferMapType_t mapType )
{
assert( bufferHandle );
assert( IsMapped() == false );
nvrhi::CpuAccessMode accessMode = nvrhi::CpuAccessMode::Write;
if( mapType == bufferMapType_t::BM_READ )
{
accessMode = nvrhi::CpuAccessMode::Read;
}
buffer = deviceManager->GetDevice()->mapBuffer( bufferHandle, accessMode );
SetMapped();
if( buffer == NULL )
{
idLib::FatalError( "idUniformBuffer::MapBuffer: failed" );
}
return buffer;
}
/*
========================
idUniformBuffer::UnmapBuffer
========================
*/
void idUniformBuffer::UnmapBuffer()
{
assert( bufferHandle );
assert( IsMapped() );
if( deviceManager && deviceManager->GetDevice() )
{
deviceManager->GetDevice()->unmapBuffer( bufferHandle );
}
SetUnmapped();
}
/*
========================
idUniformBuffer::ClearWithoutFreeing
========================
*/
void idUniformBuffer::ClearWithoutFreeing()
{
size = 0;
offsetInOtherBuffer = OWNS_BUFFER_FLAG;
bufferHandle.Reset();
}

View file

@ -0,0 +1,278 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 2014-2020 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "precompiled.h"
#pragma hdrstop
#include "../RenderCommon.h"
#include "../Framebuffer.h"
#include "sys/DeviceManager.h"
extern DeviceManager* deviceManager;
static void R_ListFramebuffers_f( const idCmdArgs& args )
{
if( !glConfig.framebufferObjectAvailable )
{
common->Printf( "GL_EXT_framebuffer_object is not available.\n" );
return;
}
}
Framebuffer::Framebuffer( const char* name, int w, int h )
: fboName( name )
, frameBuffer( 0 )
, colorFormat( 0 )
, depthBuffer( 0 )
, depthFormat( 0 )
, stencilFormat( 0 )
, stencilBuffer( 0 )
, width( w )
, height( h )
, msaaSamples( false )
{
framebuffers.Append( this );
}
Framebuffer::Framebuffer( const char* name, const nvrhi::FramebufferDesc& desc )
: fboName( name )
, frameBuffer( 0 )
, colorFormat( 0 )
, depthBuffer( 0 )
, depthFormat( 0 )
, stencilFormat( 0 )
, stencilBuffer( 0 )
, msaaSamples( false )
{
framebuffers.Append( this );
apiObject = deviceManager->GetDevice()->createFramebuffer( desc );
width = apiObject->getFramebufferInfo().width;
height = apiObject->getFramebufferInfo().height;
}
Framebuffer::~Framebuffer()
{
}
void Framebuffer::Init()
{
cmdSystem->AddCommand( "listFramebuffers", R_ListFramebuffers_f, CMD_FL_RENDERER, "lists framebuffers" );
// HDR
ResizeFramebuffers();
}
void Framebuffer::CheckFramebuffers()
{
int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight();
}
void Framebuffer::Shutdown()
{
framebuffers.DeleteContents( true );
}
void Framebuffer::ResizeFramebuffers()
{
tr.backend.pipelineCache.Clear();
uint32_t backBufferCount = deviceManager->GetBackBufferCount();
globalFramebuffers.swapFramebuffers.Resize( backBufferCount );
globalFramebuffers.swapFramebuffers.SetNum( backBufferCount );
int screenWidth = renderSystem->GetWidth();
int screenHeight = renderSystem->GetHeight();
tr.backend.commandList->open();
globalImages->currentRenderLDR->Reload( false, tr.backend.commandList );
globalImages->currentRenderImage->Reload( false, tr.backend.commandList );
globalImages->currentDepthImage->Reload( false, tr.backend.commandList );
globalImages->currentRenderHDRImage->Reload( false, tr.backend.commandList );
globalImages->currentRenderHDRImage64->Reload( false, tr.backend.commandList );
for( int i = 0; i < MAX_SSAO_BUFFERS; i++ )
{
globalImages->ambientOcclusionImage[i]->Reload( false, tr.backend.commandList );
}
globalImages->hierarchicalZbufferImage->Reload( false, tr.backend.commandList );
globalImages->currentNormalsImage->Reload( false, tr.backend.commandList );
globalImages->smaaEdgesImage->Reload( false, tr.backend.commandList );
globalImages->smaaBlendImage->Reload( false, tr.backend.commandList );
for( int i = 0; i < MAX_SHADOWMAP_RESOLUTIONS; i++ )
{
globalImages->shadowImage[i]->Reload( false, tr.backend.commandList );
}
tr.backend.commandList->close();
deviceManager->GetDevice()->executeCommandList( tr.backend.commandList );
for( uint32_t index = 0; index < backBufferCount; index++ )
{
globalFramebuffers.swapFramebuffers[index] = new Framebuffer(
va( "_swapChain%d", index ),
nvrhi::FramebufferDesc()
.addColorAttachment( deviceManager->GetBackBuffer( index ) ) );
}
for( int arr = 0; arr < 6; arr++ )
{
for( int mip = 0; mip < MAX_SHADOWMAP_RESOLUTIONS; mip++ )
{
globalFramebuffers.shadowFBO[mip][arr] = new Framebuffer( va( "_shadowMap%i_%i", mip, arr ),
nvrhi::FramebufferDesc().setDepthAttachment(
nvrhi::FramebufferAttachment()
.setTexture( globalImages->shadowImage[mip]->GetTextureHandle().Get() )
.setArraySlice( arr ) ) );
}
}
globalFramebuffers.ldrFBO = new Framebuffer( "_ldr",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->currentRenderLDR->texture )
.setDepthAttachment( globalImages->currentDepthImage->texture ) );
globalFramebuffers.hdrFBO = new Framebuffer( "_hdr",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->currentRenderHDRImage->texture )
.setDepthAttachment( globalImages->currentDepthImage->texture ) );
globalFramebuffers.postProcFBO = new Framebuffer( "_postProc",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->currentRenderImage->texture ) );
globalFramebuffers.envprobeFBO = new Framebuffer( "_envprobeRender",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->envprobeHDRImage->texture )
.setDepthAttachment( globalImages->envprobeDepthImage->texture ) );
globalFramebuffers.hdr64FBO = new Framebuffer( "_hdr64",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->currentRenderHDRImage64->texture ) );
for( int i = 0; i < MAX_SSAO_BUFFERS; i++ )
{
globalFramebuffers.ambientOcclusionFBO[i] = new Framebuffer( va( "_aoRender%i", i ),
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->ambientOcclusionImage[i]->texture ) );
}
// HIERARCHICAL Z BUFFER
for( int i = 0; i < MAX_HIERARCHICAL_ZBUFFERS; i++ )
{
globalFramebuffers.csDepthFBO[i] = new Framebuffer( va( "_csz%d", i ),
nvrhi::FramebufferDesc().addColorAttachment(
nvrhi::FramebufferAttachment()
.setTexture( globalImages->hierarchicalZbufferImage->texture )
.setMipLevel( i ) ) );
}
globalFramebuffers.geometryBufferFBO = new Framebuffer( "_gbuffer",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->currentNormalsImage->texture )
.setDepthAttachment( globalImages->currentDepthImage->texture ) );
globalFramebuffers.smaaEdgesFBO = new Framebuffer( "_smaaEdges",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->smaaEdgesImage->texture ) );
globalFramebuffers.smaaEdgesFBO = new Framebuffer( "_smaaBlend",
nvrhi::FramebufferDesc()
.addColorAttachment( globalImages->smaaBlendImage->texture ) );
Framebuffer::Unbind();
}
void Framebuffer::Bind()
{
RENDERLOG_PRINTF( "Framebuffer::Bind( %s )\n", fboName.c_str() );
if( tr.backend.currentFrameBuffer != this )
{
tr.backend.currentPipeline = nullptr;
}
tr.backend.currentFrameBuffer = this;
}
bool Framebuffer::IsBound()
{
return tr.backend.currentFrameBuffer == this;
}
void Framebuffer::Unbind()
{
RENDERLOG_PRINTF( "Framebuffer::Unbind()\n" );
globalFramebuffers.swapFramebuffers[deviceManager->GetCurrentBackBufferIndex()]->Bind();
}
bool Framebuffer::IsDefaultFramebufferActive()
{
return tr.backend.currentFrameBuffer == globalFramebuffers.swapFramebuffers[deviceManager->GetCurrentBackBufferIndex()];
}
Framebuffer* Framebuffer::GetActiveFramebuffer()
{
return tr.backend.currentFrameBuffer;
}
void Framebuffer::AddColorBuffer( int format, int index, int multiSamples )
{
}
void Framebuffer::AddDepthBuffer( int format, int multiSamples )
{
}
void Framebuffer::AddStencilBuffer( int format, int multiSamples )
{
}
void Framebuffer::AttachImage2D( int target, const idImage* image, int index, int mipmapLod )
{
}
void Framebuffer::AttachImageDepth( int target, const idImage* image )
{
}
void Framebuffer::AttachImageDepthLayer( const idImage* image, int layer )
{
}
void Framebuffer::Check()
{
}
idScreenRect Framebuffer::GetViewPortInfo() const
{
nvrhi::Viewport viewport = apiObject->getFramebufferInfo().getViewport();
idScreenRect screenRect;
screenRect.Clear();
screenRect.AddPoint( viewport.minX, viewport.minY );
screenRect.AddPoint( viewport.maxX, viewport.maxY );
return screenRect;
}

View file

@ -0,0 +1,467 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2016 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "precompiled.h"
#pragma hdrstop
/*
================================================================================================
Contains the Image implementation for OpenGL.
================================================================================================
*/
#include "../RenderCommon.h"
#include "sys/DeviceManager.h"
extern DeviceManager* deviceManager;
/*
====================
idImage::idImage
====================
*/
idImage::idImage( const char* name ) : imgName( name )
{
texture.Reset();
generatorFunction = NULL;
filter = TF_DEFAULT;
repeat = TR_REPEAT;
usage = TD_DEFAULT;
cubeFiles = CF_2D;
cubeMapSize = 0;
isLoaded = false;
referencedOutsideLevelLoad = false;
levelLoadReferenced = false;
defaulted = false;
sourceFileTime = FILE_NOT_FOUND_TIMESTAMP;
binaryFileTime = FILE_NOT_FOUND_TIMESTAMP;
refCount = 0;
DeferredLoadImage();
}
/*
====================
idImage::~idImage
====================
*/
idImage::~idImage()
{
PurgeImage();
}
/*
====================
idImage::IsLoaded
====================
*/
bool idImage::IsLoaded() const
{
return isLoaded;
}
void idImage::CreateSampler()
{
sampler.Reset();
samplerDesc = nvrhi::SamplerDesc()
.setAllFilters( false )
.setAllAddressModes( nvrhi::SamplerAddressMode::Clamp )
.setMaxAnisotropy( 1.0f );
if( opts.format == FMT_DEPTH || opts.format == FMT_DEPTH_STENCIL )
{
samplerDesc.setReductionType( nvrhi::SamplerReductionType::Comparison );
}
switch( filter )
{
case TF_DEFAULT:
samplerDesc.minFilter = true;
samplerDesc.setAllFilters( true )
.setMaxAnisotropy( r_maxAnisotropicFiltering.GetInteger() );
break;
case TF_LINEAR:
samplerDesc.setAllFilters( true );
break;
case TF_NEAREST:
samplerDesc.setAllFilters( false );
break;
// RB:
case TF_NEAREST_MIPMAP:
samplerDesc.setAllFilters( false );
break;
default:
idLib::FatalError( "idImage::CreateSampler: unrecognized texture filter %d", filter );
}
switch( repeat )
{
case TR_REPEAT:
samplerDesc.setAddressU( nvrhi::SamplerAddressMode::Repeat )
.setAddressV( nvrhi::SamplerAddressMode::Repeat )
.setAddressW( nvrhi::SamplerAddressMode::Repeat );
break;
case TR_CLAMP:
samplerDesc.setAddressU( nvrhi::SamplerAddressMode::ClampToEdge )
.setAddressV( nvrhi::SamplerAddressMode::ClampToEdge )
.setAddressW( nvrhi::SamplerAddressMode::ClampToEdge );
break;
case TR_CLAMP_TO_ZERO_ALPHA:
samplerDesc.setBorderColor( nvrhi::Color( 0.f, 0.f, 0.f, 0.f ) )
.setAddressU( nvrhi::SamplerAddressMode::ClampToBorder )
.setAddressV( nvrhi::SamplerAddressMode::ClampToBorder )
.setAddressW( nvrhi::SamplerAddressMode::ClampToBorder );
break;
case TR_CLAMP_TO_ZERO:
samplerDesc.setBorderColor( nvrhi::Color( 0.f, 0.f, 0.f, 1.f ) )
.setAddressU( nvrhi::SamplerAddressMode::ClampToBorder )
.setAddressV( nvrhi::SamplerAddressMode::ClampToBorder )
.setAddressW( nvrhi::SamplerAddressMode::ClampToBorder );
break;
default:
idLib::FatalError( "idImage::CreateSampler: unrecognized texture repeat mode %d", repeat );
}
//sampler = deviceManager->GetDevice()->createSampler( samplerDesc );
}
/*
==============
Bind
Automatically enables 2D mapping or cube mapping if needed
==============
*/
void idImage::Bind()
{
RENDERLOG_PRINTF( "idImage::Bind( %s )\n", GetName() );
tr.backend.SetCurrentImage( this );
}
/*
====================
CopyFramebuffer
====================
*/
void idImage::CopyFramebuffer( int x, int y, int imageWidth, int imageHeight )
{
tr.backend.pc.c_copyFrameBuffer++;
}
/*
====================
CopyDepthbuffer
====================
*/
void idImage::CopyDepthbuffer( int x, int y, int imageWidth, int imageHeight )
{
tr.backend.pc.c_copyFrameBuffer++;
}
/*
========================
idImage::SubImageUpload
========================
*/
void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int height, const void* pic, nvrhi::ICommandList* commandList, int pixelPitch )
{
assert( x >= 0 && y >= 0 && mipLevel >= 0 && width >= 0 && height >= 0 && mipLevel < opts.numLevels );
}
/*
========================
idImage::SetSamplerState
========================
*/
void idImage::SetSamplerState( textureFilter_t tf, textureRepeat_t tr )
{
}
/*
========================
idImage::SetTexParameters
========================
*/
void idImage::SetTexParameters()
{
}
/*
========================
idImage::AllocImage
Every image will pass through this function. Allocates all the necessary MipMap levels for the
Image, but doesn't put anything in them.
This should not be done during normal game-play, if you can avoid it.
========================
*/
void idImage::AllocImage()
{
PurgeImage();
nvrhi::Format format = nvrhi::Format::RGBA8_UINT;
int bpp = 4;
CreateSampler();
switch( opts.format )
{
case FMT_RGBA8:
format = nvrhi::Format::RGBA8_UNORM;
break;
case FMT_XRGB8:
format = nvrhi::Format::X32G8_UINT;
break;
case FMT_RGB565:
format = nvrhi::Format::B5G6R5_UNORM;
break;
case FMT_ALPHA:
format = nvrhi::Format::R8_UINT;
break;
case FMT_L8A8:
format = nvrhi::Format::RG8_UINT;
break;
case FMT_LUM8:
format = nvrhi::Format::R8_UINT;
break;
case FMT_INT8:
format = nvrhi::Format::R8_UINT;
break;
case FMT_R8:
format = nvrhi::Format::R8_UNORM;
break;
case FMT_DXT1:
format = nvrhi::Format::BC1_UNORM_SRGB;
break;
case FMT_DXT5:
// This is used for compressed normals
format = nvrhi::Format::BC3_UNORM_SRGB;
if( usage == TD_BUMP )
{
format = nvrhi::Format::BC3_UNORM;
}
break;
case FMT_DEPTH:
format = nvrhi::Format::D32;
break;
case FMT_DEPTH_STENCIL:
format = nvrhi::Format::D24S8;
break;
case FMT_SHADOW_ARRAY:
format = nvrhi::Format::D32;
break;
case FMT_RG16F:
format = nvrhi::Format::RG16_FLOAT;
break;
case FMT_RGBA16F:
format = nvrhi::Format::RGBA16_FLOAT;
break;
case FMT_RGBA32F:
format = nvrhi::Format::RGBA32_FLOAT;
break;
case FMT_R32F:
format = nvrhi::Format::R32_FLOAT;
break;
case FMT_X16:
//internalFormat = GL_INTENSITY16;
//dataFormat = GL_LUMINANCE;
//dataType = GL_UNSIGNED_SHORT;
//format = nvrhi::Format::Lum
break;
case FMT_Y16_X16:
//internalFormat = GL_LUMINANCE16_ALPHA16;
//dataFormat = GL_LUMINANCE_ALPHA;
//dataType = GL_UNSIGNED_SHORT;
break;
// see http://what-when-how.com/Tutorial/topic-615ll9ug/Praise-for-OpenGL-ES-30-Programming-Guide-291.html
case FMT_R11G11B10F:
format = nvrhi::Format::R11G11B10_FLOAT;
break;
default:
idLib::Error( "Unhandled image format %d in %s\n", opts.format, GetName() );
}
// if we don't have a rendering context, just return after we
// have filled in the parms. We must have the values set, or
// an image match from a shader before OpenGL starts would miss
// the generated texture
if( !tr.IsInitialized() )
{
return;
}
int compressedSize = 0;
uint originalWidth = opts.width;
uint originalHeight = opts.height;
if( IsCompressed() )
{
originalWidth = ( originalWidth + 3 ) & ~3;
originalHeight = ( originalHeight + 3 ) & ~3;
}
uint scaledWidth = originalWidth;
uint scaledHeight = originalHeight;
uint maxTextureSize = 0;
if( maxTextureSize > 0 &&
int( std::max( originalWidth, originalHeight ) ) > maxTextureSize &&
opts.isRenderTarget &&
opts.textureType == TT_2D )
{
if( originalWidth >= originalHeight )
{
scaledHeight = originalHeight * maxTextureSize / originalWidth;
scaledWidth = maxTextureSize;
}
else
{
scaledWidth = originalWidth * maxTextureSize / originalHeight;
scaledHeight = maxTextureSize;
}
}
auto textureDesc = nvrhi::TextureDesc()
.setDebugName( GetName() )
.setDimension( nvrhi::TextureDimension::Texture2D )
.setWidth( scaledWidth )
.setHeight( scaledHeight )
.setFormat( format )
.setSampleCount( opts.samples )
.setMipLevels( opts.numLevels );
if( opts.isRenderTarget )
{
//textureDesc.keepInitialState = true;
//textureDesc.setKeepInitialState( true );
textureDesc.setInitialState( nvrhi::ResourceStates::RenderTarget )
.setClearValue( nvrhi::Color( 0.f ) )
.setIsRenderTarget( true )
.setKeepInitialState( true );
if( opts.format == FMT_DEPTH || opts.format == FMT_DEPTH_STENCIL || opts.format == FMT_SHADOW_ARRAY )
{
textureDesc.setInitialState( nvrhi::ResourceStates::DepthWrite )
.setClearValue( nvrhi::Color( 1.f ) );
}
if( opts.format == FMT_R32F || opts.format == FMT_R8 )
{
// TODO(Stephen): Probably make this an image option.
// This is a hack to make cszBuffer and ambient occlusion uav work.
textureDesc.setIsUAV( true );
}
}
if( opts.textureType == TT_2D )
{
textureDesc.setDimension( nvrhi::TextureDimension::Texture2D );
}
else if( opts.textureType == TT_CUBIC )
{
textureDesc.setDimension( nvrhi::TextureDimension::TextureCube );
textureDesc.setArraySize( 6 );
}
// RB begin
else if( opts.textureType == TT_2D_ARRAY )
{
textureDesc.setDimension( nvrhi::TextureDimension::Texture2DArray );
textureDesc.setArraySize( 6 );
}
else if( opts.textureType == TT_2D_MULTISAMPLE )
{
textureDesc.setDimension( nvrhi::TextureDimension::Texture2DMS );
textureDesc.setArraySize( 1 );
}
texture = deviceManager->GetDevice()->createTexture( textureDesc );
assert( texture );
}
/*
========================
idImage::PurgeImage
========================
*/
void idImage::PurgeImage()
{
texture.Reset();
sampler.Reset();
isLoaded = false;
defaulted = false;
}
/*
========================
idImage::Resize
========================
*/
void idImage::Resize( int width, int height )
{
if( opts.width == width && opts.height == height )
{
return;
}
opts.width = width;
opts.height = height;
AllocImage();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,285 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2018 Robert Beckebans
Copyright (C) 2016-2017 Dustin Land
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "precompiled.h"
#pragma hdrstop
#include "../RenderCommon.h"
#include "nvrhi/common/shader-blob.h"
#include <sys/DeviceManager.h>
idCVar r_displayGLSLCompilerMessages( "r_displayGLSLCompilerMessages", "1", CVAR_BOOL | CVAR_ARCHIVE, "Show info messages the GPU driver outputs when compiling the shaders" );
idCVar r_alwaysExportGLSL( "r_alwaysExportGLSL", "1", CVAR_BOOL, "" );
/*
========================
idRenderProgManager::StartFrame
========================
*/
void idRenderProgManager::StartFrame()
{
}
/*
================================================================================================
idRenderProgManager::BindProgram
================================================================================================
*/
void idRenderProgManager::BindProgram( int index )
{
if( currentIndex == index )
{
return;
}
currentIndex = index;
RENDERLOG_PRINTF( "Binding HLSL Program %s\n", renderProgs[index].name.c_str() );
renderProg_t& prog = renderProgs[index];
tr.backend.BindProgram( shaders[prog.vertexShaderIndex].handle,
shaders[prog.fragmentShaderIndex].handle,
prog.inputLayout,
prog.bindingLayout );
renderProgs[index].bindingLayout;
}
/*
================================================================================================
idRenderProgManager::Unbind
================================================================================================
*/
void idRenderProgManager::Unbind()
{
currentIndex = -1;
}
/*
================================================================================================
idRenderProgManager::LoadShader
================================================================================================
*/
void idRenderProgManager::LoadShader( int index, rpStage_t stage )
{
if( shaders[index].handle )
{
return; // Already loaded
}
LoadShader( shaders[index] );
}
extern DeviceManager* deviceManager;
/*
================================================================================================
idRenderProgManager::LoadGLSLShader
================================================================================================
*/
void idRenderProgManager::LoadShader( shader_t& shader )
{
idStr stage;
nvrhi::ShaderType shaderType{};
if( shader.stage == SHADER_STAGE_VERTEX )
{
stage = "vs";
shaderType = nvrhi::ShaderType::Vertex;
}
else if( shader.stage == SHADER_STAGE_FRAGMENT )
{
stage = "ps";
shaderType = nvrhi::ShaderType::Pixel;
}
else if( shader.stage == SHADER_STAGE_COMPUTE )
{
stage = "cs";
shaderType = nvrhi::ShaderType::Compute;
}
idStr adjustedName = shader.name;
adjustedName.StripFileExtension();
//adjustedName.StripPath();
adjustedName = idStr( "renderprogs/dxil/" ) + adjustedName + "." + stage + ".bin";
ShaderBlob shaderBlob = GetBytecode( adjustedName );
if( !shaderBlob.data )
{
return;
}
idList<nvrhi::ShaderConstant> constants;
for( int i = 0; i < shader.macros.Num(); i++ )
{
constants.Append( nvrhi::ShaderConstant
{
shader.macros[i].name.c_str(),
shader.macros[i].definition.c_str()
} );
}
nvrhi::ShaderDesc desc = nvrhi::ShaderDesc( shaderType );
desc.debugName = shader.name;
nvrhi::ShaderDesc descCopy = desc;
// TODO(Stephen): Might not want to hard-code this.
descCopy.entryName = "main";
nvrhi::ShaderConstant* shaderConstant( nullptr );
nvrhi::ShaderHandle shaderHandle = nvrhi::createShaderPermutation( device, descCopy, shaderBlob.data, shaderBlob.size,
( constants.Num() > 0 ) ? &constants[0] : shaderConstant, uint32_t( constants.Num() ) );
shader.handle = shaderHandle;
}
ShaderBlob idRenderProgManager::GetBytecode( const char* fileName )
{
ShaderBlob blob;
blob.size = fileSystem->ReadFile( fileName, &blob.data );
if( !blob.data )
{
//common->Error( "Couldn't read the binary file for shader %s", fileName);
}
return blob;
}
/*
================================================================================================
idRenderProgManager::LoadGLSLProgram
================================================================================================
*/
void idRenderProgManager::LoadProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex )
{
renderProg_t& prog = renderProgs[programIndex];
prog.fragmentShaderIndex = fragmentShaderIndex;
prog.vertexShaderIndex = vertexShaderIndex;
if( prog.vertexLayout > 0 )
{
prog.inputLayout = device->createInputLayout(
&vertexLayoutDescs[prog.vertexLayout][0],
vertexLayoutDescs[prog.vertexLayout].Num(),
shaders[prog.vertexShaderIndex].handle );
}
prog.bindingLayout = bindingLayouts[prog.bindingLayoutType];
}
/*
================================================================================================
idRenderProgManager::FindProgram
================================================================================================
*/
int idRenderProgManager::FindProgram( const char* name, int vIndex, int fIndex, bindingLayoutType_t bindingType )
{
for( int i = 0; i < renderProgs.Num(); ++i )
{
if( ( renderProgs[i].vertexShaderIndex == vIndex ) && ( renderProgs[i].fragmentShaderIndex == fIndex ) )
{
return i;
}
}
renderProg_t program;
program.name = name;
program.vertexLayout = LAYOUT_DRAW_VERT;
program.bindingLayoutType = bindingType;
int index = renderProgs.Append( program );
LoadProgram( index, vIndex, fIndex );
return index;
}
/*
================================================================================================
idRenderProgManager::CommitUnforms
================================================================================================
*/
void idRenderProgManager::CommitUniforms( uint64 stateBits )
{
}
/*
================================================================================================
idRenderProgManager::KillAllShaders()
================================================================================================
*/
void idRenderProgManager::KillAllShaders()
{
Unbind();
for( int i = 0; i < shaders.Num(); i++ )
{
if( shaders[i].handle )
{
shaders[i].handle.Reset();
}
}
}
/*
================================================================================================
idRenderProgManager::SetUniformValue
================================================================================================
*/
void idRenderProgManager::SetUniformValue( const renderParm_t rp, const float* value )
{
for( int i = 0; i < 4; i++ )
{
uniforms[rp][i] = value[i];
}
}
/*
================================================================================================
idRenderProgManager::ZeroUniforms
================================================================================================
*/
void idRenderProgManager::ZeroUniforms()
{
memset( uniforms.Ptr(), 0, uniforms.Allocated() );
}
/*
================================================================================================
idRenderProgManager::CommitConstantBuffer
================================================================================================
*/
void idRenderProgManager::CommitConstantBuffer( nvrhi::ICommandList* commandList )
{
uniforms.Size();
commandList->writeBuffer( constantBuffer, &uniforms[0], uniforms.Allocated() );
}

View file

@ -4,6 +4,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2018 Robert Beckebans
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -33,7 +34,12 @@ If you have questions concerning this license or the applicable additional terms
#include "RenderCommon.h"
#if defined(USE_VULKAN)
#if defined( USE_NVRHI )
#include <sys/DeviceManager.h>
#include <nvrhi/utils.h>
#elif defined(USE_VULKAN)
extern idUniformBuffer emptyUBO;
@ -43,7 +49,6 @@ If you have questions concerning this license or the applicable additional terms
#endif
idRenderProgManager renderProgManager;
/*
@ -80,146 +85,335 @@ static void R_ReloadShaders( const idCmdArgs& args )
idRenderProgManager::Init()
================================================================================================
*/
void idRenderProgManager::Init()
void idRenderProgManager::Init( nvrhi::IDevice* _device )
{
common->Printf( "----- Initializing Render Shaders -----\n" );
for( int i = 0; i < MAX_BUILTINS; i++ )
{
builtinShaders[i] = -1;
}
#if defined( USE_NVRHI )
device = _device;
uniforms.SetNum( RENDERPARM_TOTAL, vec4_zero );
constantBuffer = device->createBuffer(
nvrhi::utils::CreateVolatileConstantBufferDesc( uniforms.Allocated(),
"RenderParams",
c_MaxRenderPassConstantBufferVersions ) );
// === Main draw vertex layout ===
vertexLayoutDescs.SetNum( NUM_VERTEX_LAYOUTS, idList<nvrhi::VertexAttributeDesc>() );
vertexLayoutDescs[LAYOUT_DRAW_VERT].Append(
nvrhi::VertexAttributeDesc()
.setName( "POSITION" )
.setFormat( nvrhi::Format::RGB32_FLOAT )
.setOffset( offsetof( idDrawVert, xyz ) )
.setElementStride( sizeof( idDrawVert ) ) );
vertexLayoutDescs[LAYOUT_DRAW_VERT].Append(
nvrhi::VertexAttributeDesc()
.setName( "TEXCOORD" )
.setFormat( nvrhi::Format::RG16_FLOAT )
.setOffset( offsetof( idDrawVert, st ) )
.setElementStride( sizeof( idDrawVert ) ) );
vertexLayoutDescs[LAYOUT_DRAW_VERT].Append(
nvrhi::VertexAttributeDesc()
.setName( "NORMAL" )
.setFormat( nvrhi::Format::RGBA8_UNORM )
.setOffset( offsetof( idDrawVert, normal ) )
.setElementStride( sizeof( idDrawVert ) ) );
vertexLayoutDescs[LAYOUT_DRAW_VERT].Append(
nvrhi::VertexAttributeDesc()
.setName( "TANGENT" )
.setFormat( nvrhi::Format::RGBA8_UNORM )
.setOffset( offsetof( idDrawVert, tangent ) )
.setElementStride( sizeof( idDrawVert ) ) );
vertexLayoutDescs[LAYOUT_DRAW_VERT].Append(
nvrhi::VertexAttributeDesc()
.setName( "COLOR" )
.setArraySize( 2 )
.setFormat( nvrhi::Format::RGBA8_UNORM )
.setOffset( offsetof( idDrawVert, color ) )
.setElementStride( sizeof( idDrawVert ) ) );
// === Shadow vertex ===
vertexLayoutDescs[LAYOUT_DRAW_SHADOW_VERT].Append(
nvrhi::VertexAttributeDesc()
.setName( "POSITION" )
.setFormat( nvrhi::Format::RGBA32_FLOAT )
.setOffset( offsetof( idShadowVert, xyzw ) )
.setElementStride( sizeof( idShadowVert ) ) );
// === Shadow vertex skinned ===
vertexLayoutDescs[LAYOUT_DRAW_SHADOW_VERT_SKINNED].Append(
nvrhi::VertexAttributeDesc()
.setName( "POSITION" )
.setFormat( nvrhi::Format::RGBA32_FLOAT )
.setOffset( offsetof( idShadowVertSkinned, xyzw ) )
.setElementStride( sizeof( idShadowVertSkinned ) ) );
vertexLayoutDescs[LAYOUT_DRAW_SHADOW_VERT_SKINNED].Append(
nvrhi::VertexAttributeDesc()
.setName( "COLOR" )
.setArraySize( 2 )
.setFormat( nvrhi::Format::RGBA8_UNORM )
.setOffset( offsetof( idShadowVertSkinned, color ) )
.setElementStride( sizeof( idShadowVertSkinned ) ) );
bindingLayouts.SetNum( NUM_BINDING_LAYOUTS );
auto defaultLayoutDesc = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) );
bindingLayouts[BINDING_LAYOUT_DEFAULT] = device->createBindingLayout( defaultLayoutDesc );
auto ambientIblLayoutDesc = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // specular
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // base color
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // brdf lut
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // ssao
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 7 ) ) // irradiance cube map
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 8 ) ) // radiance cube map 1
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 9 ) ) // radiance cube map 2
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 10 ) ) // radiance cube map 3
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) ) // normal sampler
.addItem( nvrhi::BindingLayoutItem::Sampler( 1 ) ) // specular sampler
.addItem( nvrhi::BindingLayoutItem::Sampler( 2 ) ) // base color sampler
.addItem( nvrhi::BindingLayoutItem::Sampler( 3 ) ) // brdf lut sampler
.addItem( nvrhi::BindingLayoutItem::Sampler( 4 ) ) // ssao sampler
.addItem( nvrhi::BindingLayoutItem::Sampler( 7 ) ) // irradiance sampler
.addItem( nvrhi::BindingLayoutItem::Sampler( 8 ) ) // radiance sampler 1
.addItem( nvrhi::BindingLayoutItem::Sampler( 9 ) ) // radiance sampler 2
.addItem( nvrhi::BindingLayoutItem::Sampler( 10 ) ); // radiance sampler 3
bindingLayouts[BINDING_LAYOUT_AMBIENT_LIGHTING_IBL] = device->createBindingLayout( ambientIblLayoutDesc );
auto blitLayoutDesc = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) ); // blit constants
bindingLayouts[BINDING_LAYOUT_BLIT] = device->createBindingLayout( blitLayoutDesc );
auto aoLayoutDesc = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 1 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 2 ) );
bindingLayouts[BINDING_LAYOUT_DRAW_AO] = device->createBindingLayout( aoLayoutDesc );
auto aoLayoutDesc2 = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) );
bindingLayouts[BINDING_LAYOUT_DRAW_AO1] = device->createBindingLayout( aoLayoutDesc2 );
auto interactionBindingLayout = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // specular
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // base color
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // light falloff
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // light projection
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 1 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 2 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 3 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 4 ) );
bindingLayouts[BINDING_LAYOUT_DRAW_INTERACTION] = device->createBindingLayout( interactionBindingLayout );
auto interactionSmBindingLayout = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // normal
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // specular
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // base color
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ) // light falloff
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 4 ) ) // light projection
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 5 ) ) // shadow map array
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 6 ) ) // jitter
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 1 ) );
bindingLayouts[BINDING_LAYOUT_DRAW_INTERACTION_SM] = device->createBindingLayout( interactionSmBindingLayout );
auto fogBindingLayout = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Sampler( 1 ) );
bindingLayouts[BINDING_LAYOUT_DRAW_FOG] = device->createBindingLayout( fogBindingLayout );
auto ppFxBindingLayout = nvrhi::BindingLayoutDesc()
.setVisibility( nvrhi::ShaderType::All )
.addItem( nvrhi::BindingLayoutItem::VolatileConstantBuffer( 0 ) )
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // current render
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // normal map
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // mask
.addItem( nvrhi::BindingLayoutItem::Sampler( 0 ) ); // Linear sampler
bindingLayouts[BINDING_LAYOUT_POST_PROCESS_CNM] = device->createBindingLayout( ppFxBindingLayout );
#endif
// RB: added checks for GPU skinning
struct builtinShaders_t
{
int index;
const char* name;
const char* nameOutSuffix;
uint32 shaderFeatures;
bool requireGPUSkinningSupport;
rpStage_t stages;
vertexLayoutType_t layout;
int index;
const char* name;
const char* nameOutSuffix;
idList<shaderMacro_t> macros;
bool requireGPUSkinningSupport;
rpStage_t stages;
vertexLayoutType_t layout;
bindingLayoutType_t bindingLayout;
} builtins[] =
{
{ BUILTIN_GUI, "builtin/gui", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_COLOR, "builtin/color", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_GUI, "builtin/gui", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_COLOR, "builtin/color", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB begin
{ BUILTIN_COLOR_SKINNED, "builtin/color", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_VERTEX_COLOR, "builtin/vertex_color", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTING, "builtin/lighting/ambient_lighting", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTING_SKINNED, "builtin/lighting/ambient_lighting", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_COLOR_SKINNED, "builtin/color", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_VERTEX_COLOR, "builtin/vertex_color", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_AMBIENT_LIGHTING, "builtin/lighting/ambient_lighting", "", { { "USE_GPU_SKINNING", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_AMBIENT_LIGHTING_SKINNED, "builtin/lighting/ambient_lighting", "_skinned", { { "USE_GPU_SKINNING", "1" }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_AMBIENT_LIGHTING_IBL, "builtin/lighting/ambient_lighting_IBL", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED, "builtin/lighting/ambient_lighting_IBL", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR, "builtin/lighting/ambient_lighting_IBL", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED, "builtin/lighting/ambient_lighting_IBL", "_PBR_skinned", BIT( USE_GPU_SKINNING | USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTING_IBL, "builtin/lighting/ambient_lighting_IBL", "", { { "USE_GPU_SKINNING", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED, "builtin/lighting/ambient_lighting_IBL", "_skinned", { { "USE_GPU_SKINNING", "1" }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR, "builtin/lighting/ambient_lighting_IBL", "_PBR", { { "USE_GPU_SKINNING", "0" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED, "builtin/lighting/ambient_lighting_IBL", "_PBR_skinned", { { "USE_GPU_SKINNING", "1" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL, "builtin/lighting/ambient_lightgrid_IBL", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED, "builtin/lighting/ambient_lightgrid_IBL", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR, "builtin/lighting/ambient_lightgrid_IBL", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED, "builtin/lighting/ambient_lightgrid_IBL", "_PBR_skinned", BIT( USE_GPU_SKINNING | USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL, "builtin/lighting/ambient_lightgrid_IBL", "", { { "USE_GPU_SKINNING", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED, "builtin/lighting/ambient_lightgrid_IBL", "_skinned", { { "USE_GPU_SKINNING", "1" }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR, "builtin/lighting/ambient_lightgrid_IBL", "_PBR", { { "USE_GPU_SKINNING", "0" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED, "builtin/lighting/ambient_lightgrid_IBL", "_PBR_skinned", { { "USE_GPU_SKINNING", "1" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_AMBIENT_LIGHTING_IBL },
{ BUILTIN_SMALL_GEOMETRY_BUFFER, "builtin/gbuffer", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED, "builtin/gbuffer", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SMALL_GEOMETRY_BUFFER, "builtin/gbuffer", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED, "builtin/gbuffer", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB end
{ BUILTIN_TEXTURED, "builtin/texture", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURE_VERTEXCOLOR, "builtin/texture_color", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SRGB, "builtin/texture_color", "_sRGB", BIT( USE_SRGB ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED, "builtin/texture_color_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR, "builtin/texture_color_texgen", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TEXTURED, "builtin/texture", "", { }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_TEXTURE_VERTEXCOLOR, "builtin/texture_color", "", { {"USE_GPU_SKINNING", "0" }, {"USE_SRGB", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SRGB, "builtin/texture_color", "_sRGB", { {"USE_GPU_SKINNING", "0" }, {"USE_SRGB", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED, "builtin/texture_color", "_skinned", { {"USE_GPU_SKINNING", "1" }, {"USE_SRGB", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR, "builtin/texture_color_texgen", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB begin
{ BUILTIN_INTERACTION, "builtin/lighting/interaction", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SKINNED, "builtin/lighting/interaction", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION, "builtin/lighting/interaction", "", { {"USE_GPU_SKINNING", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_INTERACTION_SKINNED, "builtin/lighting/interaction", "_skinned", { {"USE_GPU_SKINNING", "1" }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_INTERACTION_AMBIENT, "builtin/lighting/interactionAmbient", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_AMBIENT_SKINNED, "builtin/lighting/interactionAmbient_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_AMBIENT, "builtin/lighting/interactionAmbient", "", { {"USE_GPU_SKINNING", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_INTERACTION_AMBIENT_SKINNED, "builtin/lighting/interactionAmbient", "_skinned", { {"USE_GPU_SKINNING", "1" }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT, "builtin/lighting/interactionSM", "_spot", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "builtin/lighting/interactionSM", "_spot_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT, "builtin/lighting/interactionSM", "_spot", { {"USE_GPU_SKINNING", "0" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "builtin/lighting/interactionSM", "_spot_skinned", { {"USE_GPU_SKINNING", "1" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", 0 }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT, "builtin/lighting/interactionSM", "_point", BIT( LIGHT_POINT ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "builtin/lighting/interactionSM", "_point_skinned", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_POINT ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT, "builtin/lighting/interactionSM", "_point", { {"USE_GPU_SKINNING", "0" }, { "LIGHT_POINT", "1" }, { "LIGHT_PARALLEL", "0" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "builtin/lighting/interactionSM", "_point_skinned", { {"USE_GPU_SKINNING", "1" }, { "LIGHT_POINT", "1" }, { "LIGHT_PARALLEL", 0 }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL, "builtin/lighting/interactionSM", "_parallel", BIT( LIGHT_PARALLEL ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "builtin/lighting/interactionSM", "_parallel_skinned", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_PARALLEL ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL, "builtin/lighting/interactionSM", "_parallel", { {"USE_GPU_SKINNING", "0" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "1" }, { "USE_PBR", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "builtin/lighting/interactionSM", "_parallel_skinned", { {"USE_GPU_SKINNING", "1" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "1" }, { "USE_PBR", "0" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
// PBR variants
{ BUILTIN_PBR_INTERACTION, "builtin/lighting/interaction", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SKINNED, "builtin/lighting/interaction", "_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION, "builtin/lighting/interaction", "_PBR", { {"USE_GPU_SKINNING", "0" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_PBR_INTERACTION_SKINNED, "builtin/lighting/interaction", "_skinned_PBR", { {"USE_GPU_SKINNING", "1" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_PBR_INTERACTION_AMBIENT, "builtin/lighting/interactionAmbient", "_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED, "builtin/lighting/interactionAmbient_skinned", "_PBR", BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_AMBIENT, "builtin/lighting/interactionAmbient", "_PBR", { {"USE_GPU_SKINNING", "0" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED, "builtin/lighting/interactionAmbient_skinned", "_PBR", { {"USE_GPU_SKINNING", "1" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT, "builtin/lighting/interactionSM", "_spot_PBR", BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "builtin/lighting/interactionSM", "_spot_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT, "builtin/lighting/interactionSM", "_spot_PBR", { {"USE_GPU_SKINNING", "0" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "0" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED, "builtin/lighting/interactionSM", "_spot_skinned_PBR", { {"USE_GPU_SKINNING", "1" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "0" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT, "builtin/lighting/interactionSM", "_point_PBR", BIT( LIGHT_POINT ) | BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "builtin/lighting/interactionSM", "_point_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_POINT ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT, "builtin/lighting/interactionSM", "_point_PBR", { {"USE_GPU_SKINNING", "0" }, { "LIGHT_POINT", "1" }, { "LIGHT_PARALLEL", "0" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED, "builtin/lighting/interactionSM", "_point_skinned_PBR", { {"USE_GPU_SKINNING", "1" }, { "LIGHT_POINT", "1" }, { "LIGHT_PARALLEL", "0" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL, "builtin/lighting/interactionSM", "_parallel_PBR", BIT( LIGHT_PARALLEL ) | BIT( USE_PBR ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "builtin/lighting/interactionSM", "_parallel_skinned_PBR", BIT( USE_GPU_SKINNING ) | BIT( LIGHT_PARALLEL ) | BIT( USE_PBR ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL, "builtin/lighting/interactionSM", "_parallel_PBR", { {"USE_GPU_SKINNING", "0" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "1" }, { "USE_PBR", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
{ BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED, "builtin/lighting/interactionSM", "_parallel_skinned_PBR", { {"USE_GPU_SKINNING", "1" }, { "LIGHT_POINT", "0" }, { "LIGHT_PARALLEL", "1" }, { "USE_PBR", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_INTERACTION_SM },
// debug stuff
{ BUILTIN_DEBUG_LIGHTGRID, "builtin/debug/lightgrid", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEBUG_LIGHTGRID_SKINNED, "builtin/debug/lightgrid", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEBUG_LIGHTGRID, "builtin/debug/lightgrid", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEBUG_LIGHTGRID_SKINNED, "builtin/debug/lightgrid", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEBUG_OCTAHEDRON, "builtin/debug/octahedron", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEBUG_OCTAHEDRON_SKINNED, "builtin/debug/octahedron", "_skinned", BIT( USE_GPU_SKINNING ), true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEBUG_OCTAHEDRON, "builtin/debug/octahedron", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEBUG_OCTAHEDRON_SKINNED, "builtin/debug/octahedron", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB end
{ BUILTIN_ENVIRONMENT, "builtin/legacy/environment", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_ENVIRONMENT_SKINNED, "builtin/legacy/environment_skinned", "", 0, true , SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT},
{ BUILTIN_BUMPY_ENVIRONMENT, "builtin/legacy/bumpyenvironment", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_BUMPY_ENVIRONMENT_SKINNED, "builtin/legacy/bumpyenvironment_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_ENVIRONMENT, "builtin/legacy/environment", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_ENVIRONMENT_SKINNED, "builtin/legacy/environment", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true , SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_BUMPY_ENVIRONMENT, "builtin/legacy/bumpyenvironment", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_BUMPY_ENVIRONMENT_SKINNED, "builtin/legacy/bumpyenvironment", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEPTH, "builtin/depth", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEPTH_SKINNED, "builtin/depth_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEPTH, "builtin/depth", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEPTH_SKINNED, "builtin/depth", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SHADOW, "builtin/lighting/shadow", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_SHADOW_VERT },
{ BUILTIN_SHADOW_SKINNED, "builtin/lighting/shadow_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_SHADOW_VERT_SKINNED },
{ BUILTIN_SHADOW, "builtin/lighting/shadow", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_SHADOW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SHADOW_SKINNED, "builtin/lighting/shadow", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_SHADOW_VERT_SKINNED, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SHADOW_DEBUG, "builtin/debug/shadowDebug", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SHADOW_DEBUG_SKINNED, "builtin/debug/shadowDebug_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SHADOW_DEBUG, "builtin/debug/shadowDebug", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SHADOW_DEBUG_SKINNED, "builtin/debug/shadowDebug", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_BLENDLIGHT, "builtin/fog/blendlight", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_FOG, "builtin/fog/fog", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_FOG_SKINNED, "builtin/fog/fog_skinned", "", 0, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SKYBOX, "builtin/legacy/skybox", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_WOBBLESKY, "builtin/legacy/wobblesky", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_POSTPROCESS, "builtin/post/postprocess", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_BLENDLIGHT, "builtin/fog/blendlight", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_FOG, "builtin/fog/fog", "", { {"USE_GPU_SKINNING", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_FOG },
{ BUILTIN_FOG_SKINNED, "builtin/fog/fog", "_skinned", { {"USE_GPU_SKINNING", "1" } }, true, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_FOG },
{ BUILTIN_SKYBOX, "builtin/legacy/skybox", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_WOBBLESKY, "builtin/legacy/wobblesky", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_POSTPROCESS, "builtin/post/postprocess", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB begin
{ BUILTIN_SCREEN, "builtin/post/screen", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_TONEMAP, "builtin/post/tonemap", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_BRIGHTPASS, "builtin/post/tonemap", "_brightpass", BIT( BRIGHTPASS ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_HDR_GLARE_CHROMATIC, "builtin/post/hdr_glare_chromatic", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_HDR_DEBUG, "builtin/post/tonemap", "_debug", BIT( HDR_DEBUG ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SCREEN, "builtin/post/screen", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_TONEMAP, "builtin/post/tonemap", "", { { "BRIGHTPASS", "0" }, { "HDR_DEBUG", "0"} }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_BRIGHTPASS, "builtin/post/tonemap", "_brightpass", { { "BRIGHTPASS", "1" }, { "HDR_DEBUG", "0"} }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_HDR_GLARE_CHROMATIC, "builtin/post/hdr_glare_chromatic", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_HDR_DEBUG, "builtin/post/tonemap", "_debug", { { "BRIGHTPASS", "0" }, { "HDR_DEBUG", "1"} }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SMAA_EDGE_DETECTION, "builtin/post/SMAA_edge_detection", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SMAA_BLENDING_WEIGHT_CALCULATION, "builtin/post/SMAA_blending_weight_calc", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SMAA_NEIGHBORHOOD_BLENDING, "builtin/post/SMAA_final", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_SMAA_EDGE_DETECTION, "builtin/post/SMAA_edge_detection", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SMAA_BLENDING_WEIGHT_CALCULATION, "builtin/post/SMAA_blending_weight_calc", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_SMAA_NEIGHBORHOOD_BLENDING, "builtin/post/SMAA_final", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_AMBIENT_OCCLUSION, "builtin/SSAO/AmbientOcclusion_AO", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT, "builtin/SSAO/AmbientOcclusion_AO", "_write", BIT( BRIGHTPASS ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR, "builtin/SSAO/AmbientOcclusion_blur", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT, "builtin/SSAO/AmbientOcclusion_blur", "_write", BIT( BRIGHTPASS ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_OCCLUSION_MINIFY, "builtin/SSAO/AmbientOcclusion_minify", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_OCCLUSION_RECONSTRUCT_CSZ, "builtin/SSAO/AmbientOcclusion_minify", "_mip0", BIT( BRIGHTPASS ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEEP_GBUFFER_RADIOSITY_SSGI, "builtin/SSGI/DeepGBufferRadiosity_radiosity", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR, "builtin/SSGI/DeepGBufferRadiosity_blur", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR_AND_OUTPUT, "builtin/SSGI/DeepGBufferRadiosity_blur", "_write", BIT( BRIGHTPASS ), false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_AMBIENT_OCCLUSION, "builtin/SSAO/AmbientOcclusion_AO", "", { { "BRIGHTPASS", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_AO },
{ BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT, "builtin/SSAO/AmbientOcclusion_AO", "_write", { { "BRIGHTPASS", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_AO },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR, "builtin/SSAO/AmbientOcclusion_blur", "", { { "BRIGHTPASS", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_AO },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT, "builtin/SSAO/AmbientOcclusion_blur", "_write", { { "BRIGHTPASS", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_AO },
{ BUILTIN_AMBIENT_OCCLUSION_MINIFY, "builtin/SSAO/AmbientOcclusion_minify", "", { { "BRIGHTPASS", "0" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_AO1 },
{ BUILTIN_AMBIENT_OCCLUSION_RECONSTRUCT_CSZ, "builtin/SSAO/AmbientOcclusion_minify", "_mip0", { { "BRIGHTPASS", "1" } }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DRAW_AO1 },
{ BUILTIN_DEEP_GBUFFER_RADIOSITY_SSGI, "builtin/SSGI/DeepGBufferRadiosity_radiosity", "", { }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR, "builtin/SSGI/DeepGBufferRadiosity_blur", "", { }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR_AND_OUTPUT, "builtin/SSGI/DeepGBufferRadiosity_blur", "_write", { }, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB end
{ BUILTIN_STEREO_DEGHOST, "builtin/VR/stereoDeGhost", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_STEREO_WARP, "builtin/VR/stereoWarp", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_BINK, "builtin/video/bink", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_BINK_GUI, "builtin/video/bink_gui", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_STEREO_INTERLACE, "builtin/VR/stereoInterlace", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_MOTION_BLUR, "builtin/post/motionBlur", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_STEREO_DEGHOST, "builtin/VR/stereoDeGhost", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_STEREO_WARP, "builtin/VR/stereoWarp", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_BINK, "builtin/video/bink", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_BINK_GUI, "builtin/video/bink_gui", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_STEREO_INTERLACE, "builtin/VR/stereoInterlace", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
{ BUILTIN_MOTION_BLUR, "builtin/post/motionBlur", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB begin
{ BUILTIN_DEBUG_SHADOWMAP, "builtin/debug/debug_shadowmap", "", 0, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT },
{ BUILTIN_DEBUG_SHADOWMAP, "builtin/debug/debug_shadowmap", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
// RB end
{ BUILTIN_BLIT, "builtin/blit", "", { { "TEXTURE_ARRAY", "0" } }, false, SHADER_STAGE_FRAGMENT, LAYOUT_UNKNOWN, BINDING_LAYOUT_BLIT },
{ BUILTIN_RECT, "builtin/rect", "", { }, false, SHADER_STAGE_VERTEX, LAYOUT_DRAW_VERT, BINDING_LAYOUT_BLIT },
};
int numBuiltins = sizeof( builtins ) / sizeof( builtins[0] );
@ -232,6 +426,7 @@ void idRenderProgManager::Init()
prog.name = builtins[i].name;
prog.builtin = true;
prog.vertexLayout = builtins[i].layout;
prog.bindingLayoutType = builtins[i].bindingLayout;
builtinShaders[builtins[i].index] = i;
@ -241,27 +436,22 @@ void idRenderProgManager::Init()
continue;
}
uint32 shaderFeatures = builtins[i].shaderFeatures;
if( builtins[i].requireGPUSkinningSupport )
{
shaderFeatures |= BIT( USE_GPU_SKINNING );
}
int vIndex = -1;
if( builtins[ i ].stages & SHADER_STAGE_VERTEX )
{
vIndex = FindShader( builtins[ i ].name, SHADER_STAGE_VERTEX, builtins[i].nameOutSuffix, shaderFeatures, true, builtins[i].layout );
vIndex = FindShader( builtins[ i ].name, SHADER_STAGE_VERTEX, builtins[i].nameOutSuffix, builtins[i].macros, true, builtins[i].layout );
}
int fIndex = -1;
if( builtins[ i ].stages & SHADER_STAGE_FRAGMENT )
{
fIndex = FindShader( builtins[ i ].name, SHADER_STAGE_FRAGMENT, builtins[i].nameOutSuffix, shaderFeatures, true, builtins[i].layout );
fIndex = FindShader( builtins[ i ].name, SHADER_STAGE_FRAGMENT, builtins[i].nameOutSuffix, builtins[i].macros, true, builtins[i].layout );
}
//idLib::Printf( "Loading GLSL program %i %i %i\n", i, vIndex, fIndex );
idLib::Printf( "Loading shader program %s\n", prog.name.c_str() );
LoadGLSLProgram( i, vIndex, fIndex );
LoadProgram( i, vIndex, fIndex );
}
r_useHalfLambertLighting.ClearModified();
@ -349,7 +539,7 @@ void idRenderProgManager::LoadAllShaders()
continue;
}
LoadGLSLProgram( i, renderProgs[i].vertexShaderIndex, renderProgs[i].fragmentShaderIndex );
LoadProgram( i, renderProgs[i].vertexShaderIndex, renderProgs[i].fragmentShaderIndex );
}
}
@ -370,6 +560,43 @@ void idRenderProgManager::Shutdown()
idRenderProgManager::FindVertexShader
================================================================================================
*/
/*
int idRenderProgManager::FindShader( const char* name, rpStage_t stage )
{
idStr shaderName( name );
shaderName.StripFileExtension();
for( int i = 0; i < shaders.Num(); i++ )
{
shader_t& shader = shaders[ i ];
if( shader.name.Icmp( shaderName.c_str() ) == 0 && shader.stage == stage )
{
LoadShader( i, stage );
return i;
}
}
// Load it.
shader_t shader;
shader.name = shaderName;
shader.stage = stage;
for( int i = 0; i < MAX_SHADER_MACRO_NAMES; i++ )
{
int feature = ( bool )( 0 & BIT( i ) );
idStr macroName( GetGLSLMacroName( ( shaderFeature_t )i ) );
idStr value( feature );
shader.macros.Append( shaderMacro_t( macroName, value ) );
}
int index = shaders.Append( shader );
LoadShader( index, stage );
return index;
}
*/
/*
int idRenderProgManager::FindShader( const char* name, rpStage_t stage, const char* nameOutSuffix, uint32 features, bool builtin, vertexLayoutType_t vertexLayout )
{
idStr shaderName( name );
@ -399,14 +626,69 @@ int idRenderProgManager::FindShader( const char* name, rpStage_t stage, const ch
return index;
}
*/
// RB begin
int idRenderProgManager::FindShader( const char* name, rpStage_t stage, const char* nameOutSuffix, const idList<shaderMacro_t>& macros, bool builtin, vertexLayoutType_t vertexLayout )
{
idStr shaderName( name );
shaderName.StripFileExtension();
for( int i = 0; i < shaders.Num(); i++ )
{
shader_t& shader = shaders[i];
if( shader.name.Icmp( shaderName ) == 0 && shader.stage == stage && shader.nameOutSuffix.Icmp( nameOutSuffix ) == 0 )
{
LoadShader( i, stage );
return i;
}
}
// Load it.
shader_t shader;
shader.name = shaderName;
shader.nameOutSuffix = nameOutSuffix;
shader.shaderFeatures = 0;
shader.builtin = builtin;
shader.stage = stage;
shader.macros = macros;
int index = shaders.Append( shader );
LoadShader( index, stage );
return index;
}
#if defined( USE_NVRHI )
nvrhi::ShaderHandle idRenderProgManager::GetShader( int index )
{
return shaders[ index ].handle;
}
programInfo_t idRenderProgManager::GetProgramInfo( int index )
{
programInfo_t info;
renderProg_t& prog = renderProgs[index];
if( prog.vertexShaderIndex > -1 && prog.vertexShaderIndex < shaders.Num() )
{
info.vs = GetShader( prog.vertexShaderIndex );
}
if( prog.fragmentShaderIndex > -1 && prog.fragmentShaderIndex < shaders.Num() )
{
info.ps = GetShader( prog.fragmentShaderIndex );
}
info.inputLayout = prog.inputLayout;
info.bindingLayout = prog.bindingLayout;
return info;
}
#endif
bool idRenderProgManager::IsShaderBound() const
{
return ( current != -1 );
return ( currentIndex != -1 );
}
// RB end
/*
================================================================================================

View file

@ -3,8 +3,9 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2018 Robert Beckebans
Copyright (C) 2013-2022 Robert Beckebans
Copyright (C) 2016-2017 Dustin Land
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -211,6 +212,12 @@ enum rpBinding_t
BINDING_TYPE_MAX
};
struct ShaderBlob
{
void* data = nullptr;
size_t size = 0;
};
#define VERTEX_UNIFORM_ARRAY_NAME "_va_"
#define FRAGMENT_UNIFORM_ARRAY_NAME "_fa_"
@ -235,6 +242,149 @@ struct attribInfo_t
extern attribInfo_t attribsPC[];
// Shader macros are used to pick which permutation of a shader to load from a ShaderBlob
// binary file.
struct shaderMacro_t
{
idStr name;
idStr definition;
shaderMacro_t()
: name()
, definition()
{
}
shaderMacro_t( const idStr& _name, const idStr& _definition )
: name( _name )
, definition( _definition )
{ }
};
#if defined( USE_NVRHI )
struct programInfo_t
{
nvrhi::ShaderHandle vs;
nvrhi::ShaderHandle ps;
nvrhi::InputLayoutHandle inputLayout;
nvrhi::BindingLayoutHandle bindingLayout;
};
#endif
enum
{
BUILTIN_GUI,
BUILTIN_COLOR,
// RB begin
BUILTIN_COLOR_SKINNED,
BUILTIN_VERTEX_COLOR,
BUILTIN_AMBIENT_LIGHTING,
BUILTIN_AMBIENT_LIGHTING_SKINNED,
BUILTIN_AMBIENT_LIGHTING_IBL,
BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED,
BUILTIN_AMBIENT_LIGHTING_IBL_PBR,
BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED,
BUILTIN_AMBIENT_LIGHTGRID_IBL,
BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED,
BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR,
BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED,
BUILTIN_SMALL_GEOMETRY_BUFFER,
BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED,
// RB end
BUILTIN_TEXTURED,
BUILTIN_TEXTURE_VERTEXCOLOR,
BUILTIN_TEXTURE_VERTEXCOLOR_SRGB,
BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED,
BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR,
BUILTIN_INTERACTION,
BUILTIN_INTERACTION_SKINNED,
BUILTIN_INTERACTION_AMBIENT,
BUILTIN_INTERACTION_AMBIENT_SKINNED,
// RB begin
BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT,
BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT,
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
BUILTIN_PBR_INTERACTION,
BUILTIN_PBR_INTERACTION_SKINNED,
BUILTIN_PBR_INTERACTION_AMBIENT,
BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
BUILTIN_DEBUG_LIGHTGRID,
BUILTIN_DEBUG_LIGHTGRID_SKINNED,
BUILTIN_DEBUG_OCTAHEDRON,
BUILTIN_DEBUG_OCTAHEDRON_SKINNED,
// RB end
BUILTIN_ENVIRONMENT,
BUILTIN_ENVIRONMENT_SKINNED,
BUILTIN_BUMPY_ENVIRONMENT,
BUILTIN_BUMPY_ENVIRONMENT_SKINNED,
BUILTIN_DEPTH,
BUILTIN_DEPTH_SKINNED,
BUILTIN_SHADOW,
BUILTIN_SHADOW_SKINNED,
BUILTIN_SHADOW_DEBUG,
BUILTIN_SHADOW_DEBUG_SKINNED,
BUILTIN_BLENDLIGHT,
BUILTIN_FOG,
BUILTIN_FOG_SKINNED,
BUILTIN_SKYBOX,
BUILTIN_WOBBLESKY,
BUILTIN_POSTPROCESS,
// RB begin
BUILTIN_SCREEN,
BUILTIN_TONEMAP,
BUILTIN_BRIGHTPASS,
BUILTIN_HDR_GLARE_CHROMATIC,
BUILTIN_HDR_DEBUG,
BUILTIN_SMAA_EDGE_DETECTION,
BUILTIN_SMAA_BLENDING_WEIGHT_CALCULATION,
BUILTIN_SMAA_NEIGHBORHOOD_BLENDING,
BUILTIN_AMBIENT_OCCLUSION,
BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT,
BUILTIN_AMBIENT_OCCLUSION_BLUR,
BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT,
BUILTIN_AMBIENT_OCCLUSION_MINIFY,
BUILTIN_AMBIENT_OCCLUSION_RECONSTRUCT_CSZ,
BUILTIN_DEEP_GBUFFER_RADIOSITY_SSGI,
BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR,
BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR_AND_OUTPUT,
// RB end
BUILTIN_STEREO_DEGHOST,
BUILTIN_STEREO_WARP,
BUILTIN_BINK,
BUILTIN_BINK_GUI,
BUILTIN_STEREO_INTERLACE,
BUILTIN_MOTION_BLUR,
BUILTIN_DEBUG_SHADOWMAP,
// SP Begin
BUILTIN_BLIT,
BUILTIN_RECT,
// SP End
MAX_BUILTINS
};
/*
================================================================================================
@ -247,7 +397,7 @@ public:
idRenderProgManager();
virtual ~idRenderProgManager();
void Init();
void Init( nvrhi::IDevice* _device );
void Shutdown();
void StartFrame();
@ -255,27 +405,45 @@ public:
void SetRenderParm( renderParm_t rp, const float* value );
void SetRenderParms( renderParm_t rp, const float* values, int numValues );
int FindShader( const char* name, rpStage_t stage );
int FindShader( const char* name, rpStage_t stage, const char* nameOutSuffix, uint32 features, bool builtin, vertexLayoutType_t vertexLayout = LAYOUT_DRAW_VERT );
int FindShader( const char* name, rpStage_t stage, const char* nameOutSuffix, const idList<shaderMacro_t>& macros, bool builtin, vertexLayoutType_t vertexLayout = LAYOUT_DRAW_VERT );
#if defined( USE_NVRHI )
nvrhi::ShaderHandle GetShader( int index );
nvrhi::BufferHandle GetConstantBuffer()
{
return constantBuffer;
}
programInfo_t GetProgramInfo( int index );
int CurrentProgram() const
{
return currentIndex;
}
#endif
void BindProgram( int progIndex );
void BindShader_GUI( )
void BindShader_GUI()
{
BindShader_Builtin( BUILTIN_GUI );
}
void BindShader_Color( )
void BindShader_Color()
{
BindShader_Builtin( BUILTIN_COLOR );
}
// RB begin
void BindShader_ColorSkinned( )
void BindShader_ColorSkinned()
{
BindShader_Builtin( BUILTIN_COLOR_SKINNED );
}
void BindShader_VertexColor( )
void BindShader_VertexColor()
{
BindShader_Builtin( BUILTIN_VERTEX_COLOR );
}
@ -343,7 +511,7 @@ public:
}
// RB end
void BindShader_Texture( )
void BindShader_Texture()
{
BindShader_Builtin( BUILTIN_TEXTURED );
}
@ -712,12 +880,22 @@ public:
// the joints buffer should only be bound for vertex programs that use joints
bool ShaderUsesJoints() const
{
#if defined( USE_NVRHI )
// FIXME
return false;
#else
return renderProgs[current].usesJoints;
#endif
}
// the rpEnableSkinning render parm should only be set for vertex programs that use it
bool ShaderHasOptionalSkinning() const
{
#if defined( USE_NVRHI )
// FIXME
return false;
#else
return renderProgs[current].optionalSkinning;
#endif
}
// unbind the currently bound render program
@ -737,10 +915,29 @@ public:
void SetUniformValue( const renderParm_t rp, const float* value );
void CommitUniforms( uint64 stateBits );
void CachePipeline( uint64 stateBits );
int FindGLSLProgram( const char* name, int vIndex, int fIndex );
int FindProgram( const char* name, int vIndex, int fIndex, bindingLayoutType_t bindingType = BINDING_LAYOUT_DEFAULT );
void ZeroUniforms();
#if defined(USE_VULKAN)
#if defined( USE_NVRHI )
void CommitConstantBuffer( nvrhi::ICommandList* commandList );
ID_INLINE nvrhi::IBuffer* ConstantBuffer()
{
return constantBuffer;
}
ID_INLINE nvrhi::InputLayoutHandle InputLayout()
{
return renderProgs[currentIndex].inputLayout;
}
ID_INLINE nvrhi::BindingLayoutHandle BindingLayout()
{
return renderProgs[currentIndex].bindingLayout;
}
ID_INLINE int BindingLayoutType()
{
return renderProgs[currentIndex].bindingLayoutType;
}
#elif defined(USE_VULKAN)
void PrintPipelines();
void ClearPipelines();
#endif
@ -750,118 +947,12 @@ public:
private:
void LoadShader( int index, rpStage_t stage );
// Reads the binary fileName and returns a ShaderBlob.
ShaderBlob GetBytecode( const char* fileName );
idStr StripDeadCode( const idStr& in, const char* name, const idStrList& compileMacros, bool builtin );
idStr ConvertCG2GLSL( const idStr& in, const char* name, rpStage_t stage, idStr& outLayout, bool vkGLSL, bool hasGPUSkinning, vertexLayoutType_t vertexLayout );
enum
{
BUILTIN_GUI,
BUILTIN_COLOR,
// RB begin
BUILTIN_COLOR_SKINNED,
BUILTIN_VERTEX_COLOR,
BUILTIN_AMBIENT_LIGHTING,
BUILTIN_AMBIENT_LIGHTING_SKINNED,
BUILTIN_AMBIENT_LIGHTING_IBL,
BUILTIN_AMBIENT_LIGHTING_IBL_SKINNED,
BUILTIN_AMBIENT_LIGHTING_IBL_PBR,
BUILTIN_AMBIENT_LIGHTING_IBL_PBR_SKINNED,
BUILTIN_AMBIENT_LIGHTGRID_IBL,
BUILTIN_AMBIENT_LIGHTGRID_IBL_SKINNED,
BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR,
BUILTIN_AMBIENT_LIGHTGRID_IBL_PBR_SKINNED,
BUILTIN_SMALL_GEOMETRY_BUFFER,
BUILTIN_SMALL_GEOMETRY_BUFFER_SKINNED,
// RB end
BUILTIN_TEXTURED,
BUILTIN_TEXTURE_VERTEXCOLOR,
BUILTIN_TEXTURE_VERTEXCOLOR_SRGB,
BUILTIN_TEXTURE_VERTEXCOLOR_SKINNED,
BUILTIN_TEXTURE_TEXGEN_VERTEXCOLOR,
BUILTIN_INTERACTION,
BUILTIN_INTERACTION_SKINNED,
BUILTIN_INTERACTION_AMBIENT,
BUILTIN_INTERACTION_AMBIENT_SKINNED,
// RB begin
BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT,
BUILTIN_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT,
BUILTIN_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
BUILTIN_PBR_INTERACTION,
BUILTIN_PBR_INTERACTION_SKINNED,
BUILTIN_PBR_INTERACTION_AMBIENT,
BUILTIN_PBR_INTERACTION_AMBIENT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_SPOT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_POINT_SKINNED,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL,
BUILTIN_PBR_INTERACTION_SHADOW_MAPPING_PARALLEL_SKINNED,
BUILTIN_DEBUG_LIGHTGRID,
BUILTIN_DEBUG_LIGHTGRID_SKINNED,
BUILTIN_DEBUG_OCTAHEDRON,
BUILTIN_DEBUG_OCTAHEDRON_SKINNED,
// RB end
BUILTIN_ENVIRONMENT,
BUILTIN_ENVIRONMENT_SKINNED,
BUILTIN_BUMPY_ENVIRONMENT,
BUILTIN_BUMPY_ENVIRONMENT_SKINNED,
BUILTIN_DEPTH,
BUILTIN_DEPTH_SKINNED,
BUILTIN_SHADOW,
BUILTIN_SHADOW_SKINNED,
BUILTIN_SHADOW_DEBUG,
BUILTIN_SHADOW_DEBUG_SKINNED,
BUILTIN_BLENDLIGHT,
BUILTIN_FOG,
BUILTIN_FOG_SKINNED,
BUILTIN_SKYBOX,
BUILTIN_WOBBLESKY,
BUILTIN_POSTPROCESS,
// RB begin
BUILTIN_SCREEN,
BUILTIN_TONEMAP,
BUILTIN_BRIGHTPASS,
BUILTIN_HDR_GLARE_CHROMATIC,
BUILTIN_HDR_DEBUG,
BUILTIN_SMAA_EDGE_DETECTION,
BUILTIN_SMAA_BLENDING_WEIGHT_CALCULATION,
BUILTIN_SMAA_NEIGHBORHOOD_BLENDING,
BUILTIN_AMBIENT_OCCLUSION,
BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT,
BUILTIN_AMBIENT_OCCLUSION_BLUR,
BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT,
BUILTIN_AMBIENT_OCCLUSION_MINIFY,
BUILTIN_AMBIENT_OCCLUSION_RECONSTRUCT_CSZ,
BUILTIN_DEEP_GBUFFER_RADIOSITY_SSGI,
BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR,
BUILTIN_DEEP_GBUFFER_RADIOSITY_BLUR_AND_OUTPUT,
// RB end
BUILTIN_STEREO_DEGHOST,
BUILTIN_STEREO_WARP,
BUILTIN_BINK,
BUILTIN_BINK_GUI,
BUILTIN_STEREO_INTERLACE,
BUILTIN_MOTION_BLUR,
BUILTIN_DEBUG_SHADOWMAP,
MAX_BUILTINS
};
int builtinShaders[MAX_BUILTINS];
void BindShader_Builtin( int i )
{
@ -885,10 +976,82 @@ private:
const char* GetGLSLMacroName( shaderFeature_t sf ) const;
bool CompileGLSL( uint target, const char* name );
void LoadGLSLProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex );
void LoadProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex );
static const uint INVALID_PROGID = 0xFFFFFFFF;
#if defined( USE_NVRHI )
struct shader_t
{
shader_t() :
name(),
nameOutSuffix(),
shaderFeatures( 0 ),
builtin( false ),
macros(),
handle( nullptr ),
stage( SHADER_STAGE_DEFAULT )
{
}
idStr name;
idStr nameOutSuffix;
uint32 shaderFeatures;
bool builtin;
idList<shaderMacro_t> macros;
nvrhi::ShaderHandle handle;
rpStage_t stage;
};
struct renderProg_t
{
renderProg_t() :
name(),
vertexShaderIndex( -1 ),
fragmentShaderIndex( -1 ),
builtin( true ),
usesJoints( false ),
vertexLayout( LAYOUT_UNKNOWN ),
bindingLayoutType( BINDING_LAYOUT_DEFAULT ),
inputLayout( nullptr ),
bindingLayout( nullptr )
{
}
idStr name;
int vertexShaderIndex;
int fragmentShaderIndex;
bool builtin;
bool usesJoints;
vertexLayoutType_t vertexLayout;
bindingLayoutType_t bindingLayoutType;
nvrhi::InputLayoutHandle inputLayout;
nvrhi::BindingLayoutHandle bindingLayout;
};
void LoadShader( shader_t& shader );
int currentIndex;
idList<renderProg_t, TAG_RENDER> renderProgs;
idList<shader_t, TAG_RENDER> shaders;
idStaticList< idVec4, RENDERPARM_TOTAL > uniforms;
nvrhi::IDevice* device;
using VertexAttribDescList = idList< nvrhi::VertexAttributeDesc >;
idStaticList< VertexAttribDescList, NUM_VERTEX_LAYOUTS > vertexLayoutDescs;
idStaticList< nvrhi::BindingLayoutHandle, NUM_BINDING_LAYOUTS > bindingLayouts;
nvrhi::BufferHandle constantBuffer;
// Temp
nvrhi::InputLayoutHandle inputLayout;
nvrhi::BindingLayoutHandle bindingLayout;
nvrhi::BindingSetHandle bindingSet;
renderProg_t* currentShader;
#else
#if defined(USE_VULKAN)
struct shader_t
{
@ -1012,6 +1175,8 @@ private:
idUniformBuffer* parmBuffers[ NUM_FRAME_DATA ];
#endif
#endif //#if defined( USE_NVRHI )
};
extern idRenderProgManager renderProgManager;

View file

@ -248,11 +248,9 @@ struct glconfig_t
float pixelAspect;
// RB begin
#if !defined(__ANDROID__) && !defined(USE_VULKAN)
#if !defined(USE_NVRHI) && !defined(USE_VULKAN)
GLuint global_vao;
#endif
// RB end
};
@ -291,7 +289,7 @@ public:
virtual void ResetGuiModels() = 0;
virtual void InitOpenGL() = 0;
virtual void InitBackend() = 0;
virtual void ShutdownOpenGL() = 0;
@ -351,10 +349,10 @@ public:
virtual void SetGLState( const uint64 glState ) = 0;
virtual void DrawFilled( const idVec4& color, float x, float y, float w, float h ) = 0;
virtual void DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial* material ) = 0;
void DrawStretchPic( const idVec4& rect, const idVec4& st, const idMaterial* material )
virtual void DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial* material, float z = 0.0f ) = 0;
void DrawStretchPic( const idVec4& rect, const idVec4& st, const idMaterial* material, float z = 0.0f )
{
DrawStretchPic( rect.x, rect.y, rect.z, rect.w, st.x, st.y, st.z, st.w, material );
DrawStretchPic( rect.x, rect.y, rect.z, rect.w, st.x, st.y, st.z, st.w, material, z );
}
virtual void DrawStretchPic( const idVec4& topLeft, const idVec4& topRight, const idVec4& bottomRight, const idVec4& bottomLeft, const idMaterial* material ) = 0;
virtual void DrawStretchTri( const idVec2& p1, const idVec2& p2, const idVec2& p3, const idVec2& t1, const idVec2& t2, const idVec2& t3, const idMaterial* material ) = 0;
@ -362,10 +360,10 @@ public:
virtual void PrintMemInfo( MemInfo_t* mi ) = 0;
virtual void DrawSmallChar( int x, int y, int ch ) = 0;
virtual void DrawSmallStringExt( int x, int y, const char* string, const idVec4& setColor, bool forceColor ) = 0;
virtual void DrawBigChar( int x, int y, int ch ) = 0;
virtual void DrawBigStringExt( int x, int y, const char* string, const idVec4& setColor, bool forceColor ) = 0;
virtual void DrawSmallChar( int x, int y, int ch ) = 0;
virtual void DrawSmallStringExt( int x, int y, const char* string, const idVec4& setColor, bool forceColor ) = 0;
virtual void DrawBigChar( int x, int y, int ch ) = 0;
virtual void DrawBigStringExt( int x, int y, const char* string, const idVec4& setColor, bool forceColor ) = 0;
// dump all 2D drawing so far this frame to the demo file
virtual void WriteDemoPics() = 0;
@ -418,6 +416,7 @@ public:
// then perform all desired rendering, then capture to an image
// if the specified physical dimensions are larger than the current cropped region, they will be cut down to fit
virtual void CropRenderSize( int width, int height ) = 0;
virtual void CropRenderSize( int x, int y, int width, int height ) = 0;
virtual void CaptureRenderToImage( const char* imageName, bool clearColorAfterCopy = false ) = 0;
// fixAlpha will set all the alpha channel values to 0xff, which allows screen captures
// to use the default tga loading code without having dimmed down areas in many places

View file

@ -3,8 +3,9 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014-2016 Robert Beckebans
Copyright (C) 2014-2021 Robert Beckebans
Copyright (C) 2014-2016 Kot in Action Creative Artel
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -326,10 +327,9 @@ const char* fileExten[4] = { "tga", "png", "jpg", "exr" };
const char* envDirection[6] = { "_px", "_nx", "_py", "_ny", "_pz", "_nz" };
const char* skyDirection[6] = { "_forward", "_back", "_left", "_right", "_up", "_down" };
#if defined( USE_NVRHI )
DeviceManager* deviceManager;
#endif
/*
=============================
@ -2206,6 +2206,7 @@ void idRenderSystemLocal::Shutdown()
delete guiModel;
parallelJobManager->FreeJobList( envprobeJobList );
parallelJobManager->FreeJobList( frontEndJobList );
Clear();
@ -2225,7 +2226,7 @@ void idRenderSystemLocal::ResetGuiModels()
delete guiModel;
guiModel = new( TAG_RENDER ) idGuiModel;
guiModel->Clear();
guiModel->BeginFrame();
guiModel->BeginFrame( commandList );
tr_guiModel = guiModel; // for DeviceContext fast path
}
@ -2251,6 +2252,11 @@ idRenderSystemLocal::LoadLevelImages
void idRenderSystemLocal::LoadLevelImages()
{
globalImages->LoadLevelImages( false );
#if defined( USE_NVRHI )
deviceManager->GetDevice()->waitForIdle();
deviceManager->GetDevice()->runGarbageCollection();
#endif
}
/*
@ -2341,13 +2347,27 @@ void idRenderSystemLocal::ResetFonts()
idRenderSystemLocal::InitOpenGL
========================
*/
void idRenderSystemLocal::InitOpenGL()
void idRenderSystemLocal::InitBackend()
{
// if OpenGL isn't started, start it now
if( !IsInitialized() )
{
backend.Init();
#if defined( USE_NVRHI )
if( !commandList )
{
commandList = deviceManager->GetDevice()->createCommandList();
}
commandList->open();
// Reloading images here causes the rendertargets to get deleted. Figure out how to handle this properly on 360
globalImages->ReloadImages( true, commandList );
commandList->close();
deviceManager->GetDevice()->executeCommandList( commandList );
#else
// Reloading images here causes the rendertargets to get deleted. Figure out how to handle this properly on 360
//globalImages->ReloadImages( true );
@ -2357,6 +2377,8 @@ void idRenderSystemLocal::InitOpenGL()
{
common->Printf( "glGetError() = 0x%x\n", err );
}
#endif
#endif
}
}

View file

@ -1074,6 +1074,7 @@ void idRenderWorldLocal::RenderScene( const renderView_t* renderView )
// setup view parms for the initial view
viewDef_t* parms = ( viewDef_t* )R_ClearedFrameAlloc( sizeof( *parms ), FRAME_ALLOC_VIEW_DEF );
parms->renderView = *renderView;
parms->targetRender = nullptr;
if( tr.takingScreenshot )
{
@ -1102,6 +1103,7 @@ void idRenderWorldLocal::RenderScene( const renderView_t* renderView )
parms->scissor.y2 = parms->viewport.y2 - parms->viewport.y1;
parms->isSubview = false;
parms->isObliqueProjection = false;
parms->initialViewAreaOrigin = renderView->vieworg;
parms->renderWorld = this;

View file

@ -719,7 +719,7 @@ void idRenderWorldLocal::WriteRenderLight( idDemoFile* f, qhandle_t handle, cons
ReadRenderLight
================
*/
void idRenderWorldLocal::ReadRenderLight( )
void idRenderWorldLocal::ReadRenderLight()
{
renderLight_t light;
int index, i;

View file

@ -4,6 +4,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2020-2021 Robert Beckebans
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -36,6 +37,11 @@ If you have questions concerning this license or the applicable additional terms
#include "CmdlineProgressbar.h"
#include "../framework/Common_local.h" // commonLocal.WaitGameThread();
#if defined( USE_NVRHI )
#include <sys/DeviceManager.h>
extern DeviceManager* deviceManager;
#endif
/*
=============
R_SetEnvprobeDefViewEnvprobe
@ -1149,6 +1155,12 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
int totalEnd = Sys_Milliseconds();
#if defined( USE_NVRHI )
nvrhi::CommandListHandle commandList = deviceManager->GetDevice()->createCommandList();
commandList->open();
#endif
//--------------------------------------------
// LOAD CONVOLVED OCTAHEDRONS INTO THE GPU
//--------------------------------------------
@ -1160,10 +1172,15 @@ CONSOLE_COMMAND( bakeEnvironmentProbes, "Bake environment probes", NULL )
continue;
}
def->irradianceImage->Reload( true );
def->radianceImage->Reload( true );
def->irradianceImage->Reload( true, commandList );
def->radianceImage->Reload( true, commandList );
}
#if defined( USE_NVRHI )
commandList->close();
deviceManager->GetDevice()->executeCommandList( commandList );
#endif
idLib::Printf( "----------------------------------\n" );
idLib::Printf( "Processed %i light probes\n", totalProcessedProbes );
common->Printf( "Baked SH irradiance and GGX mip maps in %5.1f seconds\n\n", ( totalEnd - totalStart ) / ( 1000.0f ) );

View file

@ -4,6 +4,7 @@
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2021 Robert Beckebans
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
@ -425,7 +426,7 @@ void idRenderWorldLocal::LoadLightGridImages()
}
else
{
area->lightGrid.irradianceImage->Reload( true );
area->lightGrid.irradianceImage->Reload( true, commandList );
}
}
}

View file

@ -386,6 +386,8 @@ static void R_AddSingleLight( viewLight_t* vLight )
vLight->entityInteractionState[ edef->index ] = viewLight_t::INTERACTION_NO;
// The table is updated at interaction::AllocAndLink() and interaction::UnlinkAndFree()
// TODO(Stephen): interactionTableRow is null if renderDef is used in a gui.sub
const idInteraction* inter = interactionTableRow[ edef->index ];
const renderEntity_t& eParms = edef->parms;

View file

@ -332,7 +332,7 @@ void R_SetupDrawSurfShader( drawSurf_t* drawSurf, const idMaterial* shader, cons
R_SetupDrawSurfJoints
===================
*/
void R_SetupDrawSurfJoints( drawSurf_t* drawSurf, const srfTriangles_t* tri, const idMaterial* shader )
void R_SetupDrawSurfJoints( drawSurf_t* drawSurf, const srfTriangles_t* tri, const idMaterial* shader, nvrhi::ICommandList* commandList )
{
// RB: added check wether GPU skinning is available at all
if( tri->staticModelWithJoints == NULL || !r_useGPUSkinning.GetBool() || !glConfig.gpuSkinningAvailable )
@ -348,7 +348,7 @@ void R_SetupDrawSurfJoints( drawSurf_t* drawSurf, const srfTriangles_t* tri, con
if( !vertexCache.CacheIsCurrent( model->jointsInvertedBuffer ) )
{
const int alignment = glConfig.uniformBufferOffsetAlignment;
model->jointsInvertedBuffer = vertexCache.AllocJoint( model->jointsInverted, model->numInvertedJoints );
model->jointsInvertedBuffer = vertexCache.AllocJoint( model->jointsInverted, model->numInvertedJoints, sizeof( idJointMat ), commandList );
}
drawSurf->jointCache = model->jointsInvertedBuffer;
}
@ -750,7 +750,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// make sure we have an ambient cache and all necessary normals / tangents
if( !vertexCache.CacheIsCurrent( tri->indexCache ) )
{
tri->indexCache = vertexCache.AllocIndex( tri->indexes, tri->numIndexes );
tri->indexCache = vertexCache.AllocIndex( tri->indexes, tri->numIndexes, sizeof( triIndex_t ), nullptr );
}
if( !vertexCache.CacheIsCurrent( tri->ambientCache ) )
@ -765,7 +765,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
//assert( false ); // this should no longer be hit
// RB end
}
tri->ambientCache = vertexCache.AllocVertex( tri->verts, tri->numVerts );
tri->ambientCache = vertexCache.AllocVertex( tri->verts, tri->numVerts, sizeof( idDrawVert ), nullptr );
}
// add the surface for drawing
@ -807,14 +807,14 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// copy verts and indexes to this frame's hardware memory if they aren't already there
if( !vertexCache.CacheIsCurrent( tri->ambientCache ) )
{
tri->ambientCache = vertexCache.AllocVertex( tri->verts, tri->numVerts );
tri->ambientCache = vertexCache.AllocVertex( tri->verts, tri->numVerts, sizeof( idDrawVert ), nullptr );
}
if( !vertexCache.CacheIsCurrent( tri->indexCache ) )
{
tri->indexCache = vertexCache.AllocIndex( tri->indexes, tri->numIndexes );
tri->indexCache = vertexCache.AllocIndex( tri->indexes, tri->numIndexes, sizeof( triIndex_t ), nullptr );
}
R_SetupDrawSurfJoints( baseDrawSurf, tri, shader );
R_SetupDrawSurfJoints( baseDrawSurf, tri, shader, nullptr );
baseDrawSurf->numIndexes = tri->numIndexes;
baseDrawSurf->ambientCache = tri->ambientCache;
@ -907,7 +907,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// when using shadow volumes
if( r_cullDynamicLightTriangles.GetBool() && !r_skipDynamicShadows.GetBool() && !r_useShadowMapping.GetBool() && shader->SurfaceCastsShadow() )
{
vertCacheHandle_t lightIndexCache = vertexCache.AllocIndex( NULL, lightDrawSurf->numIndexes );
vertCacheHandle_t lightIndexCache = vertexCache.AllocIndex( NULL, lightDrawSurf->numIndexes, sizeof( triIndex_t ), nullptr );
if( vertexCache.CacheIsCurrent( lightIndexCache ) )
{
lightDrawSurf->indexCache = lightIndexCache;
@ -968,7 +968,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
lightDrawSurf->renderZFail = 0;
lightDrawSurf->shaderRegisters = shaderRegisters;
R_SetupDrawSurfJoints( lightDrawSurf, tri, shader );
R_SetupDrawSurfJoints( lightDrawSurf, tri, shader, nullptr );
// Determine which linked list to add the light surface to.
// There will only be localSurfaces if the light casts shadows and
@ -1096,7 +1096,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// make sure we have an ambient cache and all necessary normals / tangents
if( !vertexCache.CacheIsCurrent( tri->indexCache ) )
{
tri->indexCache = vertexCache.AllocIndex( tri->indexes, tri->numIndexes );
tri->indexCache = vertexCache.AllocIndex( tri->indexes, tri->numIndexes, sizeof( triIndex_t ), nullptr );
}
// throw the entire source surface at it without any per-triangle culling
@ -1116,7 +1116,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
//assert( false ); // this should no longer be hit
// RB end
}
tri->ambientCache = vertexCache.AllocVertex( tri->verts, tri->numVerts );
tri->ambientCache = vertexCache.AllocVertex( tri->verts, tri->numVerts, sizeof( idDrawVert ), nullptr );
}
shadowDrawSurf->ambientCache = tri->ambientCache;
@ -1135,7 +1135,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
R_SetupDrawSurfShader( shadowDrawSurf, shader, renderEntity );
}
R_SetupDrawSurfJoints( shadowDrawSurf, tri, shader );
R_SetupDrawSurfJoints( shadowDrawSurf, tri, shader, nullptr );
// determine which linked list to add the shadow surface to
@ -1220,7 +1220,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
// duplicates them with w set to 0 and 1 for the vertex program to project.
// This is constant for any number of lights, the vertex program takes care
// of projecting the verts to infinity for a particular light.
tri->shadowCache = vertexCache.AllocVertex( NULL, tri->numVerts * 2, sizeof( idShadowVert ) );
tri->shadowCache = vertexCache.AllocVertex( NULL, tri->numVerts * 2, sizeof( idShadowVert ), nullptr );
idShadowVert* shadowVerts = ( idShadowVert* )vertexCache.MappedVertexBuffer( tri->shadowCache );
idShadowVert::CreateShadowCache( shadowVerts, tri->verts, tri->numVerts );
}
@ -1228,7 +1228,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
const int maxShadowVolumeIndexes = tri->numSilEdges * 6 + tri->numIndexes * 2;
shadowDrawSurf->numIndexes = 0;
shadowDrawSurf->indexCache = vertexCache.AllocIndex( NULL, maxShadowVolumeIndexes );
shadowDrawSurf->indexCache = vertexCache.AllocIndex( NULL, maxShadowVolumeIndexes, sizeof( triIndex_t ), nullptr );
shadowDrawSurf->shadowCache = tri->shadowCache;
shadowDrawSurf->scissorRect = vLight->scissorRect; // default to the light scissor and light depth bounds
shadowDrawSurf->shadowVolumeState = SHADOWVOLUME_DONE; // assume the shadow volume is done in case the index cache allocation failed
@ -1306,7 +1306,7 @@ void R_AddSingleModel( viewEntity_t* vEntity )
shadowDrawSurf->sort = 0.0f;
shadowDrawSurf->shaderRegisters = NULL;
R_SetupDrawSurfJoints( shadowDrawSurf, tri, NULL );
R_SetupDrawSurfJoints( shadowDrawSurf, tri, NULL, nullptr );
// determine which linked list to add the shadow surface to
shadowDrawSurf->linkChain = shader->TestMaterialFlag( MF_NOSELFSHADOW ) ? &vLight->localShadows : &vLight->globalShadows;

View file

@ -46,10 +46,10 @@ DEFORM SURFACES
R_FinishDeform
=================
*/
static drawSurf_t* R_FinishDeform( drawSurf_t* surf, srfTriangles_t* newTri, const idDrawVert* newVerts, const triIndex_t* newIndexes )
static drawSurf_t* R_FinishDeform( drawSurf_t* surf, srfTriangles_t* newTri, const idDrawVert* newVerts, const triIndex_t* newIndexes, nvrhi::ICommandList* commandList )
{
newTri->ambientCache = vertexCache.AllocVertex( newVerts, newTri->numVerts );
newTri->indexCache = vertexCache.AllocIndex( newIndexes, newTri->numIndexes );
newTri->ambientCache = vertexCache.AllocVertex( newVerts, newTri->numVerts, sizeof( idDrawVert ), commandList );
newTri->indexCache = vertexCache.AllocIndex( newIndexes, newTri->numIndexes, sizeof( triIndex_t ), commandList );
surf->frontEndGeo = newTri;
surf->numIndexes = newTri->numIndexes;
@ -146,7 +146,7 @@ static drawSurf_t* R_AutospriteDeform( drawSurf_t* surf )
newIndexes[6 * ( i >> 2 ) + 5] = i + 3;
}
return R_FinishDeform( surf, newTri, newVerts, newIndexes );
return R_FinishDeform( surf, newTri, newVerts, newIndexes, nullptr );
}
/*
@ -278,7 +278,7 @@ static drawSurf_t* R_TubeDeform( drawSurf_t* surf )
}
}
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes );
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes, nullptr );
}
/*
@ -522,7 +522,7 @@ static drawSurf_t* R_FlareDeform( drawSurf_t* surf )
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // to make this a multiple of 16 bytes
};
return R_FinishDeform( surf, newTri, newVerts, triIndexes );
return R_FinishDeform( surf, newTri, newVerts, triIndexes, nullptr );
}
/*
@ -552,7 +552,7 @@ static drawSurf_t* R_ExpandDeform( drawSurf_t* surf )
newVerts[i].xyz = srcTri->verts[i].xyz + srcTri->verts[i].GetNormal() * dist;
}
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes );
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes, nullptr );
}
/*
@ -582,7 +582,7 @@ static drawSurf_t* R_MoveDeform( drawSurf_t* surf )
newVerts[i].xyz[0] += dist;
}
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes );
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes, nullptr );
}
/*
@ -626,7 +626,7 @@ static drawSurf_t* R_TurbulentDeform( drawSurf_t* surf )
newVerts[i].SetTexCoord( tempST );
}
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes );
return R_FinishDeform( surf, newTri, newVerts, srcTri->indexes, nullptr );
}
/*
@ -852,7 +852,7 @@ static drawSurf_t* R_EyeballDeform( drawSurf_t* surf )
newTri->numIndexes = numIndexes;
return R_FinishDeform( surf, newTri, newVerts, newIndexes );
return R_FinishDeform( surf, newTri, newVerts, newIndexes, nullptr );
}
/*
@ -862,7 +862,7 @@ R_ParticleDeform
Emit particles from the surface.
=====================
*/
static drawSurf_t* R_ParticleDeform( drawSurf_t* surf, bool useArea )
static drawSurf_t* R_ParticleDeform( drawSurf_t* surf, bool useArea, nvrhi::ICommandList* commandList )
{
const renderEntity_t* renderEntity = &surf->space->entityDef->parms;
const viewDef_t* viewDef = tr.viewDef;
@ -1096,8 +1096,8 @@ static drawSurf_t* R_ParticleDeform( drawSurf_t* surf, bool useArea )
newTri->bounds = stage->bounds; // just always draw the particles
newTri->numVerts = numVerts;
newTri->numIndexes = numIndexes;
newTri->ambientCache = vertexCache.AllocVertex( newVerts, numVerts );
newTri->indexCache = vertexCache.AllocIndex( newIndexes, numIndexes );
newTri->ambientCache = vertexCache.AllocVertex( newVerts, numVerts, sizeof( idDrawVert ), commandList );
newTri->indexCache = vertexCache.AllocIndex( newIndexes, numIndexes, sizeof( triIndex_t ), commandList );
drawSurf_t* drawSurf = ( drawSurf_t* )R_FrameAlloc( sizeof( *drawSurf ), FRAME_ALLOC_DRAW_SURFACE );
drawSurf->frontEndGeo = newTri;
@ -1133,11 +1133,21 @@ drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf )
return NULL;
}
return R_DeformDrawSurf( drawSurf, drawSurf->material->Deform() );
}
/*
=================
R_DeformDrawSurf
=================
*/
drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf, deform_t deformType )
{
if( r_skipDeforms.GetBool() )
{
return drawSurf;
}
switch( drawSurf->material->Deform() )
switch( deformType )
{
case DFRM_SPRITE:
return R_AutospriteDeform( drawSurf );
@ -1154,10 +1164,10 @@ drawSurf_t* R_DeformDrawSurf( drawSurf_t* drawSurf )
case DFRM_EYEBALL:
return R_EyeballDeform( drawSurf );
case DFRM_PARTICLE:
return R_ParticleDeform( drawSurf, true );
return R_ParticleDeform( drawSurf, true, nullptr );
case DFRM_PARTICLE2:
return R_ParticleDeform( drawSurf, false );
return R_ParticleDeform( drawSurf, false, nullptr );
default:
return NULL;
}
}
}

View file

@ -4,6 +4,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2014 Robert Beckebans
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -228,6 +229,7 @@ static viewDef_t* R_MirrorViewBySurface( const drawSurf_t* drawSurf )
viewDef_t* parms = ( viewDef_t* )R_FrameAlloc( sizeof( *parms ) );
*parms = *tr.viewDef;
parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons
parms->targetRender = nullptr;
parms->isSubview = true;
parms->isMirror = true;
@ -271,6 +273,97 @@ static viewDef_t* R_MirrorViewBySurface( const drawSurf_t* drawSurf )
return parms;
}
/*
========================
R_PortalViewBySurface
========================
*/
static viewDef_t* R_PortalViewBySurface( const drawSurf_t* surf )
{
if( !surf->space->entityDef->parms.remoteRenderView )
{
return nullptr;
}
// copy the viewport size from the original
viewDef_t* parms = ( viewDef_t* )R_FrameAlloc( sizeof( *parms ) );
*parms = *tr.viewDef;
idMat3 viewaxis = parms->renderView.viewaxis;
idMat3 remoteViewAxis = surf->space->entityDef->parms.remoteRenderView->viewaxis;
const idVec3 orig = parms->renderView.vieworg;
float fov_x = parms->renderView.fov_x;
float fov_y = parms->renderView.fov_y;
parms->renderView = *surf->space->entityDef->parms.remoteRenderView;
parms->renderView.fov_x = fov_x;
parms->renderView.fov_y = fov_y;
idAngles ang = viewaxis.ToAngles();
idAngles angleDiff;
idMat3 surfViewAxis;
// Difference in view axis
idPlane originalPlane, plane;
R_PlaneForSurface( surf->frontEndGeo, originalPlane );
R_LocalPlaneToGlobal( surf->space->modelMatrix, originalPlane, plane );
orientation_t surface;
surface.origin = plane.Normal() * -plane[3];
surface.axis[0] = plane.Normal();
surface.axis[0].NormalVectors( surface.axis[1], surface.axis[2] );
surface.axis[2] = -surface.axis[2];
surfViewAxis = surface.axis;
idAngles surfAng = surfViewAxis.ToAngles();
angleDiff = surfAng - ang;
idAngles origAngle = parms->renderView.viewaxis.ToAngles();
origAngle = origAngle - angleDiff;
origAngle.yaw -= 180;
origAngle.Normalize180();
parms->renderView.viewaxis = origAngle.ToMat3();
// Direction vector in camera space.
const idMat3 inverseSurfView = surfViewAxis.Transpose();
idVec3 dirToPortal = ( surf->space->entityDef->parms.origin - orig ) * inverseSurfView;
dirToPortal.z = -dirToPortal.z;
parms->renderView.vieworg += dirToPortal * remoteViewAxis;
// Set up oblique view clipping plane
parms->numClipPlanes = 1;
parms->clipPlanes[0] = remoteViewAxis[0];
parms->clipPlanes[0][3] = -( surf->space->entityDef->parms.remoteRenderView->vieworg * parms->clipPlanes[0].Normal() );
float dist = parms->clipPlanes[0].Dist();
float viewdist = parms->renderView.vieworg * parms->clipPlanes[0].Normal();
float fDist = -dist + viewdist;
// fudge avoids depth precision artifacts when performing oblique projection
static const float fudge = 2.f;
if( fDist > fudge || fDist < -fudge )
{
if( fDist < 0.f )
{
fDist += fudge;
}
else
{
fDist -= fudge;
}
}
parms->clipPlanes[0][3] = fDist;
parms->isObliqueProjection = true;
parms->renderView.viewID = 0; // clear to allow player bodies to show up, and suppress view weapons
parms->initialViewAreaOrigin = parms->renderView.vieworg;
parms->isSubview = true;
parms->isMirror = false;
return parms;
}
/*
========================
R_XrayViewBySurface
@ -519,29 +612,54 @@ bool R_GenerateSurfaceSubview( const drawSurf_t* drawSurf )
case DI_XRAY_RENDER:
R_XrayRender( drawSurf, const_cast<textureStage_t*>( &stage->texture ), scissor );
break;
case DI_GUI_RENDER:
case DI_RENDER_TARGET:
return false;
}
}
return true;
}
// issue a new view command
parms = R_MirrorViewBySurface( drawSurf );
if( parms == NULL )
if( shader->IsMirrorSubView() )
{
return false;
// issue a new view command
parms = R_MirrorViewBySurface( drawSurf );
if( parms == NULL )
{
return false;
}
parms->scissor = scissor;
parms->superView = tr.viewDef;
parms->subviewSurface = drawSurf;
// triangle culling order changes with mirroring
parms->isMirror = ( ( ( int )parms->isMirror ^ ( int )tr.viewDef->isMirror ) != 0 );
// generate render commands for it
R_RenderView( parms );
return true;
}
else if( shader->IsPortalSubView() )
{
parms = R_PortalViewBySurface( drawSurf );
if( parms == nullptr )
{
return false;
}
parms->scissor = scissor;
parms->superView = tr.viewDef;
parms->subviewSurface = drawSurf;
R_RenderView( parms );
return true;
}
parms->scissor = scissor;
parms->superView = tr.viewDef;
parms->subviewSurface = drawSurf;
// triangle culling order changes with mirroring
parms->isMirror = ( ( ( int )parms->isMirror ^ ( int )tr.viewDef->isMirror ) != 0 );
// generate render commands for it
R_RenderView( parms );
return true;
return false;
}
/*

View file

@ -2092,7 +2092,7 @@ deformInfo_t* R_BuildDeformInfo( int numVerts, const idDrawVert* verts, int numI
tri.dominantTris = NULL;
}
R_CreateDeformStaticVertices( deform, commandList );
//R_CreateDeformStaticVertices( deform, commandList );
return deform;
}

113
neo/sys/DeviceManager.cpp Normal file
View file

@ -0,0 +1,113 @@
#include "precompiled.h"
#pragma hdrstop
#include "DeviceManager.h"
// Either move RenderPass to sys or move window resizing logic
#include "renderer/RenderPass.h"
DeviceManager* DeviceManager::Create( nvrhi::GraphicsAPI api )
{
switch( api )
{
#if USE_DX11
case nvrhi::GraphicsAPI::D3D11:
return CreateD3D11();
#endif
#if USE_DX12
case nvrhi::GraphicsAPI::D3D12:
return CreateD3D12();
#endif
#if USE_VK
case nvrhi::GraphicsAPI::VULKAN:
return CreateVK();
#endif
default:
common->Error( "DeviceManager::Create: Unsupported Graphics API (%d)", api );
return nullptr;
}
}
void DeviceManager::GetWindowDimensions( int& width, int& height )
{
width = deviceParms.backBufferWidth;
height = deviceParms.backBufferHeight;
}
void DeviceManager::BackBufferResizing()
{
tr.backend.BackBufferResizing();
Framebuffer::Shutdown();
}
void DeviceManager::BackBufferResized()
{
Framebuffer::ResizeFramebuffers();
}
const DeviceCreationParameters& DeviceManager::GetDeviceParams()
{
return deviceParms;
}
nvrhi::IFramebuffer* DeviceManager::GetCurrentFramebuffer()
{
return GetFramebuffer( GetCurrentBackBufferIndex() );
}
nvrhi::IFramebuffer* DeviceManager::GetFramebuffer( uint32_t index )
{
if( index < globalFramebuffers.swapFramebuffers.Num() )
{
return globalFramebuffers.swapFramebuffers[index]->GetApiObject();
}
return nullptr;
}
void DeviceManager::AddRenderPassToBack( IRenderPass* pRenderPass )
{
renderPasses.Remove( pRenderPass );
renderPasses.Append( pRenderPass );
pRenderPass->BackBufferResizing();
pRenderPass->BackBufferResized(
deviceParms.backBufferWidth,
deviceParms.backBufferHeight,
deviceParms.swapChainSampleCount );
}
DeviceManager* DeviceManager::CreateD3D11()
{
return nullptr;
}
DeviceManager* DeviceManager::CreateVK()
{
return nullptr;
}
DefaultMessageCallback& DefaultMessageCallback::GetInstance()
{
static DefaultMessageCallback instance;
return instance;
}
void DefaultMessageCallback::message( nvrhi::MessageSeverity severity, const char* messageText )
{
switch( severity )
{
case nvrhi::MessageSeverity::Info:
common->Printf( messageText );
break;
case nvrhi::MessageSeverity::Warning:
common->Warning( messageText );
break;
case nvrhi::MessageSeverity::Error:
common->Error( messageText );
break;
case nvrhi::MessageSeverity::Fatal:
common->FatalError( messageText );
break;
}
}

212
neo/sys/DeviceManager.h Normal file
View file

@ -0,0 +1,212 @@
/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2022 Stephen Pridham
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef SYS_DEVICE_MANAGER_H_
#define SYS_DEVICE_MANAGER_H_
#include "renderer/RenderCommon.h"
struct DeviceCreationParameters
{
bool startMaximized = false;
bool startFullscreen = false;
bool allowModeSwitch = true;
int windowPosX = -1; // -1 means use default placement
int windowPosY = -1;
uint32_t backBufferWidth = 1280;
uint32_t backBufferHeight = 720;
uint32_t refreshRate = 0;
uint32_t swapChainBufferCount = 3;
nvrhi::Format swapChainFormat = nvrhi::Format::SRGBA8_UNORM;
uint32_t swapChainSampleCount = 1;
uint32_t swapChainSampleQuality = 0;
uint32_t maxFramesInFlight = 2;
bool enableDebugRuntime = false;
bool enableNvrhiValidationLayer = false;
bool vsyncEnabled = false;
bool enableRayTracingExtensions = false; // for vulkan
bool enableComputeQueue = false;
bool enableCopyQueue = false;
#if USE_DX11 || USE_DX12
// Adapter to create the device on. Setting this to non-null overrides adapterNameSubstring.
// If device creation fails on the specified adapter, it will *not* try any other adapters.
IDXGIAdapter* adapter = nullptr;
#endif
// For use in the case of multiple adapters; only effective if 'adapter' is null. If this is non-null, device creation will try to match
// the given string against an adapter name. If the specified string exists as a sub-string of the
// adapter name, the device and window will be created on that adapter. Case sensitive.
std::wstring adapterNameSubstring = L"";
// set to true to enable DPI scale factors to be computed per monitor
// this will keep the on-screen window size in pixels constant
//
// if set to false, the DPI scale factors will be constant but the system
// may scale the contents of the window based on DPI
//
// note that the backbuffer size is never updated automatically; if the app
// wishes to scale up rendering based on DPI, then it must set this to true
// and respond to DPI scale factor changes by resizing the backbuffer explicitly
bool enablePerMonitorDPI = false;
#if USE_DX11 || USE_DX12
DXGI_USAGE swapChainUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_1;
#endif
#if USE_VK
std::vector<std::string> requiredVulkanInstanceExtensions;
std::vector<std::string> requiredVulkanDeviceExtensions;
std::vector<std::string> requiredVulkanLayers;
std::vector<std::string> optionalVulkanInstanceExtensions;
std::vector<std::string> optionalVulkanDeviceExtensions;
std::vector<std::string> optionalVulkanLayers;
std::vector<size_t> ignoredVulkanValidationMessageLocations;
#endif
};
struct DefaultMessageCallback : public nvrhi::IMessageCallback
{
static DefaultMessageCallback& GetInstance();
void message( nvrhi::MessageSeverity severity, const char* messageText ) override;
};
class IRenderPass;
class idRenderBackend;
/// Initialize the window and graphics device.
class DeviceManager
{
public:
static DeviceManager* Create( nvrhi::GraphicsAPI api );
bool CreateWindowDeviceAndSwapChain( const glimpParms_t& params, const char* windowTitle );
// returns the size of the window in screen coordinates
void GetWindowDimensions( int& width, int& height );
// returns the screen coordinate to pixel coordinate scale factor
void GetDPIScaleInfo( float& x, float& y ) const
{
x = dpiScaleFactorX;
y = dpiScaleFactorY;
}
void UpdateWindowSize();
protected:
friend class idRenderBackend;
void* windowHandle;
bool windowVisible = false;
bool isNvidia = false;
DeviceCreationParameters deviceParms;
float dpiScaleFactorX = 1.f;
float dpiScaleFactorY = 1.f;
bool requestedVSync = false;
uint32_t m_FrameIndex = 0;
idList<IRenderPass*> renderPasses;
DeviceManager() = default;
void BackBufferResizing();
void BackBufferResized();
// device-specific methods
virtual bool CreateDeviceAndSwapChain() = 0;
virtual void DestroyDeviceAndSwapChain() = 0;
virtual void ResizeSwapChain() = 0;
virtual void BeginFrame() = 0;
virtual void Present() = 0;
public:
[[nodiscard]] virtual nvrhi::IDevice* GetDevice() const = 0;
[[nodiscard]] virtual const char* GetRendererString() const = 0;
[[nodiscard]] virtual nvrhi::GraphicsAPI GetGraphicsAPI() const = 0;
const DeviceCreationParameters& GetDeviceParams();
virtual void SetVsyncEnabled( bool enabled )
{
requestedVSync = enabled; /* will be processed later */
}
virtual void ReportLiveObjects() {}
[[nodiscard]] uint32_t GetFrameIndex() const
{
return m_FrameIndex;
}
virtual nvrhi::ITexture* GetCurrentBackBuffer() = 0;
virtual nvrhi::ITexture* GetBackBuffer( uint32_t index ) = 0;
virtual uint32_t GetCurrentBackBufferIndex() = 0;
virtual uint32_t GetBackBufferCount() = 0;
nvrhi::IFramebuffer* GetCurrentFramebuffer();
nvrhi::IFramebuffer* GetFramebuffer( uint32_t index );
void AddRenderPassToBack( IRenderPass* pRenderPass );
void Shutdown();
virtual ~DeviceManager() = default;
void SetWindowTitle( const char* title );
virtual bool IsVulkanInstanceExtensionEnabled( const char* extensionName ) const
{
return false;
}
virtual bool IsVulkanDeviceExtensionEnabled( const char* extensionName ) const
{
return false;
}
virtual bool IsVulkanLayerEnabled( const char* layerName ) const
{
return false;
}
virtual void GetEnabledVulkanInstanceExtensions( std::vector<std::string>& extensions ) const { }
virtual void GetEnabledVulkanDeviceExtensions( std::vector<std::string>& extensions ) const { }
virtual void GetEnabledVulkanLayers( std::vector<std::string>& layers ) const { }
private:
static DeviceManager* CreateD3D11();
static DeviceManager* CreateD3D12();
static DeviceManager* CreateVK();
std::string m_WindowTitle;
};
#endif

View file

@ -434,6 +434,10 @@ struct sysEvent_t
{
return evType == SE_MOUSE;
}
bool IsMouseAbsoluteEvent() const
{
return evType == SE_MOUSE_ABSOLUTE;
}
bool IsCharEvent() const
{
return evType == SE_CHAR;
@ -446,6 +450,10 @@ struct sysEvent_t
{
return evValue2 != 0;
}
bool IsKeyUp() const
{
return evValue2 == 0;
}
keyNum_t GetKey() const
{
return static_cast< keyNum_t >( evValue );

View file

@ -1778,7 +1778,7 @@ idSessionLocal::EndMatch
this is for when the game is over before we go back to lobby. Need this incase the host leaves during this time
========================
*/
void idSessionLocal::MatchFinished( )
void idSessionLocal::MatchFinished()
{
if( verify( GetActingGameStateLobby().IsHost() ) )
{