The main menu renders with Vulkan

This commit is contained in:
Robert Beckebans 2018-11-02 22:13:15 +01:00
parent 33c7d06871
commit 2f8413b2ee
6 changed files with 376 additions and 18 deletions

View file

@ -453,13 +453,20 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef )
ymin += jittery * height;
ymax += jittery * height;
// RB: IMPORTANT - the projectionMatrix has a few changes to make it work with Vulkan
// In Vulkan is the y-axis flipped
viewDef->projectionMatrix[0 * 4 + 0] = 2.0f * zNear / width;
viewDef->projectionMatrix[1 * 4 + 0] = 0.0f;
viewDef->projectionMatrix[2 * 4 + 0] = ( xmax + xmin ) / width; // normally 0
viewDef->projectionMatrix[3 * 4 + 0] = 0.0f;
viewDef->projectionMatrix[0 * 4 + 1] = 0.0f;
#if defined(USE_VULKAN)
viewDef->projectionMatrix[1 * 4 + 1] = -2.0f * zNear / height;
#else
viewDef->projectionMatrix[1 * 4 + 1] = 2.0f * zNear / height;
#endif
viewDef->projectionMatrix[2 * 4 + 1] = ( ymax + ymin ) / height; // normally 0
viewDef->projectionMatrix[3 * 4 + 1] = 0.0f;
@ -468,8 +475,8 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef )
// rasterize right at the wraparound point
viewDef->projectionMatrix[0 * 4 + 2] = 0.0f;
viewDef->projectionMatrix[1 * 4 + 2] = 0.0f;
viewDef->projectionMatrix[2 * 4 + 2] = -0.999f; // adjust value to prevent imprecision issues
viewDef->projectionMatrix[3 * 4 + 2] = -2.0f * zNear;
viewDef->projectionMatrix[2 * 4 + 2] = -0.999f; // adjust value to prevent imprecision issues
viewDef->projectionMatrix[3 * 4 + 2] = -1.0f * zNear; // RB: was -2.0f * zNear
viewDef->projectionMatrix[0 * 4 + 3] = 0.0f;
viewDef->projectionMatrix[1 * 4 + 3] = 0.0f;
@ -481,10 +488,6 @@ void R_SetupProjectionMatrix( viewDef_t* viewDef )
viewDef->projectionMatrix[1 * 4 + 1] = -viewDef->projectionMatrix[1 * 4 + 1];
viewDef->projectionMatrix[1 * 4 + 3] = -viewDef->projectionMatrix[1 * 4 + 3];
}
#if defined(USE_VULKAN)
viewDef->projectionMatrix[1 * 4 + 1] *= -1.0F;
#endif
}

View file

@ -265,30 +265,34 @@ void idGuiModel::EmitFullScreen()
viewDef->scissor.x2 = viewDef->viewport.x2 - viewDef->viewport.x1;
viewDef->scissor.y2 = viewDef->viewport.y2 - viewDef->viewport.y1;
// RB: IMPORTANT - the projectionMatrix has a few changes to make it work with Vulkan
viewDef->projectionMatrix[0 * 4 + 0] = 2.0f / renderSystem->GetVirtualWidth();
viewDef->projectionMatrix[0 * 4 + 1] = 0.0f;
viewDef->projectionMatrix[0 * 4 + 2] = 0.0f;
viewDef->projectionMatrix[0 * 4 + 3] = 0.0f;
viewDef->projectionMatrix[1 * 4 + 0] = 0.0f;
#if defined(USE_VULKAN)
viewDef->projectionMatrix[1 * 4 + 1] = 2.0f / renderSystem->GetVirtualHeight();
#else
viewDef->projectionMatrix[1 * 4 + 1] = -2.0f / renderSystem->GetVirtualHeight();
#endif
viewDef->projectionMatrix[1 * 4 + 2] = 0.0f;
viewDef->projectionMatrix[1 * 4 + 3] = 0.0f;
viewDef->projectionMatrix[2 * 4 + 0] = 0.0f;
viewDef->projectionMatrix[2 * 4 + 1] = 0.0f;
viewDef->projectionMatrix[2 * 4 + 2] = -2.0f;
viewDef->projectionMatrix[2 * 4 + 2] = -1.0f;
viewDef->projectionMatrix[2 * 4 + 3] = 0.0f;
viewDef->projectionMatrix[3 * 4 + 0] = -1.0f;
viewDef->projectionMatrix[3 * 4 + 1] = 1.0f;
viewDef->projectionMatrix[3 * 4 + 2] = -1.0f;
viewDef->projectionMatrix[3 * 4 + 3] = 1.0f;
viewDef->projectionMatrix[3 * 4 + 0] = -1.0f; // RB: was -2.0f
#if defined(USE_VULKAN)
viewDef->projectionMatrix[1 * 4 + 1] *= -1.0F;
viewDef->projectionMatrix[3 * 4 + 1] *= -1.0F;
viewDef->projectionMatrix[3 * 4 + 1] = -1.0f;
#else
viewDef->projectionMatrix[3 * 4 + 1] = 1.0f;
#endif
viewDef->projectionMatrix[3 * 4 + 2] = 0.0f; // RB: was 1.0f
viewDef->projectionMatrix[3 * 4 + 3] = 1.0f;
// make a tech5 renderMatrix for faster culling
idRenderMatrix::Transpose( *( idRenderMatrix* )viewDef->projectionMatrix, viewDef->projectionRenderMatrix );

View file

@ -421,3 +421,293 @@ void idRenderProgManager::SetRenderParm( renderParm_t rp, const float* value )
SetUniformValue( rp, value );
}
/*
========================
RpPrintState
========================
*/
void RpPrintState( uint64 stateBits, uint64* stencilBits )
{
// culling
idLib::Printf( "Culling: " );
switch( stateBits & GLS_CULL_BITS )
{
case GLS_CULL_FRONTSIDED:
idLib::Printf( "FRONTSIDED -> BACK" );
break;
case GLS_CULL_BACKSIDED:
idLib::Printf( "BACKSIDED -> FRONT" );
break;
case GLS_CULL_TWOSIDED:
idLib::Printf( "TWOSIDED" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( "\n" );
// polygon mode
idLib::Printf( "PolygonMode: %s\n", ( stateBits & GLS_POLYMODE_LINE ) ? "LINE" : "FILL" );
// color mask
idLib::Printf( "ColorMask: " );
idLib::Printf( ( stateBits & GLS_REDMASK ) ? "_" : "R" );
idLib::Printf( ( stateBits & GLS_GREENMASK ) ? "_" : "G" );
idLib::Printf( ( stateBits & GLS_BLUEMASK ) ? "_" : "B" );
idLib::Printf( ( stateBits & GLS_ALPHAMASK ) ? "_" : "A" );
idLib::Printf( "\n" );
// blend
idLib::Printf( "Blend: src=" );
switch( stateBits & GLS_SRCBLEND_BITS )
{
case GLS_SRCBLEND_ZERO:
idLib::Printf( "ZERO" );
break;
case GLS_SRCBLEND_ONE:
idLib::Printf( "ONE" );
break;
case GLS_SRCBLEND_DST_COLOR:
idLib::Printf( "DST_COLOR" );
break;
case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
idLib::Printf( "ONE_MINUS_DST_COLOR" );
break;
case GLS_SRCBLEND_SRC_ALPHA:
idLib::Printf( "SRC_ALPHA" );
break;
case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
idLib::Printf( "ONE_MINUS_SRC_ALPHA" );
break;
case GLS_SRCBLEND_DST_ALPHA:
idLib::Printf( "DST_ALPHA" );
break;
case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
idLib::Printf( "ONE_MINUS_DST_ALPHA" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( ", dst=" );
switch( stateBits & GLS_DSTBLEND_BITS )
{
case GLS_DSTBLEND_ZERO:
idLib::Printf( "ZERO" );
break;
case GLS_DSTBLEND_ONE:
idLib::Printf( "ONE" );
break;
case GLS_DSTBLEND_SRC_COLOR:
idLib::Printf( "SRC_COLOR" );
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
idLib::Printf( "ONE_MINUS_SRC_COLOR" );
break;
case GLS_DSTBLEND_SRC_ALPHA:
idLib::Printf( "SRC_ALPHA" );
break;
case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
idLib::Printf( "ONE_MINUS_SRC_ALPHA" );
break;
case GLS_DSTBLEND_DST_ALPHA:
idLib::Printf( "DST_ALPHA" );
break;
case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
idLib::Printf( "ONE_MINUS_DST_ALPHA" );
break;
default:
idLib::Printf( "NA" );
}
idLib::Printf( "\n" );
// depth func
idLib::Printf( "DepthFunc: " );
switch( stateBits & GLS_DEPTHFUNC_BITS )
{
case GLS_DEPTHFUNC_EQUAL:
idLib::Printf( "EQUAL" );
break;
case GLS_DEPTHFUNC_ALWAYS:
idLib::Printf( "ALWAYS" );
break;
case GLS_DEPTHFUNC_LESS:
idLib::Printf( "LEQUAL" );
break;
case GLS_DEPTHFUNC_GREATER:
idLib::Printf( "GEQUAL" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( "\n" );
// depth mask
idLib::Printf( "DepthWrite: %s\n", ( stateBits & GLS_DEPTHMASK ) ? "FALSE" : "TRUE" );
// depth bounds
idLib::Printf( "DepthBounds: %s\n", ( stateBits & GLS_DEPTH_TEST_MASK ) ? "TRUE" : "FALSE" );
// depth bias
idLib::Printf( "DepthBias: %s\n", ( stateBits & GLS_POLYGON_OFFSET ) ? "TRUE" : "FALSE" );
// stencil
auto printStencil = [&]( stencilFace_t face, uint64 bits, uint64 mask, uint64 ref )
{
idLib::Printf( "Stencil: %s, ", ( bits & ( GLS_STENCIL_FUNC_BITS | GLS_STENCIL_OP_BITS ) ) ? "ON" : "OFF" );
idLib::Printf( "Face=" );
switch( face )
{
case STENCIL_FACE_FRONT:
idLib::Printf( "FRONT" );
break;
case STENCIL_FACE_BACK:
idLib::Printf( "BACK" );
break;
default:
idLib::Printf( "BOTH" );
break;
}
idLib::Printf( ", Func=" );
switch( bits & GLS_STENCIL_FUNC_BITS )
{
case GLS_STENCIL_FUNC_NEVER:
idLib::Printf( "NEVER" );
break;
case GLS_STENCIL_FUNC_LESS:
idLib::Printf( "LESS" );
break;
case GLS_STENCIL_FUNC_EQUAL:
idLib::Printf( "EQUAL" );
break;
case GLS_STENCIL_FUNC_LEQUAL:
idLib::Printf( "LEQUAL" );
break;
case GLS_STENCIL_FUNC_GREATER:
idLib::Printf( "GREATER" );
break;
case GLS_STENCIL_FUNC_NOTEQUAL:
idLib::Printf( "NOTEQUAL" );
break;
case GLS_STENCIL_FUNC_GEQUAL:
idLib::Printf( "GEQUAL" );
break;
case GLS_STENCIL_FUNC_ALWAYS:
idLib::Printf( "ALWAYS" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( ", OpFail=" );
switch( bits & GLS_STENCIL_OP_FAIL_BITS )
{
case GLS_STENCIL_OP_FAIL_KEEP:
idLib::Printf( "KEEP" );
break;
case GLS_STENCIL_OP_FAIL_ZERO:
idLib::Printf( "ZERO" );
break;
case GLS_STENCIL_OP_FAIL_REPLACE:
idLib::Printf( "REPLACE" );
break;
case GLS_STENCIL_OP_FAIL_INCR:
idLib::Printf( "INCR" );
break;
case GLS_STENCIL_OP_FAIL_DECR:
idLib::Printf( "DECR" );
break;
case GLS_STENCIL_OP_FAIL_INVERT:
idLib::Printf( "INVERT" );
break;
case GLS_STENCIL_OP_FAIL_INCR_WRAP:
idLib::Printf( "INCR_WRAP" );
break;
case GLS_STENCIL_OP_FAIL_DECR_WRAP:
idLib::Printf( "DECR_WRAP" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( ", ZFail=" );
switch( bits & GLS_STENCIL_OP_ZFAIL_BITS )
{
case GLS_STENCIL_OP_ZFAIL_KEEP:
idLib::Printf( "KEEP" );
break;
case GLS_STENCIL_OP_ZFAIL_ZERO:
idLib::Printf( "ZERO" );
break;
case GLS_STENCIL_OP_ZFAIL_REPLACE:
idLib::Printf( "REPLACE" );
break;
case GLS_STENCIL_OP_ZFAIL_INCR:
idLib::Printf( "INCR" );
break;
case GLS_STENCIL_OP_ZFAIL_DECR:
idLib::Printf( "DECR" );
break;
case GLS_STENCIL_OP_ZFAIL_INVERT:
idLib::Printf( "INVERT" );
break;
case GLS_STENCIL_OP_ZFAIL_INCR_WRAP:
idLib::Printf( "INCR_WRAP" );
break;
case GLS_STENCIL_OP_ZFAIL_DECR_WRAP:
idLib::Printf( "DECR_WRAP" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( ", OpPass=" );
switch( bits & GLS_STENCIL_OP_PASS_BITS )
{
case GLS_STENCIL_OP_PASS_KEEP:
idLib::Printf( "KEEP" );
break;
case GLS_STENCIL_OP_PASS_ZERO:
idLib::Printf( "ZERO" );
break;
case GLS_STENCIL_OP_PASS_REPLACE:
idLib::Printf( "REPLACE" );
break;
case GLS_STENCIL_OP_PASS_INCR:
idLib::Printf( "INCR" );
break;
case GLS_STENCIL_OP_PASS_DECR:
idLib::Printf( "DECR" );
break;
case GLS_STENCIL_OP_PASS_INVERT:
idLib::Printf( "INVERT" );
break;
case GLS_STENCIL_OP_PASS_INCR_WRAP:
idLib::Printf( "INCR_WRAP" );
break;
case GLS_STENCIL_OP_PASS_DECR_WRAP:
idLib::Printf( "DECR_WRAP" );
break;
default:
idLib::Printf( "NA" );
break;
}
idLib::Printf( ", mask=%llu, ref=%llu\n", mask, ref );
};
uint32 mask = uint32( ( stateBits & GLS_STENCIL_FUNC_MASK_BITS ) >> GLS_STENCIL_FUNC_MASK_SHIFT );
uint32 ref = uint32( ( stateBits & GLS_STENCIL_FUNC_REF_BITS ) >> GLS_STENCIL_FUNC_REF_SHIFT );
if( stateBits & GLS_SEPARATE_STENCIL )
{
printStencil( STENCIL_FACE_FRONT, stencilBits[ 0 ], mask, ref );
printStencil( STENCIL_FACE_BACK, stencilBits[ 1 ], mask, ref );
}
else
{
printStencil( STENCIL_FACE_NUM, stateBits, mask, ref );
}
}

View file

@ -624,6 +624,11 @@ public:
int FindGLSLProgram( const char* name, int vIndex, int fIndex );
void ZeroUniforms();
#if defined(USE_VULKAN)
void PrintPipelines();
void ClearPipelines();
#endif
static const char* FindEmbeddedSourceShader( const char* name );
private:

View file

@ -45,7 +45,7 @@ idCVar r_syncEveryFrame( "r_syncEveryFrame", "1", CVAR_BOOL, "Don't let the GPU
// NEW VULKAN STUFF
idCVar r_vkEnableValidationLayers( "r_vkEnableValidationLayers", "1", CVAR_BOOL, "" );
idCVar r_vkEnableValidationLayers( "r_vkEnableValidationLayers", "0", CVAR_BOOL, "" );
vulkanContext_t vkcontext;
@ -1066,7 +1066,7 @@ static void CreateRenderPass()
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
// RB
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
//depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@ -1925,7 +1925,9 @@ idRenderBackend::GL_PolygonOffset
*/
void idRenderBackend::GL_PolygonOffset( float scale, float bias )
{
// TODO
vkCmdSetDepthBias( vkcontext.commandBuffer[ vkcontext.frameParity ], bias, 0.0f, scale );
RENDERLOG_PRINTF( "GL_PolygonOffset( scale=%f, bias=%f )\n", scale, bias );
}
/*
@ -1935,7 +1937,22 @@ idRenderBackend::GL_DepthBoundsTest
*/
void idRenderBackend::GL_DepthBoundsTest( const float zmin, const float zmax )
{
// TODO
if( zmin > zmax )
{
return;
}
if( zmin == 0.0f && zmax == 0.0f )
{
glStateBits = glStateBits & ~GLS_DEPTH_TEST_MASK;
}
else
{
glStateBits |= GLS_DEPTH_TEST_MASK;
vkCmdSetDepthBounds( vkcontext.commandBuffer[ vkcontext.frameParity ], zmin, zmax );
}
RENDERLOG_PRINTF( "GL_DepthBoundsTest( zmin=%f, zmax=%f )\n", zmin, zmax );
}
/*

View file

@ -727,6 +727,8 @@ void idRenderProgManager::LoadShader( shader_t& shader )
shaderModuleCreateInfo.pCode = ( uint32* )spirvBuffer;
ID_VK_CHECK( vkCreateShaderModule( vkcontext.device, &shaderModuleCreateInfo, NULL, &shader.module ) );
Mem_Free( spirvBuffer );
}
/*
@ -1450,5 +1452,42 @@ void idRenderProgManager::CommitUniforms( uint64 stateBits )
}
void idRenderProgManager::PrintPipelines()
{
for( int i = 0; i < renderProgManager.renderProgs.Num(); ++i )
{
renderProg_t& prog = renderProgManager.renderProgs[ i ];
for( int j = 0; j < prog.pipelines.Num(); ++j )
{
idLib::Printf( "%s: %llu\n", prog.name.c_str(), prog.pipelines[ j ].stateBits );
idLib::Printf( "------------------------------------------\n" );
RpPrintState( prog.pipelines[ j ].stateBits, vkcontext.stencilOperations );
idLib::Printf( "\n" );
}
}
}
void idRenderProgManager::ClearPipelines()
{
for( int i = 0; i < renderProgManager.renderProgs.Num(); ++i )
{
renderProg_t& prog = renderProgManager.renderProgs[ i ];
for( int j = 0; j < prog.pipelines.Num(); ++j )
{
vkDestroyPipeline( vkcontext.device, prog.pipelines[ j ].pipeline, NULL );
}
prog.pipelines.Clear();
}
}
CONSOLE_COMMAND( Vulkan_PrintPipelineStates, "Print the GLState bits associated with each pipeline.", 0 )
{
renderProgManager.PrintPipelines();
}
CONSOLE_COMMAND( Vulkan_ClearPipelines, "Clear all existing pipelines, forcing them to be recreated.", 0 )
{
renderProgManager.ClearPipelines();
}