/// @copydoc GameObject::TryFinishPrecacheResourceData() bool ShaderVariant::TryFinishPrecacheResourceData() { Renderer* pRenderer = Renderer::GetStaticInstance(); HELIUM_ASSERT( pRenderer ); // Get the type of shader being loaded. Name variantName = GetName(); tchar_t shaderTypeCharacter = ( *variantName )[ 0 ]; RShader::EType shaderType; if( shaderTypeCharacter == TXT( 'v' ) ) { shaderType = RShader::TYPE_VERTEX; } else { HELIUM_ASSERT( shaderTypeCharacter == TXT( 'p' ) ); shaderType = RShader::TYPE_PIXEL; } // Wait for all async load requests to complete. bool bHavePendingLoad = false; size_t loadRequestCount = m_renderResourceLoads.GetSize(); for( size_t loadRequestIndex = 0; loadRequestIndex < loadRequestCount; ++loadRequestIndex ) { LoadData& rLoadData = m_renderResourceLoads[ loadRequestIndex ]; if( IsInvalid( rLoadData.id ) ) { continue; } if( !TryFinishLoadSubData( rLoadData.id ) ) { bHavePendingLoad = true; continue; } SetInvalid( rLoadData.id ); // Serialize the constant buffer information. BinaryDeserializer deserializer; deserializer.Prepare( rLoadData.pData, rLoadData.size ); deserializer.BeginSerialize(); m_constantBufferSets[ loadRequestIndex ].Serialize( deserializer ); m_samplerInputSets[ loadRequestIndex ].Serialize( deserializer ); m_textureInputSets[ loadRequestIndex ].Serialize( deserializer ); size_t dataOffset = deserializer.GetCurrentOffset(); deserializer.EndSerialize(); // Apply padding for shader code alignment. dataOffset = Min( Align( dataOffset, sizeof( uint32_t ) ), rLoadData.size ); // Create the shader resource. size_t shaderSize = rLoadData.size - dataOffset; const void* pShaderData = static_cast< const uint8_t* >( rLoadData.pData ) + dataOffset; RShaderPtr spShaderBase; if( shaderType == RShader::TYPE_VERTEX ) { spShaderBase = pRenderer->CreateVertexShader( shaderSize, pShaderData ); } else { spShaderBase = pRenderer->CreatePixelShader( shaderSize, pShaderData ); } if( !spShaderBase ) { HELIUM_TRACE( TRACE_ERROR, ( TXT( "ShaderVariant::TryFinishPrecacheResourceData(): Failed to create shader for sub-data %" ) TPRIuSZ TXT( " of shader \"%s\".\n" ) ), loadRequestIndex, *GetPath().ToString() ); } m_renderResources[ loadRequestIndex ] = spShaderBase; } if( bHavePendingLoad ) { return false; } // All load requests have completed, so free all memory allocated for resource staging. m_renderResourceLoads.Clear(); DefaultAllocator().Free( m_pRenderResourceLoadBuffer ); m_pRenderResourceLoadBuffer = NULL; return true; }