Merge branch '837-loading-screen-progressbar'

This commit is contained in:
Robert Beckebans 2024-06-29 13:11:06 +02:00
commit ca72a728fe
16 changed files with 677 additions and 547 deletions

View file

@ -330,6 +330,34 @@ bool idMenuHandler_Shell::HandleGuiEvent( const sysEvent_t* sev )
if( showingIntro )
{
// RB: allow to skip intro videos
if( sev->evType == SE_KEY && sev->evValue2 == 1 && ( sev->evValue == K_ESCAPE || sev->evValue == K_JOY9 ) )
{
if( introGui != NULL && introGui->IsActive() )
{
gui->StopSound();
showingIntro = false;
introGui->Activate( false );
PlaySound( GUI_SOUND_MUSIC );
const char* introName = introGui->GetName();
if( idStr::Cmp( introName, "swf/roeintro.swf" ) == 0 )
{
StartGame( 1 );
}
else if( idStr::Cmp( introName, "swf/leintro.swf" ) == 0 )
{
StartGame( 2 );
}
else
{
StartGame( 0 );
}
}
}
// RB end
return true;
}

View file

@ -1794,7 +1794,7 @@ bool idCommonLocal::ProcessEvent( const sysEvent_t* event )
{
if( event->evType == SE_KEY && event->evValue2 == 1 && ( event->evValue == K_ESCAPE || event->evValue == K_JOY9 ) )
{
if( game->CheckInCinematic() == true )
if( game->CheckInCinematic() )
{
game->SkipCinematicScene();
}

View file

@ -229,9 +229,12 @@ public:
// DG end
virtual void UpdateLevelLoadPacifier() = 0;
//virtual void UpdateLevelLoadPacifier( int mProgress ) = 0;
//virtual void UpdateLevelLoadPacifier( bool updateSecondary ) = 0;
//virtual void UpdateLevelLoadPacifier( bool updateSecondary, int Progress ) = 0;
// RB begin
virtual void LoadPacifierInfo( VERIFY_FORMAT_STRING const char* fmt, ... ) = 0;
virtual void LoadPacifierProgressTotal( int total ) = 0;
virtual void LoadPacifierProgressIncrement( int step ) = 0;
virtual bool LoadPacifierRunning() = 0;
// RB end
// Checks for and removes command line "+set var arg" constructs.
// If match is NULL, all set commands will be executed, otherwise

View file

@ -772,7 +772,9 @@ void idCommonLocal::UpdateLevelLoadPacifier()
}
txtVal->SetStrokeInfo( true, 1.75f, 0.75f );
}
UpdateScreen( false );
if( autoswapsRunning )
{
renderSystem->BeginAutomaticBackgroundSwaps( icon );
@ -780,6 +782,83 @@ void idCommonLocal::UpdateLevelLoadPacifier()
}
}
// RB begin
void idCommonLocal::LoadPacifierInfo( VERIFY_FORMAT_STRING const char* fmt, ... )
{
char msg[256];
va_list argptr;
va_start( argptr, fmt );
idStr::vsnPrintf( msg, 256 - 1, fmt, argptr );
msg[ sizeof( msg ) - 1 ] = '\0';
va_end( argptr );
loadPacifierStatus = msg;
//if( com_refreshOnPrint )
//{
// UpdateScreen( false );
//}
}
void idCommonLocal::LoadPacifierProgressTotal( int total )
{
loadPacifierCount = 0;
loadPacifierExpectedCount = total;
loadPacifierTics = 0;
loadPacifierNextTicCount = 0;
}
void idCommonLocal::LoadPacifierProgressIncrement( int step )
{
loadPacifierCount += step;
// don't refresh the UI with every step if there are e.g. 1300 steps
if( ( ( loadPacifierCount + 1 ) >= loadPacifierNextTicCount ) && loadPacifierExpectedCount > 0 )
{
size_t ticsNeeded = ( size_t )( ( ( double )( loadPacifierCount + 1 ) / loadPacifierExpectedCount ) * 50.0 );
//do
//{
//common->Printf( "*" );
//}
//while( ++loadPacifierTics < ticsNeeded );
loadPacifierTics = ticsNeeded;
loadPacifierNextTicCount = ( size_t )( ( loadPacifierTics / 50.0 ) * loadPacifierExpectedCount );
if( loadPacifierCount == ( loadPacifierExpectedCount - 1 ) )
{
// reset
//if( tics < 51 )
//{
// common->Printf( "*" );
//}
//common->Printf( "\n" );
//stateUI.progress = 1;
//loadPacifierCount = 0;
//loadPacifierExpectedCount = 0;
//loadPacifierTics = 0;
//loadPacifierNextTicCount = 0;
}
UpdateLevelLoadPacifier();
}
if( loadPacifierCount >= loadPacifierExpectedCount )
{
loadPacifierExpectedCount = 0;
}
}
bool idCommonLocal::LoadPacifierRunning()
{
return loadPacifierExpectedCount > 0;
}
// RB end
// foresthale 2014-05-30: loading progress pacifier for binarize operations only
void idCommonLocal::LoadPacifierBinarizeFilename( const char* filename, const char* reason )
{
@ -817,16 +896,16 @@ void idCommonLocal::LoadPacifierBinarizeProgress( float progress )
// binarized for one filename, we don't give bogus estimates...
loadPacifierBinarizeStartTime = Sys_Milliseconds();
}
loadPacifierBinarizeProgress = progress;
if( ( time - lastUpdateTime ) >= 16 )
// RB: update every 2 milliseconds have passed
if( ( time - lastUpdateTime ) >= 2 )
{
lastUpdateTime = time;
loadPacifierBinarizeActive = true;
UpdateLevelLoadPacifier();
// TODO merge
//UpdateLevelLoadPacifier( true, progress );
}
}
@ -855,7 +934,11 @@ void idCommonLocal::LoadPacifierBinarizeProgressTotal( int total )
void idCommonLocal::LoadPacifierBinarizeProgressIncrement( int step )
{
loadPacifierBinarizeProgressCurrent += step;
LoadPacifierBinarizeProgress( ( float )loadPacifierBinarizeProgressCurrent / loadPacifierBinarizeProgressTotal );
if( loadPacifierBinarizeProgressTotal > 0 )
{
LoadPacifierBinarizeProgress( ( float )loadPacifierBinarizeProgressCurrent / loadPacifierBinarizeProgressTotal );
}
}
/*

View file

@ -157,9 +157,6 @@ public:
virtual void UpdateScreen( bool captureToImage, bool releaseMouse = true );
// DG end
virtual void UpdateLevelLoadPacifier(); // Indefinate
// virtual void UpdateLevelLoadPacifier( int mProgress );
// virtual void UpdateLevelLoadPacifier( bool Secondary );
// virtual void UpdateLevelLoadPacifier( bool updateSecondary, int mProgress );
virtual void StartupVariable( const char* match );
virtual void InitTool( const toolFlag_t tool, const idDict* dict, idEntity* entity );
virtual void WriteConfigToFile( const char* filename );
@ -440,6 +437,13 @@ public:
}
// SRS end
// RB begin
virtual void LoadPacifierInfo( VERIFY_FORMAT_STRING const char* fmt, ... );
virtual void LoadPacifierProgressTotal( int total );
virtual void LoadPacifierProgressIncrement( int step );
virtual bool LoadPacifierRunning();
// RB end
// foresthale 2014-05-30: a special binarize pacifier has to be shown in
// some cases, which includes filename and ETA information, note that
// the progress function takes 0-1 float, not 0-100, and can be called
@ -655,17 +659,25 @@ private:
int lastPacifierGuiTime;
bool lastPacifierDialogState;
// RB begin
idStrStatic<256> loadPacifierStatus = "-";
int loadPacifierCount = 0;
int loadPacifierExpectedCount = 0;
size_t loadPacifierTics = 0;
size_t loadPacifierNextTicCount = 0;
// RB end
// foresthale 2014-05-30: a special binarize pacifier has to be shown in some cases, which includes filename and ETA information
bool loadPacifierBinarizeActive;
int loadPacifierBinarizeStartTime;
float loadPacifierBinarizeProgress;
float loadPacifierBinarizeTimeLeft;
bool loadPacifierBinarizeActive = false;
int loadPacifierBinarizeStartTime = 0;
float loadPacifierBinarizeProgress = 0.0f;
float loadPacifierBinarizeTimeLeft = 0.0f;
idStr loadPacifierBinarizeFilename;
idStr loadPacifierBinarizeInfo;
int loadPacifierBinarizeMiplevel;
int loadPacifierBinarizeMiplevelTotal;
int loadPacifierBinarizeProgressTotal;
int loadPacifierBinarizeProgressCurrent;
int loadPacifierBinarizeMiplevel = 0;
int loadPacifierBinarizeMiplevelTotal = 0;
int loadPacifierBinarizeProgressTotal = 0;
int loadPacifierBinarizeProgressCurrent = 0;
bool showShellRequested;
@ -738,6 +750,7 @@ private:
// called by Draw when the scene to scene wipe is still running
void DrawWipeModel();
void DrawLoadPacifierProgressbar(); // RB
void StartWipe( const char* materialName, bool hold = false );
void CompleteWipe();
void ClearWipe();

View file

@ -234,6 +234,27 @@ void idCommonLocal::DrawWipeModel()
renderSystem->DrawStretchPic( 0, 0, renderSystem->GetVirtualWidth(), renderSystem->GetVirtualHeight(), 0, 0, 1, 1, wipeMaterial );
}
// RB begin
void idCommonLocal::DrawLoadPacifierProgressbar()
{
if( loadPacifierExpectedCount <= 0 )
{
return;
}
float loadPacifierProgress = float( loadPacifierCount ) / loadPacifierExpectedCount;
// draw our basic overlay
renderSystem->SetColor( idVec4( 0.55f, 0.0f, 0.0f, 1.0f ) );
renderSystem->DrawStretchPic( 0, renderSystem->GetVirtualHeight() - 64, renderSystem->GetVirtualWidth(), 16, 0, 0, 1, 1, whiteMaterial );
//renderSystem->SetColor( idVec4( 0.0f, 0.5f, 0.8f, 1.0f ) );
renderSystem->SetColor( colorGold );
renderSystem->DrawStretchPic( 0, renderSystem->GetVirtualHeight() - 64, loadPacifierProgress * renderSystem->GetVirtualWidth(), 16, 0, 0, 1, 1, whiteMaterial );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 64, loadPacifierStatus, idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
}
// RB end
/*
===============
idCommonLocal::Draw
@ -247,7 +268,7 @@ void idCommonLocal::Draw()
Sys_Sleep( com_sleepDraw.GetInteger() );
}
if( loadPacifierBinarizeActive )
if( loadPacifierBinarizeActive || LoadPacifierRunning() )
{
// foresthale 2014-05-30: when binarizing an asset we show a special
// overlay indicating progress
@ -261,40 +282,47 @@ void idCommonLocal::Draw()
loadGUI->Render( renderSystem, Sys_Milliseconds() );
}
// update our progress estimates
int time = Sys_Milliseconds();
if( loadPacifierBinarizeProgress > 0.0f )
{
loadPacifierBinarizeTimeLeft = ( 1.0 - loadPacifierBinarizeProgress ) * ( time - loadPacifierBinarizeStartTime ) * 0.001f / loadPacifierBinarizeProgress;
}
else
{
loadPacifierBinarizeTimeLeft = -1.0f;
}
// draw general progress bar
DrawLoadPacifierProgressbar();
// prepare our strings
const char* text;
if( loadPacifierBinarizeTimeLeft >= 99.5f )
if( loadPacifierBinarizeActive )
{
text = va( "Binarizing %3.0f%% ETA %2.0f minutes", loadPacifierBinarizeProgress * 100.0f, loadPacifierBinarizeTimeLeft / 60.0f );
}
else if( loadPacifierBinarizeTimeLeft )
{
text = va( "Binarizing %3.0f%% ETA %2.0f seconds", loadPacifierBinarizeProgress * 100.0f, loadPacifierBinarizeTimeLeft );
}
else
{
text = va( "Binarizing %3.0f%%", loadPacifierBinarizeProgress * 100.0f );
}
// update our progress estimates
int time = Sys_Milliseconds();
if( loadPacifierBinarizeProgress > 0.0f )
{
loadPacifierBinarizeTimeLeft = ( 1.0 - loadPacifierBinarizeProgress ) * ( time - loadPacifierBinarizeStartTime ) * 0.001f / loadPacifierBinarizeProgress;
}
else
{
loadPacifierBinarizeTimeLeft = -1.0f;
}
// draw our basic overlay
renderSystem->SetColor( idVec4( 0.0f, 0.0f, 0.5f, 1.0f ) );
renderSystem->DrawStretchPic( 0, renderSystem->GetVirtualHeight() - 48, renderSystem->GetVirtualWidth(), 48, 0, 0, 1, 1, whiteMaterial );
renderSystem->SetColor( idVec4( 0.0f, 0.5f, 0.8f, 1.0f ) );
renderSystem->DrawStretchPic( 0, renderSystem->GetVirtualHeight() - 48, loadPacifierBinarizeProgress * renderSystem->GetVirtualWidth(), 32, 0, 0, 1, 1, whiteMaterial );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 48, loadPacifierBinarizeFilename.c_str(), idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 32, va( "%s %d/%d lvls", loadPacifierBinarizeInfo.c_str(), loadPacifierBinarizeMiplevel, loadPacifierBinarizeMiplevelTotal ), idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 16, text, idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
// prepare our strings
const char* text;
if( loadPacifierBinarizeTimeLeft >= 99.5f )
{
text = va( "Binarizing %3.0f%% ETA %2.0f minutes", loadPacifierBinarizeProgress * 100.0f, loadPacifierBinarizeTimeLeft / 60.0f );
}
else if( loadPacifierBinarizeTimeLeft )
{
text = va( "Binarizing %3.0f%% ETA %2.0f seconds", loadPacifierBinarizeProgress * 100.0f, loadPacifierBinarizeTimeLeft );
}
else
{
text = va( "Binarizing %3.0f%%", loadPacifierBinarizeProgress * 100.0f );
}
// draw our basic overlay
renderSystem->SetColor( idVec4( 0.0f, 0.0f, 0.0f, 0.75f ) );
renderSystem->DrawStretchPic( 0, renderSystem->GetVirtualHeight() - 48, renderSystem->GetVirtualWidth(), 48, 0, 0, 1, 1, whiteMaterial );
//renderSystem->SetColor( idVec4( 0.0f, 0.5f, 0.8f, 1.0f ) );
renderSystem->SetColor( colorBrown );
renderSystem->DrawStretchPic( 0, renderSystem->GetVirtualHeight() - 48, loadPacifierBinarizeProgress * renderSystem->GetVirtualWidth(), 16, 0, 0, 1, 1, whiteMaterial );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 48, loadPacifierBinarizeFilename.c_str(), idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 32, va( "%s %d/%d lvls", loadPacifierBinarizeInfo.c_str(), loadPacifierBinarizeMiplevel, loadPacifierBinarizeMiplevelTotal ), idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
renderSystem->DrawSmallStringExt( 0, renderSystem->GetVirtualHeight() - 16, text, idVec4( 1.0f, 1.0f, 1.0f, 1.0f ), true );
}
}
else if( loadGUI != NULL )
{

View file

@ -413,6 +413,8 @@ void idBinaryImage::Load2DAtlasMipchainFromMemory( int width, int height, const
#endif
}
}
common->LoadPacifierBinarizeProgressIncrement( rect.x * rect.y );
// RB end
common->LoadPacifierBinarizeMiplevel( level + 1, numLevels );

View file

@ -251,40 +251,6 @@ typedef enum
CF_SINGLE, // SP: A single texture cubemap. All six sides in one image.
} cubeFiles_t;
class idDeferredImage
{
public:
idDeferredImage( const char* imageName );
~idDeferredImage();
idStr name;
byte* pic;
int width;
int height;
textureFilter_t textureFilter;
textureRepeat_t textureRepeat;
textureUsage_t textureUsage;
};
ID_INLINE idDeferredImage::idDeferredImage( const char* imageName )
: name( imageName )
, pic( nullptr )
, width( 0 )
, height( 0 )
, textureFilter( TF_DEFAULT )
, textureRepeat( TR_CLAMP )
, textureUsage( TD_DEFAULT )
{
}
ID_INLINE idDeferredImage::~idDeferredImage()
{
if( pic )
{
delete pic;
}
}
typedef void ( *ImageGeneratorFunction )( idImage* image, nvrhi::ICommandList* commandList );
#include "BinaryImage.h"
@ -361,7 +327,7 @@ public:
levelLoadReferenced = true;
}
void FinalizeImage( bool fromBackEnd, nvrhi::ICommandList* commandList );
void ActuallyLoadImage( bool fromBackEnd, nvrhi::ICommandList* commandList );
// Adds the image to the list of images to load on the main thread to the gpu.
void DeferredLoadImage();
@ -666,8 +632,6 @@ public:
idImage* AllocImage( const char* name );
idImage* AllocStandaloneImage( const char* name );
idDeferredImage* AllocDeferredImage( const char* name );
bool ExcludePreloadImage( const char* name );
idList<idImage*, TAG_IDLIB_LIST_IMAGE> images;
@ -676,10 +640,6 @@ public:
// Transient list of images to load on the main thread to the gpu. Freed after images are loaded.
idList<idImage*, TAG_IDLIB_LIST_IMAGE> imagesToLoad;
// Permanent images to load from memory instead of a file system.
idList<idDeferredImage*, TAG_IDLIB_LIST_IMAGE> deferredImages;
idHashIndex deferredImageHash;
bool insideLevelLoad; // don't actually load images now
bool preloadingMapImages; // unless this is set

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013-2024 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").
@ -149,6 +150,7 @@ void R_ListImages_f( const idCmdArgs& args )
bool duplicated = false;
bool overSized = false;
bool sortByName = false;
bool deferred = false;
if( args.Argc() == 1 )
{
@ -181,6 +183,10 @@ void R_ListImages_f( const idCmdArgs& args )
sorted = true;
overSized = true;
}
else if( idStr::Icmp( args.Argv( 1 ), "deferred" ) == 0 )
{
deferred = true;
}
else
{
failed = true;
@ -193,23 +199,32 @@ void R_ListImages_f( const idCmdArgs& args )
if( failed )
{
idLib::Printf( "usage: listImages [ sorted | namesort | unloaded | duplicated | showOverSized ]\n" );
common->Printf( "usage: listImages [ sorted | namesort | unloaded | duplicated | showOverSized ]\n" );
return;
}
const char* header = " -w-- -h-- filt -fmt-- wrap size --name-------\n";
idLib::Printf( "\n%s", header );
common->Printf( "\n%s", header );
totalSize = 0;
idList< idImage* >& images = globalImages->images;
const int numImages = images.Num();
const idList< idImage*, TAG_IDLIB_LIST_IMAGE >* images;
if( deferred )
{
images = &globalImages->imagesToLoad;
}
else
{
images = &globalImages->images;
}
const int numImages = images->Num();
sortedImage_t* sortedArray = ( sortedImage_t* )alloca( sizeof( sortedImage_t ) * numImages );
for( i = 0 ; i < numImages; i++ )
{
image = images[ i ];
image = ( *images )[ i ];
if( uncompressedOnly )
{
@ -229,7 +244,7 @@ void R_ListImages_f( const idCmdArgs& args )
int j;
for( j = i + 1 ; j < numImages ; j++ )
{
if( idStr::Icmp( image->GetName(), images[ j ]->GetName() ) == 0 )
if( idStr::Icmp( image->GetName(), ( *images )[ j ]->GetName() ) == 0 )
{
break;
}
@ -248,7 +263,7 @@ void R_ListImages_f( const idCmdArgs& args )
}
else
{
idLib::Printf( "%4i:", i );
common->Printf( "%4i:", i );
image->Print();
}
totalSize += image->StorageSize();
@ -268,13 +283,13 @@ void R_ListImages_f( const idCmdArgs& args )
partialSize = 0;
for( i = 0 ; i < count ; i++ )
{
idLib::Printf( "%4i:", sortedArray[i].index );
common->Printf( "%4i:", sortedArray[i].index );
sortedArray[i].image->Print();
partialSize += sortedArray[i].image->StorageSize();
if( ( ( i + 1 ) % 10 ) == 0 )
{
idLib::Printf( "-------- %5.1f of %5.1f megs --------\n",
partialSize / ( 1024 * 1024.0 ), totalSize / ( 1024 * 1024.0 ) );
common->Printf( "-------- %5.1f of %5.1f megs --------\n",
partialSize / ( 1024 * 1024.0 ), totalSize / ( 1024 * 1024.0 ) );
}
}
}
@ -296,7 +311,7 @@ idImage* idImageManager::AllocImage( const char* name )
{
if( strlen( name ) >= MAX_IMAGE_NAME )
{
idLib::Error( "idImageManager::AllocImage: \"%s\" is too long\n", name );
common->Error( "idImageManager::AllocImage: \"%s\" is too long\n", name );
}
int hash = idStr( name ).FileNameHash();
@ -328,24 +343,6 @@ idImage* idImageManager::AllocStandaloneImage( const char* name )
return image;
}
/*
==============
AllocDeferredImage
Allocates an idDeferredImage to load images from memory, adds it to the hash chain
==============
*/
idDeferredImage* idImageManager::AllocDeferredImage( const char* name )
{
idDeferredImage* image = new( TAG_IMAGE ) idDeferredImage( name );
int hash = idStr( name ).FileNameHash();
deferredImageHash.Add( hash, deferredImages.Append( image ) );
return image;
}
/*
==================
ImageFromFunction
@ -357,7 +354,6 @@ system to be completely regenerated if needed.
*/
idImage* idImageManager::ImageFromFunction( const char* _name, ImageGeneratorFunction generatorFunction )
{
// strip any .tga file extensions from anywhere in the _name
idStr name = _name;
name.Replace( ".tga", "" );
@ -437,7 +433,7 @@ idImage* idImageManager::ImageFromFile( const char* _name, textureFilter_t filte
}
if( image->cubeFiles != cubeMap )
{
idLib::Error( "Image '%s' has been referenced with conflicting cube map states", _name );
common->Error( "Image '%s' has been referenced with conflicting cube map states", _name );
}
if( image->filter != filter || image->repeat != repeat )
@ -458,8 +454,7 @@ idImage* idImageManager::ImageFromFile( const char* _name, textureFilter_t filte
if( ( !insideLevelLoad || preloadingMapImages ) && !image->IsLoaded() )
{
image->referencedOutsideLevelLoad = ( !insideLevelLoad && !preloadingMapImages );
image->FinalizeImage( false, nullptr );
image->ActuallyLoadImage( false, nullptr ); // load is from front end
declManager->MediaPrint( "%ix%i %s (reload for mixed referneces)\n", image->GetUploadWidth(), image->GetUploadHeight(), image->GetName() );
}
@ -483,7 +478,7 @@ idImage* idImageManager::ImageFromFile( const char* _name, textureFilter_t filte
if( !insideLevelLoad || preloadingMapImages )
{
image->referencedOutsideLevelLoad = ( !insideLevelLoad && !preloadingMapImages );
image->FinalizeImage( false, nullptr );
image->ActuallyLoadImage( false, nullptr ); // load is from front end
declManager->MediaPrint( "%ix%i %s\n", image->GetUploadWidth(), image->GetUploadHeight(), image->GetName() );
}
@ -671,9 +666,9 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
{
if( args.Argc() != 2 )
{
idLib::Printf( "usage: combineCubeImages <baseName>\n" );
idLib::Printf( " combines basename[1-6][0001-9999].tga to basenameCM[0001-9999].tga\n" );
idLib::Printf( " 1: forward 2:right 3:back 4:left 5:up 6:down\n" );
common->Printf( "usage: combineCubeImages <baseName>\n" );
common->Printf( " combines basename[1-6][0001-9999].tga to basenameCM[0001-9999].tga\n" );
common->Printf( " 1: forward 2:right 3:back 4:left 5:up 6:down\n" );
return;
}
@ -691,12 +686,12 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
{
idStr::snPrintf( filename, sizeof( filename ), "%s%i%04i.tga", baseName.c_str(), orderRemap[side], frameNum );
idLib::Printf( "reading %s\n", filename );
common->Printf( "reading %s\n", filename );
R_LoadImage( filename, &pics[side], &width, &height, NULL, true, NULL );
if( !pics[side] )
{
idLib::Printf( "not found.\n" );
common->Printf( "not found.\n" );
break;
}
@ -744,7 +739,7 @@ void R_CombineCubeImages_f( const idCmdArgs& args )
}
idStr::snPrintf( filename, sizeof( filename ), "%sCM%04i.tga", baseName.c_str(), frameNum );
idLib::Printf( "writing %s\n", filename );
common->Printf( "writing %s\n", filename );
R_WriteTGA( filename, combined, width, height * 6 );
}
common->SetRefreshOnPrint( false );
@ -781,8 +776,6 @@ void idImageManager::Shutdown()
{
images.DeleteContents( true );
imageHash.Clear();
deferredImages.DeleteContents( true );
deferredImageHash.Clear();
commandList.Reset();
}
@ -855,12 +848,27 @@ void idImageManager::Preload( const idPreloadManifest& manifest, const bool& map
if( preLoad_Images.GetBool() && manifest.NumResources() > 0 )
{
// preload this levels images
idLib::Printf( "Preloading images...\n" );
common->Printf( "Preloading images...\n" );
preloadingMapImages = mapPreload;
int start = Sys_Milliseconds();
int numLoaded = 0;
//fileSystem->StartPreload( preloadImageFiles );
// count
int numPreload = 0;
for( int i = 0; i < manifest.NumResources(); i++ )
{
const preloadEntry_s& p = manifest.GetPreloadByIndex( i );
if( p.resType == PRELOAD_IMAGE && !ExcludePreloadImage( p.resourceName ) )
{
numPreload++;
}
}
common->LoadPacifierInfo( "Preloading images" );
common->LoadPacifierProgressTotal( numPreload );
for( int i = 0; i < manifest.NumResources(); i++ )
{
const preloadEntry_s& p = manifest.GetPreloadByIndex( i );
@ -868,12 +876,14 @@ void idImageManager::Preload( const idPreloadManifest& manifest, const bool& map
{
globalImages->ImageFromFile( p.resourceName, ( textureFilter_t )p.imgData.filter, ( textureRepeat_t )p.imgData.repeat, ( textureUsage_t )p.imgData.usage, ( cubeFiles_t )p.imgData.cubeMap );
numLoaded++;
common->LoadPacifierProgressIncrement( 1 );
}
}
//fileSystem->StopPreload();
int end = Sys_Milliseconds();
idLib::Printf( "%05d images preloaded ( or were already loaded ) in %5.1f seconds\n", numLoaded, ( end - start ) * 0.001 );
idLib::Printf( "----------------------------------------\n" );
common->Printf( "%05d images preloaded ( or were already loaded ) in %5.1f seconds\n", numLoaded, ( end - start ) * 0.001 );
common->Printf( "----------------------------------------\n" );
preloadingMapImages = false;
}
}
@ -899,15 +909,26 @@ int idImageManager::LoadLevelImages( bool pacifier )
commandList = deviceManager->GetDevice()->createCommandList( params );
}
common->UpdateLevelLoadPacifier();
//common->UpdateLevelLoadPacifier();
commandList->open();
if( pacifier )
{
common->LoadPacifierInfo( "Loading level images" );
common->LoadPacifierProgressTotal( images.Num() );
}
int loadCount = 0;
for( int i = 0 ; i < images.Num() ; i++ )
{
idImage* image = images[ i ];
if( pacifier )
{
common->LoadPacifierProgressIncrement( 1 );
}
if( image->generatorFunction )
{
continue;
@ -916,7 +937,7 @@ int idImageManager::LoadLevelImages( bool pacifier )
if( image->levelLoadReferenced && !image->IsLoaded() )
{
loadCount++;
image->FinalizeImage( false, commandList );
image->ActuallyLoadImage( false, commandList );
}
}
@ -942,13 +963,13 @@ void idImageManager::EndLevelLoad()
{
insideLevelLoad = false;
idLib::Printf( "----- idImageManager::EndLevelLoad -----\n" );
common->Printf( "----- idImageManager::EndLevelLoad -----\n" );
int start = Sys_Milliseconds();
int loadCount = LoadLevelImages( true );
int end = Sys_Milliseconds();
idLib::Printf( "%5i images loaded in %5.1f seconds\n", loadCount, ( end - start ) * 0.001 );
idLib::Printf( "----------------------------------------\n" );
common->Printf( "%5i images loaded in %5.1f seconds\n", loadCount, ( end - start ) * 0.001 );
common->Printf( "----------------------------------------\n" );
//R_ListImages_f( idCmdArgs( "sorted sorted", false ) );
}
#endif
@ -1012,6 +1033,11 @@ void idImageManager::PrintMemInfo( MemInfo_t* mi )
void idImageManager::LoadDeferredImages( nvrhi::ICommandList* _commandList )
{
if( insideLevelLoad )
{
return;
}
#if !defined( DMAP )
if( !commandList )
{
@ -1033,16 +1059,29 @@ void idImageManager::LoadDeferredImages( nvrhi::ICommandList* _commandList )
thisCmdList->open();
}
bool preloadPacifier = common->LoadPacifierRunning();
if( !preloadPacifier && globalImages->imagesToLoad.Num() > 0 )
{
common->LoadPacifierInfo( "Loading deferred images" );
common->LoadPacifierProgressTotal( imagesToLoad.Num() );
}
for( int i = 0; i < globalImages->imagesToLoad.Num(); i++ )
{
// This is a "deferred" load of textures to the gpu.
globalImages->imagesToLoad[i]->FinalizeImage( false, thisCmdList );
globalImages->imagesToLoad[i]->ActuallyLoadImage( false, thisCmdList );
if( !preloadPacifier )
{
common->LoadPacifierProgressIncrement( 1 );
}
}
#else
// just load the binary image so we have the width and height for dmap
for( int i = 0; i < globalImages->imagesToLoad.Num(); i++ )
{
// This is a "deferred" load of textures to the gpu.
globalImages->imagesToLoad[i]->FinalizeImage( false, NULL );
globalImages->imagesToLoad[i]->ActuallyLoadImage( false, NULL );
}
#endif

View file

@ -1115,26 +1115,6 @@ retry:
}
}
}
else
{
// Try loading from a deferred image hash list
int hash = name.FileNameHash();
for( int i = globalImages->deferredImageHash.First( hash ); i != -1; i = globalImages->deferredImageHash.Next( i ) )
{
idDeferredImage* image = globalImages->deferredImages[i];
if( name.Icmp( image->name ) == 0 )
{
if( pic && *pic == nullptr )
{
*usage = image->textureUsage;
*width = image->width;
*height = image->height;
memcpy( *pic, image->pic, 4 * *width * *height );
break;
}
}
}
}
// RB end
if( ( width && *width < 1 ) || ( height && *height < 1 ) )

View file

@ -308,6 +308,200 @@ void idImage::AllocImage( const idImageOpts& imgOpts, textureFilter_t tf, textur
AllocImage();
}
/*
================
GenerateImage
================
*/
void idImage::GenerateImage( const byte* pic, int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, nvrhi::ICommandList* commandList, bool isRenderTarget, bool isUAV, uint sampleCount, cubeFiles_t _cubeFiles )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = _cubeFiles;
opts.textureType = ( sampleCount > 1 ) ? TT_2D_MULTISAMPLE : TT_2D;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
opts.samples = sampleCount;
opts.isRenderTarget = isRenderTarget;
opts.isUAV = isUAV;
// RB
if( cubeFiles == CF_2D_PACKED_MIPCHAIN )
{
opts.width = width * ( 2.0f / 3.0f );
}
DeriveOpts();
// RB: allow pic == NULL for internal framebuffer images
if( pic == NULL || opts.textureType == TT_2D_MULTISAMPLE )
{
AllocImage();
isLoaded = true;
}
else
{
idBinaryImage im( GetName() );
if( cubeFiles == CF_2D_PACKED_MIPCHAIN )
{
im.Load2DAtlasMipchainFromMemory( width, opts.height, pic, opts.numLevels, opts.format, opts.colorFormat );
}
else
{
im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
}
// don't show binarize info for generated images
common->LoadPacifierBinarizeEnd();
AllocImage();
#if defined( USE_NVRHI ) && !defined( DMAP )
if( commandList )
{
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
const int bytesPerBlock = info.bytesPerBlock;
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
for( int i = 0; i < im.NumImages(); i++ )
{
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 );
}
commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
}
#else
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
#endif
isLoaded = true;
}
// RB end
}
/*
====================
GenerateCubeImage
Non-square cube sides are not allowed
====================
*/
void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t filterParm, textureUsage_t usageParm, nvrhi::ICommandList* commandList )
{
PurgeImage();
filter = filterParm;
repeat = TR_CLAMP;
usage = usageParm;
cubeFiles = CF_NATIVE;
opts.textureType = TT_CUBIC;
opts.width = size;
opts.height = size;
opts.numLevels = 0;
DeriveOpts();
// 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 the render starts would miss
// the generated texture
#if !defined( DMAP )
if( !tr.IsInitialized() )
{
return;
}
#endif
idBinaryImage im( GetName() );
im.LoadCubeFromMemory( size, pic, opts.numLevels, opts.format, opts.gammaMips );
// don't show binarize info for generated images
common->LoadPacifierBinarizeEnd();
AllocImage();
#if defined( USE_NVRHI ) && !defined( DMAP )
int numChannels = 4;
int bytesPerPixel = numChannels;
if( opts.format == FMT_ALPHA || opts.format == FMT_DXT1 || opts.format == FMT_INT8 || opts.format == FMT_R8 )
{
bytesPerPixel = 1;
}
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
bytesPerPixel = info.bytesPerBlock;
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
commandList->writeTexture( texture, 0, img.level, data, GetRowPitch( opts.format, img.width ) );
}
commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
#else
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
#endif
isLoaded = true;
}
// RB begin
void idImage::GenerateShadowArray( int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, nvrhi::ICommandList* commandList )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D_ARRAY;
byte* pic = nullptr;
opts.textureType = TT_2D_ARRAY;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
opts.isRenderTarget = true;
DeriveOpts();
// The image will be uploaded to the gpu on a deferred state.
AllocImage();
isLoaded = true;
}
// RB end
/*
===============
GetGeneratedName
@ -337,8 +531,14 @@ Absolutely every image goes through this path
On exit, the idImage will have a valid OpenGL texture number that can be bound
===============
*/
void idImage::FinalizeImage( bool fromBackEnd, nvrhi::ICommandList* commandList )
void idImage::ActuallyLoadImage( bool fromBackEnd, nvrhi::ICommandList* commandList )
{
// RB: might have been called doubled by nested LoadDeferredImages
if( isLoaded )
{
return;
}
// if we don't have a rendering context yet, just return
//if( !tr.IsInitialized() )
//{
@ -629,37 +829,26 @@ void idImage::FinalizeImage( bool fromBackEnd, nvrhi::ICommandList* commandList
DeriveOpts();
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
commonLocal.LoadPacifierBinarizeEnd();
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
// RB: convert to compressed DXT or whatever choosen target format
if( cubeFiles == CF_2D_PACKED_MIPCHAIN )
{
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
commonLocal.LoadPacifierBinarizeProgressTotal( width * opts.height );
im.Load2DAtlasMipchainFromMemory( width, opts.height, pic, opts.numLevels, opts.format, opts.colorFormat );
}
else
{
commonLocal.LoadPacifierBinarizeFilename( generatedName.c_str(), binarizeReason.c_str() );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height );
}
im.Load2DFromMemory( opts.width, opts.height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
}
commonLocal.LoadPacifierBinarizeEnd();
@ -757,6 +946,142 @@ void idImage::DeferredPurgeImage()
globalImages->imagesToLoad.Remove( this );
}
/*
=============
RB_UploadScratchImage
if rows = cols * 6, assume it is a cube map animation
=============
*/
void idImage::UploadScratch( const byte* data, int cols, int rows, nvrhi::ICommandList* commandList )
{
#if !defined( DMAP )
// if rows = cols * 6, assume it is a cube map animation
if( rows == cols * 6 )
{
rows /= 6;
const byte* pic[6];
for( int i = 0; i < 6; i++ )
{
pic[i] = data + cols * rows * 4 * i;
}
if( opts.textureType != TT_CUBIC || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateCubeImage( pic, cols, TF_LINEAR, TD_LOOKUP_TABLE_RGBA, commandList );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
#if defined( USE_NVRHI )
int numChannels = 4;
int bytesPerPixel = numChannels;
if( opts.format == FMT_ALPHA || opts.format == FMT_DXT1 || opts.format == FMT_INT8 || opts.format == FMT_R8 )
{
bytesPerPixel = 1;
}
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
bytesPerPixel = info.bytesPerBlock;
SetSamplerState( TF_LINEAR, TR_CLAMP );
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
int bufferW = opts.width;
if( IsCompressed() )
{
bufferW = ( opts.width + 3 ) & ~3;
}
for( int i = 0; i < 6; i++ )
{
commandList->writeTexture( texture, i, 0, pic[i], GetRowPitch( opts.format, opts.width ) );
}
commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
#else
/*
for( int i = 0; i < 6; i++ )
{
SubImageUpload( 0, 0, 0, i, opts.width, opts.height, pic[i] );
}
*/
#endif
}
else
{
#if defined( USE_NVRHI )
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
if( data != NULL && commandList != NULL )
{
int numChannels = 4;
int bytesPerPixel = numChannels;
if( opts.format == FMT_ALPHA || opts.format == FMT_DXT1 || opts.format == FMT_INT8 || opts.format == FMT_R8 || opts.format == FMT_LUM8 )
{
bytesPerPixel = 1;
}
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
bytesPerPixel = info.bytesPerBlock;
SetSamplerState( TF_LINEAR, TR_REPEAT );
int bufferW = opts.width;
if( IsCompressed() )
{
bufferW = ( opts.width + 3 ) & ~3;
}
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
commandList->writeTexture( texture, 0, 0, data, GetRowPitch( opts.format, opts.width ) );
//commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
}
#else
if( opts.textureType != TT_2D || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateImage( data, cols, rows, TF_LINEAR, TR_REPEAT, TD_LOOKUP_TABLE_RGBA, commandList );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
SetSamplerState( TF_LINEAR, TR_REPEAT );
SubImageUpload( 0, 0, 0, 0, opts.width, opts.height, data );
#endif
}
isLoaded = true;
#endif
}
/*
==================
StorageSize
@ -939,354 +1264,5 @@ void idImage::Reload( bool force, nvrhi::ICommandList* commandList )
DeferredLoadImage();
}
/*
================
GenerateImage
================
*/
void idImage::GenerateImage( const byte* pic, int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, nvrhi::ICommandList* commandList, bool isRenderTarget, bool isUAV, uint sampleCount, cubeFiles_t _cubeFiles )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = _cubeFiles;
opts.textureType = ( sampleCount > 1 ) ? TT_2D_MULTISAMPLE : TT_2D;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
opts.samples = sampleCount;
opts.isRenderTarget = isRenderTarget;
opts.isUAV = isUAV;
// RB
if( cubeFiles == CF_2D_PACKED_MIPCHAIN )
{
opts.width = width * ( 2.0f / 3.0f );
}
DeriveOpts();
// RB: allow pic == NULL for internal framebuffer images
if( pic == NULL || opts.textureType == TT_2D_MULTISAMPLE )
{
AllocImage();
isLoaded = true;
}
else
{
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName() , "generated image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.height );
}
if( cubeFiles == CF_2D_PACKED_MIPCHAIN )
{
im.Load2DAtlasMipchainFromMemory( width, opts.height, pic, opts.numLevels, opts.format, opts.colorFormat );
}
else
{
im.Load2DFromMemory( width, height, pic, opts.numLevels, opts.format, opts.colorFormat, opts.gammaMips );
}
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
#if defined( USE_NVRHI ) && !defined( DMAP )
if( commandList )
{
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
const int bytesPerBlock = info.bytesPerBlock;
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
for( int i = 0; i < im.NumImages(); i++ )
{
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 );
}
commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
}
#else
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
#endif
isLoaded = true;
}
// RB end
}
/*
====================
GenerateCubeImage
Non-square cube sides are not allowed
====================
*/
void idImage::GenerateCubeImage( const byte* pic[6], int size, textureFilter_t filterParm, textureUsage_t usageParm, nvrhi::ICommandList* commandList )
{
PurgeImage();
filter = filterParm;
repeat = TR_CLAMP;
usage = usageParm;
cubeFiles = CF_NATIVE;
opts.textureType = TT_CUBIC;
opts.width = size;
opts.height = size;
opts.numLevels = 0;
DeriveOpts();
// 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 the render starts would miss
// the generated texture
#if !defined( DMAP )
if( !tr.IsInitialized() )
{
return;
}
#endif
idBinaryImage im( GetName() );
// foresthale 2014-05-30: give a nice progress display when binarizing
commonLocal.LoadPacifierBinarizeFilename( GetName(), "generated cube image" );
if( opts.numLevels > 1 )
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 * 4 / 3 );
}
else
{
commonLocal.LoadPacifierBinarizeProgressTotal( opts.width * opts.width * 6 );
}
im.LoadCubeFromMemory( size, pic, opts.numLevels, opts.format, opts.gammaMips );
commonLocal.LoadPacifierBinarizeEnd();
AllocImage();
#if defined( USE_NVRHI ) && !defined( DMAP )
int numChannels = 4;
int bytesPerPixel = numChannels;
if( opts.format == FMT_ALPHA || opts.format == FMT_DXT1 || opts.format == FMT_INT8 || opts.format == FMT_R8 )
{
bytesPerPixel = 1;
}
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
bytesPerPixel = info.bytesPerBlock;
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
commandList->writeTexture( texture, 0, img.level, data, GetRowPitch( opts.format, img.width ) );
}
commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
#else
/*
for( int i = 0; i < im.NumImages(); i++ )
{
const bimageImage_t& img = im.GetImageHeader( i );
const byte* data = im.GetImageData( i );
SubImageUpload( img.level, 0, 0, img.destZ, img.width, img.height, data );
}
*/
#endif
isLoaded = true;
}
// RB begin
void idImage::GenerateShadowArray( int width, int height, textureFilter_t filterParm, textureRepeat_t repeatParm, textureUsage_t usageParm, nvrhi::ICommandList* commandList )
{
PurgeImage();
filter = filterParm;
repeat = repeatParm;
usage = usageParm;
cubeFiles = CF_2D_ARRAY;
byte* pic = nullptr;
opts.textureType = TT_2D_ARRAY;
opts.width = width;
opts.height = height;
opts.numLevels = 0;
opts.isRenderTarget = true;
DeriveOpts();
// The image will be uploaded to the gpu on a deferred state.
AllocImage();
isLoaded = true;
}
// RB end
/*
=============
RB_UploadScratchImage
if rows = cols * 6, assume it is a cube map animation
=============
*/
void idImage::UploadScratch( const byte* data, int cols, int rows, nvrhi::ICommandList* commandList )
{
#if !defined( DMAP )
// if rows = cols * 6, assume it is a cube map animation
if( rows == cols * 6 )
{
rows /= 6;
const byte* pic[6];
for( int i = 0; i < 6; i++ )
{
pic[i] = data + cols * rows * 4 * i;
}
if( opts.textureType != TT_CUBIC || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateCubeImage( pic, cols, TF_LINEAR, TD_LOOKUP_TABLE_RGBA, commandList );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
#if defined( USE_NVRHI )
int numChannels = 4;
int bytesPerPixel = numChannels;
if( opts.format == FMT_ALPHA || opts.format == FMT_DXT1 || opts.format == FMT_INT8 || opts.format == FMT_R8 )
{
bytesPerPixel = 1;
}
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
bytesPerPixel = info.bytesPerBlock;
SetSamplerState( TF_LINEAR, TR_CLAMP );
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
int bufferW = opts.width;
if( IsCompressed() )
{
bufferW = ( opts.width + 3 ) & ~3;
}
for( int i = 0; i < 6; i++ )
{
commandList->writeTexture( texture, i, 0, pic[i], GetRowPitch( opts.format, opts.width ) );
}
commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
#else
/*
for( int i = 0; i < 6; i++ )
{
SubImageUpload( 0, 0, 0, i, opts.width, opts.height, pic[i] );
}
*/
#endif
}
else
{
#if defined( USE_NVRHI )
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
if( data != NULL && commandList != NULL )
{
int numChannels = 4;
int bytesPerPixel = numChannels;
if( opts.format == FMT_ALPHA || opts.format == FMT_DXT1 || opts.format == FMT_INT8 || opts.format == FMT_R8 || opts.format == FMT_LUM8 )
{
bytesPerPixel = 1;
}
const nvrhi::FormatInfo& info = nvrhi::getFormatInfo( texture->getDesc().format );
bytesPerPixel = info.bytesPerBlock;
SetSamplerState( TF_LINEAR, TR_REPEAT );
int bufferW = opts.width;
if( IsCompressed() )
{
bufferW = ( opts.width + 3 ) & ~3;
}
commandList->beginTrackingTextureState( texture, nvrhi::AllSubresources, nvrhi::ResourceStates::Common );
commandList->writeTexture( texture, 0, 0, data, GetRowPitch( opts.format, opts.width ) );
//commandList->setPermanentTextureState( texture, nvrhi::ResourceStates::ShaderResource );
commandList->commitBarriers();
}
#else
if( opts.textureType != TT_2D || usage != TD_LOOKUP_TABLE_RGBA )
{
GenerateImage( data, cols, rows, TF_LINEAR, TR_REPEAT, TD_LOOKUP_TABLE_RGBA, commandList );
return;
}
if( opts.width != cols || opts.height != rows )
{
opts.width = cols;
opts.height = rows;
AllocImage();
}
SetSamplerState( TF_LINEAR, TR_REPEAT );
SubImageUpload( 0, 0, 0, 0, opts.width, opts.height, data );
#endif
}
isLoaded = true;
#endif
}

View file

@ -2270,7 +2270,7 @@ void idRenderBackend::SetCurrentImage( idImage* image )
if( !image->IsLoaded() && !image->IsDefaulted() )
{
// TODO(Stephen): Fix me.
image->FinalizeImage( true, commandList );
image->ActuallyLoadImage( true, commandList );
}
context.imageParms[context.currentImageParm] = image;

View file

@ -5320,7 +5320,10 @@ void idRenderBackend::ExecuteBackEndCommands( const emptyCommand_t* cmds )
GL_StartFrame();
void* textureId = globalImages->hierarchicalZbufferImage->GetTextureID();
globalImages->LoadDeferredImages( commandList );
// RB: we need to load all images left before rendering
// this can be expensive here because of the runtime image compression
//globalImages->LoadDeferredImages( commandList );
if( !ssaoPass && r_useNewSsaoPass.GetBool() )
{

View file

@ -141,7 +141,7 @@ bool BasicTriangle::Init()
commandList->open();
for( int i = 0; i < material->GetNumStages(); i++ )
{
material->GetStage( i )->texture.image->FinalizeImage( true, commandList );
material->GetStage( i )->texture.image->ActuallyLoadImage( true, commandList );
}
commandList->close();
GetDevice()->executeCommandList( commandList );

View file

@ -670,7 +670,7 @@ public:
// Initialize everything.
// if the OS allows, pass argc/argv directly (without executable name)
// otherwise pass the command line in a single string (without executable name)
virtual void Init( int argc, const char* const* argv, const char* cmdline ) { };
virtual void Init( int argc, const char* const* argv, const char* cmdline ) {}
// Shuts down everything.
virtual void Shutdown() {}
@ -698,6 +698,13 @@ public:
virtual void UpdateScreen( bool captureToImage, bool releaseMouse = true );
virtual void UpdateLevelLoadPacifier() {}
virtual void LoadPacifierInfo( VERIFY_FORMAT_STRING const char* fmt, ... ) {}
virtual void LoadPacifierProgressTotal( int total ) {}
virtual void LoadPacifierProgressIncrement( int step ) {}
virtual bool LoadPacifierRunning()
{
return false;
}
// Checks for and removes command line "+set var arg" constructs.
@ -706,7 +713,7 @@ public:
virtual void StartupVariable( const char* match ) {}
// Begins redirection of console output to the given buffer.
virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) ) { };
virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) ) {}
// Stops redirection of console output.
virtual void EndRedirect() {}

View file

@ -618,6 +618,7 @@ int Sys_Milliseconds()
return curtime;
// DG end
}
class idSysCmdline : public idSys
{
public:
@ -823,7 +824,7 @@ public:
// Initialize everything.
// if the OS allows, pass argc/argv directly (without executable name)
// otherwise pass the command line in a single string (without executable name)
virtual void Init( int argc, const char* const* argv, const char* cmdline ) { };
virtual void Init( int argc, const char* const* argv, const char* cmdline ) {}
// Shuts down everything.
virtual void Shutdown() {}
@ -851,6 +852,13 @@ public:
virtual void UpdateScreen( bool captureToImage, bool releaseMouse = true );
virtual void UpdateLevelLoadPacifier() {}
virtual void LoadPacifierInfo( VERIFY_FORMAT_STRING const char* fmt, ... ) {}
virtual void LoadPacifierProgressTotal( int total ) {}
virtual void LoadPacifierProgressIncrement( int step ) {}
virtual bool LoadPacifierRunning()
{
return false;
}
// Checks for and removes command line "+set var arg" constructs.
@ -859,7 +867,7 @@ public:
virtual void StartupVariable( const char* match ) {}
// Begins redirection of console output to the given buffer.
virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) ) { };
virtual void BeginRedirect( char* buffer, int buffersize, void ( *flush )( const char* ) ) {}
// Stops redirection of console output.
virtual void EndRedirect() {}