First changes to fix GPU Skinning with Vulkan

This commit is contained in:
Robert Beckebans 2018-11-04 19:57:53 +01:00
parent d634243631
commit 9241db812e
5 changed files with 71 additions and 26 deletions

View file

@ -5216,7 +5216,7 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
break;
case RC_SET_BUFFER:
//SetBuffer( cmds );
SetBuffer( cmds );
c_setBuffers++;
break;

View file

@ -635,7 +635,7 @@ private:
void LoadShader( int index, rpStage_t stage );
idStr StripDeadCode( const idStr& in, const char* name, const idStrList& compileMacros, bool builtin );
idStr ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, idStr& layout, bool vkGLSL );
idStr ConvertCG2GLSL( const idStr& in, const char* name, rpStage_t stage, idStr& layout, bool vkGLSL, bool hasGPUSkinning );
enum
{

View file

@ -1013,7 +1013,7 @@ void ParseInOutStruct( idLexer& src, int attribType, int attribIgnoreType, idLis
ConvertCG2GLSL
========================
*/
idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bool isVertexProgram, idStr& layout, bool vkGLSL )
idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, rpStage_t stage, idStr& layout, bool vkGLSL, bool hasGPUSkinning )
{
idStr program;
program.ReAllocate( in.Length() * 2, false );
@ -1028,7 +1028,7 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
bool inMain = false;
bool justEnteredMain = false;
const char* uniformArrayName = isVertexProgram ? VERTEX_UNIFORM_ARRAY_NAME : FRAGMENT_UNIFORM_ARRAY_NAME;
const char* uniformArrayName = ( stage == SHADER_STAGE_VERTEX ) ? VERTEX_UNIFORM_ARRAY_NAME : FRAGMENT_UNIFORM_ARRAY_NAME;
char newline[128] = { "\n" };
idToken token;
@ -1113,6 +1113,20 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
src.ReadToken( &token );
}
// RB: HACK to add matrices uniform block layer
if( token == "uniform" && src.PeekTokenString( "matrices_ubo" ) )
{
hasGPUSkinning = true;
//src.ReadToken( &token );
//src.SkipRestOfLine();
//program += "\nlayout( binding = 1 ) ";
src.SkipRestOfLine();
continue;
}
}
// convert the in/out structs
@ -1276,7 +1290,7 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
newline[len - 0] = '\0';
// RB: add this to every vertex shader
if( inMain && !justEnteredMain && isVertexProgram && vkGLSL )
if( inMain && !justEnteredMain && ( stage == SHADER_STAGE_VERTEX ) && vkGLSL )
{
program += "\n\tvec4 position4 = vec4( in_Position, 1.0 );\n";
justEnteredMain = true;
@ -1476,7 +1490,7 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
idStr filenameHint = "// filename " + idStr( name ) + "\n";
// RB: changed to allow multiple versions of GLSL
if( isVertexProgram )
if( ( stage == SHADER_STAGE_VERTEX ) )
{
switch( glConfig.driverType )
{
@ -1527,13 +1541,14 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
if( vkGLSL )
{
out += "\n";
if( isVertexProgram )
if( ( stage == SHADER_STAGE_VERTEX ) )
{
out += "layout( binding = 0 ) uniform UBOV {\n";
}
else
{
out += "layout( binding = 1 ) uniform UBOF {\n";
//out += "layout( binding = 1 ) uniform UBOF {\n";
out += va( "layout( binding = %i ) uniform UBOF {\n", hasGPUSkinning ? 2 : 1 );
}
for( int i = 0; i < uniformList.Num(); i++ )
@ -1550,6 +1565,13 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
out += ";\n";
}
out += "};\n";
if( hasGPUSkinning && ( stage == SHADER_STAGE_VERTEX ) )
{
out += "\nlayout( binding = 1 ) uniform UBO_MAT {\n";
out += "\t vec4 matrices[ 408 ];\n";
out += "};\n";
}
}
else
{
@ -1569,7 +1591,17 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
// RB: add samplers with layout bindings
if( vkGLSL )
{
int bindingOffset = uniformList.Num() > 0 ? 2 : 1;
int bindingOffset = 1;
if( hasGPUSkinning )
{
bindingOffset++;
}
if( uniformList.Num() > 0 )
{
bindingOffset++;
}
for( int i = 0; i < samplerList.Num(); i++ )
{
@ -1589,13 +1621,20 @@ idStr idRenderProgManager::ConvertCG2GLSL( const idStr& in, const char* name, bo
layout += "]\n";
layout += "bindings [\n";
if( uniformList.Num() > 0 )
{
layout += "\tubo\n";
}
if( hasGPUSkinning && ( stage == SHADER_STAGE_VERTEX ) )
{
layout += "\tubo\n";
}
for( int i = 0; i < samplerList.Num(); i++ )
{
layout += "\t sampler\n";
layout += "\tsampler\n";
}
layout += "]\n";

View file

@ -1502,16 +1502,7 @@ void idRenderBackend::DrawElementsWithCounters( const drawSurf_t* surf )
}
}
if( surf->jointCache )
{
idUniformBuffer jointBuffer;
if( !vertexCache.GetJointBuffer( surf->jointCache, &jointBuffer ) )
{
idLib::Warning( "RB_DrawElementsWithCounters, jointBuffer == NULL" );
return;
}
}
vkcontext.jointCacheHandle = surf->jointCache;
renderProgManager.CommitUniforms( glStateBits );
@ -2252,13 +2243,13 @@ void idRenderBackend::SetBuffer( const void* data )
RENDERLOG_PRINTF( "---------- RB_SetBuffer ---------- to buffer # %d\n", cmd->buffer );
GL_Scissor( 0, 0, tr.GetWidth(), tr.GetHeight() );
// clear screen for debugging
// automatically enable this with several other debug tools
// that might leave unrendered portions of the screen
if( r_clear.GetFloat() || idStr::Length( r_clear.GetString() ) != 1 || r_singleArea.GetBool() || r_showOverDraw.GetBool() )
{
GL_Scissor( 0, 0, tr.GetWidth(), tr.GetHeight() );
float c[3];
if( sscanf( r_clear.GetString(), "%f %f %f", &c[0], &c[1], &c[2] ) == 3 )
{

View file

@ -623,9 +623,21 @@ void idRenderProgManager::LoadShader( shader_t& shader )
}
}
// FIXME: we should really scan the program source code for using rpEnableSkinning but at this
// point we directly load a binary and the program source code is not available on the consoles
bool hasGPUSkinning = false;
if( idStr::Icmp( shader.name.c_str(), "heatHaze.vfp" ) == 0 ||
idStr::Icmp( shader.name.c_str(), "heatHazeWithMask.vfp" ) == 0 ||
idStr::Icmp( shader.name.c_str(), "heatHazeWithMaskAndVertex.vfp" ) == 0 ||
( BIT( USE_GPU_SKINNING ) & shader.shaderFeatures ) )
{
hasGPUSkinning = true;
}
idStr hlslCode( hlslFileBuffer );
idStr programHLSL = StripDeadCode( hlslCode, inFile, compileMacros, shader.builtin );
programGLSL = ConvertCG2GLSL( programHLSL, inFile, shader.stage == SHADER_STAGE_VERTEX, programLayout, true );
programGLSL = ConvertCG2GLSL( programHLSL, inFile, shader.stage, programLayout, true, hasGPUSkinning );
fileSystem->WriteFile( outFileHLSL, programHLSL.c_str(), programHLSL.Length(), "fs_savepath" );
fileSystem->WriteFile( outFileGLSL, programGLSL.c_str(), programGLSL.Length(), "fs_savepath" );
@ -757,11 +769,11 @@ void idRenderProgManager::LoadGLSLProgram( const int programIndex, const int ver
// TODO
#if 0
#if 1
// RB: removed idStr::Icmp( name, "heatHaze.vfp" ) == 0 hack
for( int i = 0; i < shaders[vertexShaderIndex].uniforms.Num(); i++ )
for( int i = 0; i < shaders[vertexShaderIndex].parmIndices.Num(); i++ )
{
if( shaders[vertexShaderIndex].uniforms[i] == RENDERPARM_ENABLE_SKINNING )
if( shaders[vertexShaderIndex].parmIndices[i] == RENDERPARM_ENABLE_SKINNING )
{
prog.usesJoints = true;
prog.optionalSkinning = true;
@ -834,6 +846,8 @@ idRenderProgManager::AllocParmBlockBuffer
*/
void idRenderProgManager::AllocParmBlockBuffer( const idList<int>& parmIndices, idUniformBuffer& ubo )
{
// TODO support shadow matrices + 23 float4
const int numParms = parmIndices.Num();
const int bytes = ALIGN( numParms * sizeof( idVec4 ), vkcontext.gpu->props.limits.minUniformBufferOffsetAlignment );
@ -1488,6 +1502,7 @@ void idRenderProgManager::CommitUniforms( uint64 stateBits )
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
write.pImageInfo = &imageInfo;
//imageIndex++;
break;
}
}