diff --git a/neo/renderer/Image_load.cpp b/neo/renderer/Image_load.cpp index 41a22599..2dbf97be 100644 --- a/neo/renderer/Image_load.cpp +++ b/neo/renderer/Image_load.cpp @@ -1024,6 +1024,7 @@ void idImage::GenerateImage( const byte* pic, int width, int height, textureFilt { const bimageImage_t& img = im.GetImageHeader( i ); const byte* data = im.GetImageData( i ); + int rowPitch = GetRowPitch( opts.format, img.width ); commandList->writeTexture( texture, img.destZ, img.level, data, rowPitch ); } @@ -1112,11 +1113,7 @@ void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t f { const bimageImage_t& img = im.GetImageHeader( i ); const byte* data = im.GetImageData( i ); - int bufferW = img.width; - if( IsCompressed() ) - { - bufferW = ( img.width + 3 ) & ~3; - } + commandList->writeTexture( texture, 0, img.level, data, GetRowPitch( opts.format, img.width ) ); } diff --git a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp index 8a0df7e9..ac8a3c68 100644 --- a/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp +++ b/neo/renderer/NVRHI/RenderBackend_NVRHI.cpp @@ -96,64 +96,10 @@ GL_CheckErrors // RB: added filename, line parms bool GL_CheckErrors_( const char* filename, int line ) { - int err; - char s[64]; - int i; - - if( r_ignoreGLErrors.GetBool() ) - { - return false; - } - - // check for up to 10 errors pending - bool error = false; - for( i = 0 ; i < 10 ; i++ ) - { - err = glGetError(); - if( err == GL_NO_ERROR ) - { - break; - } - - error = true; - switch( err ) - { - case GL_INVALID_ENUM: - strcpy( s, "GL_INVALID_ENUM" ); - break; - case GL_INVALID_VALUE: - strcpy( s, "GL_INVALID_VALUE" ); - break; - case GL_INVALID_OPERATION: - strcpy( s, "GL_INVALID_OPERATION" ); - break; -#if !defined(USE_GLES2) && !defined(USE_GLES3) - case GL_STACK_OVERFLOW: - strcpy( s, "GL_STACK_OVERFLOW" ); - break; - case GL_STACK_UNDERFLOW: - strcpy( s, "GL_STACK_UNDERFLOW" ); - break; -#endif - case GL_OUT_OF_MEMORY: - strcpy( s, "GL_OUT_OF_MEMORY" ); - break; - default: - idStr::snPrintf( s, sizeof( s ), "%i", err ); - break; - } - - common->Printf( "caught OpenGL error: %s in file %s line %i\n", s, filename, line ); - } - - return error; + return false; } - - - - /* ======================== DebugCallback @@ -661,6 +607,16 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) int program = renderProgManager.CurrentProgram(); int bindingLayoutType = renderProgManager.BindingLayoutType(); auto& info = renderProgManager.GetProgramInfo( program ); + /* + if( info.cs ) + { + renderLog.OpenBlock( info.cs->getDesc().debugName.c_str() ); + } + else + { + renderLog.OpenBlock( info.ps->getDesc().debugName.c_str() ); + } + */ for( int i = 0; i < info.bindingLayouts->Num(); i++ ) { @@ -673,7 +629,7 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) renderProgManager.CommitConstantBuffer( commandList ); - PipelineKey key{ glStateBits, program, viewDef->isMirror, depthBias, slopeScaleBias, currentFrameBuffer }; + PipelineKey key{ glStateBits, program, depthBias, slopeScaleBias, currentFrameBuffer }; auto pipeline = pipelineCache.GetOrCreatePipeline( key ); if( currentPipeline != pipeline ) @@ -722,6 +678,8 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf ) // RB: added stats pc.c_drawElements++; pc.c_drawIndexes += surf->numIndexes; + + //renderLog.CloseBlock(); } void idRenderBackend::GetCurrentBindingLayout() @@ -970,24 +928,14 @@ void idRenderBackend::GL_SetDefaultState() memset( &glcontext.tmu, 0, sizeof( glcontext.tmu ) ); glStateBits = 0; - currentRenderState.depthStencilState.enableDepthWrite(); - currentRenderState.depthStencilState.enableStencil(); GL_State( 0, true ); - currentRenderState.depthStencilState.enableDepthTest(); - currentRenderState.blendState.targets[0].enableBlend(); - - if( r_useScissor.GetBool() ) - { - GL_Scissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() ); - } + GL_Scissor( 0, 0, renderSystem->GetWidth(), renderSystem->GetHeight() ); renderProgManager.Unbind(); - // RB begin Framebuffer::Unbind(); - // RB end } /* @@ -999,397 +947,13 @@ This routine is responsible for setting the most commonly changed state */ void idRenderBackend::GL_State( uint64 stateBits, bool forceGlState ) { - uint64 diff = stateBits ^ glStateBits; - - if( !r_useStateCaching.GetBool() || forceGlState ) + glStateBits = stateBits | ( glStateBits & GLS_KEEP ); + if( viewDef != NULL && viewDef->isMirror ) { - // make sure everything is set all the time, so we - // can see if our delta checking is screwing up - diff = 0xFFFFFFFFFFFFFFFF; - } - else if( diff == 0 ) - { - return; + glStateBits |= GLS_MIRROR_VIEW; } - // Reset pipeline - currentPipeline = nullptr; - - auto& currentBlendState = currentRenderState.blendState; - auto& currentDepthStencilState = currentRenderState.depthStencilState; - auto& currentRasterState = currentRenderState.rasterState; - - // - // culling - // - if( diff & ( GLS_CULL_BITS ) )//| GLS_MIRROR_VIEW ) ) - { - switch( stateBits & GLS_CULL_BITS ) - { - case GLS_CULL_TWOSIDED: - currentRasterState.setCullNone(); - break; - - case GLS_CULL_BACKSIDED: - if( viewDef != NULL && viewDef->isMirror ) - { - stateBits |= GLS_MIRROR_VIEW; - currentRasterState.setCullFront(); - } - else - { - currentRasterState.setCullBack(); - } - break; - - case GLS_CULL_FRONTSIDED: - default: - if( viewDef != NULL && viewDef->isMirror ) - { - stateBits |= GLS_MIRROR_VIEW; - currentRasterState.setCullBack(); - } - else - { - currentRasterState.setCullFront(); - } - break; - } - } - - // - // check depthFunc bits - // - if( diff & GLS_DEPTHFUNC_BITS ) - { - switch( stateBits & GLS_DEPTHFUNC_BITS ) - { - case GLS_DEPTHFUNC_EQUAL: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Equal; - break; - case GLS_DEPTHFUNC_ALWAYS: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Always; - break; - case GLS_DEPTHFUNC_LESS: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Less; - break; - case GLS_DEPTHFUNC_GREATER: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Greater; - break; - } - } - - nvrhi::BlendState::RenderTarget renderTarget; - - // - // check blend bits - // - if( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) - { - nvrhi::BlendFactor srcFactor = nvrhi::BlendFactor::One; - nvrhi::BlendFactor dstFactor = nvrhi::BlendFactor::One; - - switch( stateBits & GLS_SRCBLEND_BITS ) - { - case GLS_SRCBLEND_ZERO: - srcFactor = nvrhi::BlendFactor::Zero; - break; - case GLS_SRCBLEND_ONE: - srcFactor = nvrhi::BlendFactor::One; - break; - case GLS_SRCBLEND_DST_COLOR: - srcFactor = nvrhi::BlendFactor::DstColor; - break; - case GLS_SRCBLEND_ONE_MINUS_DST_COLOR: - srcFactor = nvrhi::BlendFactor::OneMinusDstColor; - break; - case GLS_SRCBLEND_SRC_ALPHA: - srcFactor = nvrhi::BlendFactor::SrcAlpha; - break; - case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA: - srcFactor = nvrhi::BlendFactor::OneMinusSrcAlpha; - break; - case GLS_SRCBLEND_DST_ALPHA: - srcFactor = nvrhi::BlendFactor::DstAlpha; - break; - case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA: - srcFactor = nvrhi::BlendFactor::OneMinusDstAlpha; - break; - default: - assert( !"GL_State: invalid src blend state bits\n" ); - break; - } - - switch( stateBits & GLS_DSTBLEND_BITS ) - { - case GLS_DSTBLEND_ZERO: - dstFactor = nvrhi::BlendFactor::Zero; - break; - case GLS_DSTBLEND_ONE: - dstFactor = nvrhi::BlendFactor::One; - break; - case GLS_DSTBLEND_SRC_COLOR: - dstFactor = nvrhi::BlendFactor::SrcColor; - break; - case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR: - dstFactor = nvrhi::BlendFactor::OneMinusSrcColor; - break; - case GLS_DSTBLEND_SRC_ALPHA: - dstFactor = nvrhi::BlendFactor::SrcAlpha; - break; - case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA: - dstFactor = nvrhi::BlendFactor::OneMinusSrcAlpha; - break; - case GLS_DSTBLEND_DST_ALPHA: - dstFactor = nvrhi::BlendFactor::DstAlpha; - break; - case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA: - dstFactor = nvrhi::BlendFactor::OneMinusDstAlpha; - break; - default: - assert( !"GL_State: invalid dst blend state bits\n" ); - break; - } - - // Only actually update GL's blend func if blending is enabled. - if( srcFactor == nvrhi::BlendFactor::One && dstFactor == nvrhi::BlendFactor::Zero ) - { - renderTarget.disableBlend(); - } - else - { - currentBlendState.setAlphaToCoverageEnable( true ); - renderTarget.enableBlend(); - renderTarget.setSrcBlend( srcFactor ); - renderTarget.setDestBlend( dstFactor ); - } - } - - // - // check depthmask - // - if( diff & GLS_DEPTHMASK ) - { - if( stateBits & GLS_DEPTHMASK ) - { - currentDepthStencilState.disableDepthWrite(); - if( ( stateBits & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_ALWAYS ) - { - currentDepthStencilState.disableDepthTest(); - } - } - } - - // - // check colormask - // - if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) ) - { - nvrhi::ColorMask mask{ nvrhi::ColorMask::All }; - - if( stateBits & GLS_REDMASK ) - { - mask = mask & ~nvrhi::ColorMask::Red; - } - if( stateBits & GLS_GREENMASK ) - { - mask = mask & ~nvrhi::ColorMask::Green; - } - if( stateBits & GLS_BLUEMASK ) - { - mask = mask & ~nvrhi::ColorMask::Blue; - } - if( stateBits & GLS_ALPHAMASK ) - { - mask = mask & ~nvrhi::ColorMask::Alpha; - } - - renderTarget.setBlendEnable( true ); - renderTarget.setColorWriteMask( mask ); - } - - currentBlendState.setRenderTarget( 0, renderTarget ); - - // - // fill/line mode - // - if( diff & GLS_POLYMODE_LINE ) - { - if( stateBits & GLS_POLYMODE_LINE ) - { - currentRasterState.setFillMode( nvrhi::RasterFillMode::Line ); - currentRasterState.setCullNone(); - } - else - { - currentRasterState.setCullNone(); - currentRasterState.setFillMode( nvrhi::RasterFillMode::Fill ); - } - } - - // - // polygon offset - // - if( diff & GLS_POLYGON_OFFSET ) - { - if( stateBits & GLS_POLYGON_OFFSET ) - { - currentRasterState.enableQuadFill(); - } - else - { - currentRasterState.disableQuadFill(); - } - } - - nvrhi::DepthStencilState::StencilOpDesc stencilOp; - - // - // stencil - // - if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) - { - if( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 ) - { - currentDepthStencilState.enableStencil(); - //currentDepthStencilState.enableDepthWrite(); - } - else - { - currentDepthStencilState.disableStencil(); - //currentDepthStencilState.disableDepthWrite(); - } - } - if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) ) - { - GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); - GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); - GLenum func = 0; - - currentDepthStencilState.setStencilRefValue( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); - currentDepthStencilState.setStencilReadMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); - currentDepthStencilState.setStencilWriteMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); - - switch( stateBits & GLS_STENCIL_FUNC_BITS ) - { - case GLS_STENCIL_FUNC_NEVER: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Never ); - break; - case GLS_STENCIL_FUNC_LESS: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Less ); - break; - case GLS_STENCIL_FUNC_EQUAL: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Equal ); - break; - case GLS_STENCIL_FUNC_LEQUAL: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::LessOrEqual ); - break; - case GLS_STENCIL_FUNC_GREATER: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Greater ); - break; - case GLS_STENCIL_FUNC_NOTEQUAL: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::NotEqual ); - break; - case GLS_STENCIL_FUNC_GEQUAL: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::GreaterOrEqual ); - break; - case GLS_STENCIL_FUNC_ALWAYS: - stencilOp.setStencilFunc( nvrhi::ComparisonFunc::Always ); - break; - } - } - if( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) ) - { - GLenum sFail = 0; - GLenum zFail = 0; - GLenum pass = 0; - - switch( stateBits & GLS_STENCIL_OP_FAIL_BITS ) - { - case GLS_STENCIL_OP_FAIL_KEEP: - stencilOp.setFailOp( nvrhi::StencilOp::Keep ); - break; - case GLS_STENCIL_OP_FAIL_ZERO: - stencilOp.setFailOp( nvrhi::StencilOp::Zero ); - break; - case GLS_STENCIL_OP_FAIL_REPLACE: - stencilOp.setFailOp( nvrhi::StencilOp::Replace ); - break; - case GLS_STENCIL_OP_FAIL_INCR: - stencilOp.setFailOp( nvrhi::StencilOp::IncrementAndClamp ); - break; - case GLS_STENCIL_OP_FAIL_DECR: - stencilOp.setFailOp( nvrhi::StencilOp::DecrementAndClamp ); - break; - case GLS_STENCIL_OP_FAIL_INVERT: - stencilOp.setFailOp( nvrhi::StencilOp::Invert ); - break; - case GLS_STENCIL_OP_FAIL_INCR_WRAP: - stencilOp.setFailOp( nvrhi::StencilOp::IncrementAndWrap ); - break; - case GLS_STENCIL_OP_FAIL_DECR_WRAP: - stencilOp.setFailOp( nvrhi::StencilOp::DecrementAndWrap ); - break; - } - switch( stateBits & GLS_STENCIL_OP_ZFAIL_BITS ) - { - case GLS_STENCIL_OP_ZFAIL_KEEP: - stencilOp.setDepthFailOp( nvrhi::StencilOp::Keep ); - break; - case GLS_STENCIL_OP_ZFAIL_ZERO: - stencilOp.setDepthFailOp( nvrhi::StencilOp::Zero ); - break; - case GLS_STENCIL_OP_ZFAIL_REPLACE: - stencilOp.setDepthFailOp( nvrhi::StencilOp::Replace ); - break; - case GLS_STENCIL_OP_ZFAIL_INCR: - stencilOp.setDepthFailOp( nvrhi::StencilOp::IncrementAndClamp ); - break; - case GLS_STENCIL_OP_ZFAIL_DECR: - stencilOp.setDepthFailOp( nvrhi::StencilOp::DecrementAndClamp ); - break; - case GLS_STENCIL_OP_ZFAIL_INVERT: - stencilOp.setDepthFailOp( nvrhi::StencilOp::Invert ); - break; - case GLS_STENCIL_OP_ZFAIL_INCR_WRAP: - stencilOp.setDepthFailOp( nvrhi::StencilOp::IncrementAndWrap ); - break; - case GLS_STENCIL_OP_ZFAIL_DECR_WRAP: - stencilOp.setDepthFailOp( nvrhi::StencilOp::DecrementAndWrap ); - break; - } - switch( stateBits & GLS_STENCIL_OP_PASS_BITS ) - { - case GLS_STENCIL_OP_PASS_KEEP: - stencilOp.setPassOp( nvrhi::StencilOp::Keep ); - break; - case GLS_STENCIL_OP_PASS_ZERO: - stencilOp.setPassOp( nvrhi::StencilOp::Zero ); - break; - case GLS_STENCIL_OP_PASS_REPLACE: - stencilOp.setPassOp( nvrhi::StencilOp::Replace ); - break; - case GLS_STENCIL_OP_PASS_INCR: - stencilOp.setPassOp( nvrhi::StencilOp::IncrementAndClamp ); - break; - case GLS_STENCIL_OP_PASS_DECR: - stencilOp.setPassOp( nvrhi::StencilOp::DecrementAndClamp ); - break; - case GLS_STENCIL_OP_PASS_INVERT: - stencilOp.setPassOp( nvrhi::StencilOp::Invert ); - break; - case GLS_STENCIL_OP_PASS_INCR_WRAP: - stencilOp.setPassOp( nvrhi::StencilOp::IncrementAndWrap ); - break; - case GLS_STENCIL_OP_PASS_DECR_WRAP: - stencilOp.setPassOp( nvrhi::StencilOp::DecrementAndWrap ); - break; - } - } - - currentDepthStencilState.setFrontFaceStencil( stencilOp ); - - glStateBits = stateBits; + // the rest of this is handled by PipelineCache::GetOrCreatePipeline and GetRenderState similar to Vulkan } /* diff --git a/neo/renderer/PipelineCache.cpp b/neo/renderer/PipelineCache.cpp index 2d7b92fc..1109acc5 100644 --- a/neo/renderer/PipelineCache.cpp +++ b/neo/renderer/PipelineCache.cpp @@ -1,11 +1,38 @@ -#include -#pragma hdrstrop +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +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 . + +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 "renderer/RenderCommon.h" - #include "PipelineCache.h" -void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& renderState ); + PipelineCache::PipelineCache() { @@ -52,8 +79,8 @@ nvrhi::GraphicsPipelineHandle PipelineCache::GetOrCreatePipeline( const Pipeline target.enableBlend(); } //pipelineDesc.renderState.rasterState.enableDepthClip(); - pipelineDesc.renderState.rasterState.depthBias = 0; - pipelineDesc.renderState.rasterState.slopeScaledDepthBias = 0; + //pipelineDesc.renderState.rasterState.depthBias = 0; + //pipelineDesc.renderState.rasterState.slopeScaledDepthBias = 0; // Specialize the state with the state key. GetRenderState( key.state, key, pipelineDesc.renderState ); @@ -66,76 +93,86 @@ nvrhi::GraphicsPipelineHandle PipelineCache::GetOrCreatePipeline( const Pipeline } -void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& renderState ) +void PipelineCache::GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& renderState ) { + /* uint64 diff = stateBits ^ GLS_DEFAULT; if( diff == 0 ) { return; } + */ - auto& currentBlendState = renderState.blendState; - auto& currentDepthStencilState = renderState.depthStencilState; - auto& currentRasterState = renderState.rasterState; + auto& rasterizationState = renderState.rasterState; // - // culling + // culling & mirrors // - if( diff & ( GLS_CULL_BITS ) )//| GLS_MIRROR_VIEW ) ) + //if( stateBits & ( GLS_CULL_BITS ) )//| GLS_MIRROR_VIEW ) ) { switch( stateBits & GLS_CULL_BITS ) { case GLS_CULL_TWOSIDED: - currentRasterState.setCullNone(); + rasterizationState.setCullNone(); break; case GLS_CULL_BACKSIDED: - if( key.mirrored ) + if( stateBits & GLS_MIRROR_VIEW ) { - stateBits |= GLS_MIRROR_VIEW; - currentRasterState.setCullFront(); + rasterizationState.setCullFront(); } else { - currentRasterState.setCullBack(); + rasterizationState.setCullBack(); } break; case GLS_CULL_FRONTSIDED: default: - if( key.mirrored ) + if( stateBits & GLS_MIRROR_VIEW ) { - stateBits |= GLS_MIRROR_VIEW; - currentRasterState.setCullBack(); + rasterizationState.setCullBack(); } else { - currentRasterState.setCullFront(); + rasterizationState.setCullFront(); } break; } } + rasterizationState.setFrontCounterClockwise( ( stateBits & GLS_CLOCKWISE ) == 0 ); + // - // check depthFunc bits + // fill/line mode // - if( diff & GLS_DEPTHFUNC_BITS ) + //if( diff & GLS_POLYMODE_LINE ) { - switch( stateBits & GLS_DEPTHFUNC_BITS ) + if( stateBits & GLS_POLYMODE_LINE ) { - case GLS_DEPTHFUNC_EQUAL: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Equal; - break; - case GLS_DEPTHFUNC_ALWAYS: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Always; - break; - case GLS_DEPTHFUNC_LESS: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Less; - break; - case GLS_DEPTHFUNC_GREATER: - currentDepthStencilState.depthFunc = nvrhi::ComparisonFunc::Greater; - break; + rasterizationState.setFillMode( nvrhi::RasterFillMode::Wireframe ); + } + else + { + rasterizationState.setFillMode( nvrhi::RasterFillMode::Solid ); + } + } + + // + // polygon offset + // + //if( diff & GLS_POLYGON_OFFSET ) + { + if( stateBits & GLS_POLYGON_OFFSET ) + { + rasterizationState.depthBias = key.depthBias; + rasterizationState.slopeScaledDepthBias = key.slopeBias; + rasterizationState.enableQuadFill(); + } + else + { + //currentRasterState.disableQuadFill(); } } @@ -144,11 +181,9 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend // // check blend bits // - if( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) + //if( stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) ) { nvrhi::BlendFactor srcFactor = nvrhi::BlendFactor::One; - nvrhi::BlendFactor dstFactor = nvrhi::BlendFactor::One; - switch( stateBits & GLS_SRCBLEND_BITS ) { case GLS_SRCBLEND_ZERO: @@ -180,6 +215,7 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend break; } + nvrhi::BlendFactor dstFactor = nvrhi::BlendFactor::Zero; switch( stateBits & GLS_DSTBLEND_BITS ) { case GLS_DSTBLEND_ZERO: @@ -211,6 +247,24 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend break; } + // RB: blend ops are only used by the SWF render states so far + nvrhi::BlendOp blendOp = nvrhi::BlendOp::Add; + switch( stateBits & GLS_BLENDOP_BITS ) + { + case GLS_BLENDOP_MIN: + blendOp = nvrhi::BlendOp::Min; + break; + case GLS_BLENDOP_MAX: + blendOp = nvrhi::BlendOp::Max; + break; + case GLS_BLENDOP_ADD: + blendOp = nvrhi::BlendOp::Add; + break; + case GLS_BLENDOP_SUB: + blendOp = nvrhi::BlendOp::Subrtact; + break; + } + // Only actually update GL's blend func if blending is enabled. if( srcFactor == nvrhi::BlendFactor::One && dstFactor == nvrhi::BlendFactor::Zero ) { @@ -218,32 +272,23 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend } else { - currentBlendState.setAlphaToCoverageEnable( true ); + //colorBlendState.setAlphaToCoverageEnable( true ); renderTarget.enableBlend(); + + //renderTarget.setBlendOp( blendOp ); renderTarget.setSrcBlend( srcFactor ); renderTarget.setDestBlend( dstFactor ); - } - } - // - // check depthmask - // - if( diff & GLS_DEPTHMASK ) - { - if( stateBits & GLS_DEPTHMASK ) - { - currentDepthStencilState.disableDepthWrite(); - if( ( stateBits & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_ALWAYS ) - { - currentDepthStencilState.disableDepthTest(); - } + //renderTarget.setBlendOpAlpha( blendOp ); + //renderTarget.setSrcBlendAlpha( srcFactor ); + //renderTarget.setDestBlendAlpha( dstFactor ); } } // // check colormask // - if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) ) + //if( diff & ( GLS_REDMASK | GLS_GREENMASK | GLS_BLUEMASK | GLS_ALPHAMASK ) ) { nvrhi::ColorMask mask{ nvrhi::ColorMask::All }; @@ -268,39 +313,45 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend renderTarget.setColorWriteMask( mask ); } - currentBlendState.setRenderTarget( 0, renderTarget ); + renderState.blendState.setRenderTarget( 0, renderTarget ); + + + auto& depthStencilState = renderState.depthStencilState; // - // fill/line mode + // check depthFunc bits // - if( diff & GLS_POLYMODE_LINE ) + //if( diff & GLS_DEPTHFUNC_BITS ) { - if( stateBits & GLS_POLYMODE_LINE ) + switch( stateBits & GLS_DEPTHFUNC_BITS ) { - currentRasterState.setFillMode( nvrhi::RasterFillMode::Wireframe ); - //currentRasterState.setCullNone(); - } - else - { - //currentRasterState.setCullNone(); - currentRasterState.setFillMode( nvrhi::RasterFillMode::Solid ); + case GLS_DEPTHFUNC_EQUAL: + depthStencilState.depthFunc = nvrhi::ComparisonFunc::Equal; + break; + case GLS_DEPTHFUNC_ALWAYS: + depthStencilState.depthFunc = nvrhi::ComparisonFunc::Always; + break; + case GLS_DEPTHFUNC_LESS: + depthStencilState.depthFunc = nvrhi::ComparisonFunc::LessOrEqual; + break; + case GLS_DEPTHFUNC_GREATER: + depthStencilState.depthFunc = nvrhi::ComparisonFunc::Greater; + break; } } // - // polygon offset + // check depthmask // - if( diff & GLS_POLYGON_OFFSET ) + //if( diff & GLS_DEPTHMASK ) { - if( stateBits & GLS_POLYGON_OFFSET ) + if( stateBits & GLS_DEPTHMASK ) { - currentRasterState.depthBias = key.depthBias; - currentRasterState.slopeScaledDepthBias = key.slopeBias; - currentRasterState.enableQuadFill(); - } - else - { - //currentRasterState.disableQuadFill(); + depthStencilState.disableDepthWrite(); + if( ( stateBits & GLS_DEPTHFUNC_BITS ) == GLS_DEPTHFUNC_ALWAYS ) + { + depthStencilState.disableDepthTest(); + } } } @@ -309,28 +360,27 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend // // stencil // - if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) + //if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) { if( ( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) != 0 ) { - currentDepthStencilState.enableStencil(); - //currentDepthStencilState.enableDepthWrite(); + depthStencilState.enableStencil(); } else { - currentDepthStencilState.disableStencil(); - //currentDepthStencilState.disableDepthWrite(); + depthStencilState.disableStencil(); } } - if( diff & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) ) + + if( stateBits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_FUNC_REF_BITS | GLS_STENCIL_FUNC_MASK_BITS ) ) { GLuint ref = GLuint( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); GLuint mask = GLuint( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); GLenum func = 0; - currentDepthStencilState.setStencilRefValue( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); - currentDepthStencilState.setStencilReadMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); - currentDepthStencilState.setStencilWriteMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); + depthStencilState.setStencilRefValue( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT ); + depthStencilState.setStencilReadMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); + depthStencilState.setStencilWriteMask( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT ); switch( stateBits & GLS_STENCIL_FUNC_BITS ) { @@ -360,7 +410,8 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend break; } } - if( diff & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) ) + + if( stateBits & ( GLS_STENCIL_OP_FAIL_BITS | GLS_STENCIL_OP_ZFAIL_BITS | GLS_STENCIL_OP_PASS_BITS ) ) { GLenum sFail = 0; GLenum zFail = 0; @@ -393,6 +444,7 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend stencilOp.setFailOp( nvrhi::StencilOp::DecrementAndWrap ); break; } + switch( stateBits & GLS_STENCIL_OP_ZFAIL_BITS ) { case GLS_STENCIL_OP_ZFAIL_KEEP: @@ -420,6 +472,7 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend stencilOp.setDepthFailOp( nvrhi::StencilOp::DecrementAndWrap ); break; } + switch( stateBits & GLS_STENCIL_OP_PASS_BITS ) { case GLS_STENCIL_OP_PASS_KEEP: @@ -449,5 +502,5 @@ void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& rend } } - currentDepthStencilState.setFrontFaceStencil( stencilOp ); + depthStencilState.setFrontFaceStencil( stencilOp ); } \ No newline at end of file diff --git a/neo/renderer/PipelineCache.h b/neo/renderer/PipelineCache.h index ae49e677..2524f74c 100644 --- a/neo/renderer/PipelineCache.h +++ b/neo/renderer/PipelineCache.h @@ -1,12 +1,37 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +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 . + +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 RENDERER_PIPELINECACHE_H_ #define RENDERER_PIPELINECACHE_H_ - struct PipelineKey { uint64 state; int program; - bool mirrored; int depthBias; float slopeBias; @@ -17,7 +42,6 @@ inline bool operator==( const PipelineKey& lhs, const PipelineKey& rhs ) { return lhs.state == rhs.state && lhs.program == rhs.program && - lhs.mirrored == rhs.mirrored && lhs.framebuffer == rhs.framebuffer && lhs.depthBias == rhs.depthBias && lhs.slopeBias == rhs.slopeBias; @@ -31,7 +55,6 @@ struct std::hash std::size_t h = 0; nvrhi::hash_combine( h, key.state ); nvrhi::hash_combine( h, key.program ); - nvrhi::hash_combine( h, key.mirrored ); nvrhi::hash_combine( h, key.framebuffer ); nvrhi::hash_combine( h, key.depthBias ); nvrhi::hash_combine( h, key.slopeBias ); @@ -53,6 +76,8 @@ public: private: + void GetRenderState( uint64 stateBits, PipelineKey key, nvrhi::RenderState& renderState ); + nvrhi::DeviceHandle device; idHashIndex pipelineHash; idList> pipelines; diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index d18b0ad7..68c365c8 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -513,7 +513,7 @@ private: idStaticList pendingBindingSetDescs; nvrhi::BindingLayoutHandle currentBindingLayout; nvrhi::GraphicsPipelineHandle currentPipeline; - nvrhi::RenderState currentRenderState; + //nvrhi::RenderState currentRenderState; Framebuffer* currentFrameBuffer; Framebuffer* lastFrameBuffer;