Skip to content

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
-Remove unused pending movie frames check
-Use staging textures for updating textures data
-Remove unneeded deferred context
  • Loading branch information
SaiyansKing committed Oct 7, 2021
1 parent 9578d7f commit 11766cb
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 139 deletions.
43 changes: 16 additions & 27 deletions D3D11Engine/D3D11GraphicsEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,6 @@ XRESULT D3D11GraphicsEngine::Init() {
Device11.As( &Device );
Context11.As( &Context );

LE( GetDevice()->CreateDeferredContext1( 0, DeferredContext.GetAddressOf() ) ); // Used for multithreaded texture loading

FeatureLevel10Compatibility = (maxFeatureLevel < D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0);
LogInfo() << "Creating ShaderManager";

Expand Down Expand Up @@ -786,22 +784,27 @@ XRESULT D3D11GraphicsEngine::OnBeginFrame() {
}
#endif

// Enter the critical section for safety while executing the deferred command
// list
// Manage deferred texture loads here
// We don't need counting loaded mip maps because
// gothic unlocks all mip maps only when loading is successful
// this means we can't have half-loaded textures
Engine::GAPI->EnterResourceCriticalSection();
Microsoft::WRL::ComPtr<ID3D11CommandList> dc_cl;

GetDeferredMediaContext1()->FinishCommandList( false, dc_cl.GetAddressOf() );
auto& stagingTextures = Engine::GAPI->GetStagingTextures();
for ( auto& it : stagingTextures ) {
GetContext()->CopySubresourceRegion( it.second, it.first.first, 0, 0, 0, it.first.second, 0, nullptr );
it.first.second->Release();
}
stagingTextures.clear();

// Copy list of textures we are operating on
Engine::GAPI->MoveLoadedTexturesToProcessedList();
Engine::GAPI->ClearFrameLoadedTextures();
auto& mipMaps = Engine::GAPI->GetMipMapGeneration();
for ( D3D11Texture* texture : mipMaps ) {
texture->GenerateMipMaps();
}
mipMaps.clear();

Engine::GAPI->SetFrameProcessedTexturesReady();
Engine::GAPI->LeaveResourceCriticalSection();
if ( dc_cl.Get() ) {
// LogInfo() << "Executing command list";
GetContext()->ExecuteCommandList( dc_cl.Get(), true );
}

// Check for editorpanel
if ( !UIView ) {
Expand Down Expand Up @@ -864,10 +867,6 @@ XRESULT D3D11GraphicsEngine::OnBeginFrame() {
XRESULT D3D11GraphicsEngine::OnEndFrame() {
Present();

// At least Present should have flushed the pipeline, so these textures should
// be ready by now
Engine::GAPI->SetFrameProcessedTexturesReady();

Engine::GAPI->GetRendererState().RendererInfo.Timing.StopTotal();
m_FrameLimiter->Wait();
return XR_SUCCESS;
Expand Down Expand Up @@ -1001,14 +1000,6 @@ XRESULT D3D11GraphicsEngine::Present() {

GetContext()->OMSetRenderTargets( 1, BackbufferRTV.GetAddressOf(), nullptr );

// Check for movie-frame
if ( Engine::GAPI->GetPendingMovieFrame() ) {
Engine::GAPI->GetPendingMovieFrame()->BindToPixelShader( 0 );
DrawQuad( INT2( 0, 0 ), GetBackbufferResolution() );

Engine::GAPI->SetPendingMovieFrame( nullptr );
}

SetDefaultStates();
UpdateRenderStates();
Engine::AntTweakBar->Draw();
Expand All @@ -1021,7 +1012,6 @@ XRESULT D3D11GraphicsEngine::Present() {

bool vsync = Engine::GAPI->GetRendererState().RendererSettings.EnableVSync;

Engine::GAPI->EnterResourceCriticalSection();
HRESULT hr;
if ( dxgi_1_3 ) {
if ( m_flipWithTearing ) {
Expand Down Expand Up @@ -1071,7 +1061,6 @@ XRESULT D3D11GraphicsEngine::Present() {
LogWarnBox() << "Device Removed! (Unknown reason)";
}
}
Engine::GAPI->LeaveResourceCriticalSection();

PresentPending = false;

Expand Down
2 changes: 0 additions & 2 deletions D3D11Engine/D3D11GraphicsEngineBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ class D3D11GraphicsEngineBase : public BaseGraphicsEngine {
/** Returns the Device/Context */
const Microsoft::WRL::ComPtr<ID3D11Device1>& GetDevice() { return Device; }
const Microsoft::WRL::ComPtr<ID3D11DeviceContext1>& GetContext() { return Context; }
const Microsoft::WRL::ComPtr<ID3D11DeviceContext1>& GetDeferredMediaContext1() { return DeferredContext; }

/** Pixel Shader functions */
void UnbindActivePS() { ActivePS = nullptr; }
Expand Down Expand Up @@ -248,7 +247,6 @@ class D3D11GraphicsEngineBase : public BaseGraphicsEngine {
Microsoft::WRL::ComPtr<ID3D11DeviceContext> Context11;
Microsoft::WRL::ComPtr<ID3D11Device1> Device;
Microsoft::WRL::ComPtr<ID3D11DeviceContext1> Context;
Microsoft::WRL::ComPtr<ID3D11DeviceContext1> DeferredContext;

/** Swapchain and resources */
Microsoft::WRL::ComPtr<IDXGISwapChain1> SwapChain;
Expand Down
101 changes: 65 additions & 36 deletions D3D11Engine/D3D11Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ XRESULT D3D11Texture::Init( INT2 size, ETextureFormat format, UINT mipMapCount,
HRESULT hr;
D3D11GraphicsEngineBase* engine = (D3D11GraphicsEngineBase*)Engine::GraphicsEngine;

//Engine::GAPI->EnterResourceCriticalSection();

TextureFormat = (DXGI_FORMAT)format;
TextureSize = size;
MipMapCount = mipMapCount;
Expand All @@ -56,8 +54,6 @@ XRESULT D3D11Texture::Init( INT2 size, ETextureFormat format, UINT mipMapCount,
LE( engine->GetDevice()->CreateShaderResourceView( Texture.Get(), &descRV, ShaderResourceView.ReleaseAndGetAddressOf() ) );
SetDebugName( ShaderResourceView.Get(), "D3D11Texture(\"" + fileName + "\")->ShaderResourceView" );

//Engine::GAPI->LeaveResourceCriticalSection();

return XR_SUCCESS;
}

Expand All @@ -68,8 +64,6 @@ XRESULT D3D11Texture::Init( const std::string& file ) {

//LogInfo() << "Loading Engine-Texture: " << file;

//Engine::GAPI->EnterResourceCriticalSection();

Microsoft::WRL::ComPtr<ID3D11Texture2D> res;
LE( CreateDDSTextureFromFile( engine->GetDevice().Get(), Toolbox::ToWideChar( file.c_str() ).c_str(), (ID3D11Resource**)res.ReleaseAndGetAddressOf(), ShaderResourceView.GetAddressOf() ) );

Expand All @@ -87,45 +81,77 @@ XRESULT D3D11Texture::Init( const std::string& file ) {
SetDebugName( res.Get(), "D3D11Texture(\"" + file + "\")->Texture" );
SetDebugName( ShaderResourceView.Get(), "D3D11Texture(\"" + file + "\")->ShaderResourceView" );

//Engine::GAPI->LeaveResourceCriticalSection();

return XR_SUCCESS;
}

/** Updates the Texture-Object */
XRESULT D3D11Texture::UpdateData( void* data, int mip ) {
D3D11GraphicsEngineBase* engine = (D3D11GraphicsEngineBase*)Engine::GraphicsEngine;

// Enter the critical section for safety while executing the deferred command list
Engine::GAPI->EnterResourceCriticalSection();
engine->GetContext()->UpdateSubresource( Texture.Get(), mip, nullptr, data, GetRowPitchBytes( mip ), GetSizeInBytes( mip ) );
Engine::GAPI->LeaveResourceCriticalSection();
UINT TextureWidth = (TextureSize.x >> mip);
UINT TextureHeight = (TextureSize.y >> mip);

Microsoft::WRL::ComPtr<ID3D11Texture2D> stagingTexture;
D3D11_TEXTURE2D_DESC stagingTextureDesc;
Texture.Get()->GetDesc( &stagingTextureDesc );
stagingTextureDesc.Width = TextureWidth;
stagingTextureDesc.Height = TextureHeight;
stagingTextureDesc.MipLevels = 1;
stagingTextureDesc.BindFlags = 0;
stagingTextureDesc.MiscFlags = 0;
stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
stagingTextureDesc.Usage = D3D11_USAGE_STAGING;

D3D11_SUBRESOURCE_DATA stagingTextureData;
stagingTextureData.pSysMem = data;
stagingTextureData.SysMemPitch = GetRowPitchBytes( mip );
stagingTextureData.SysMemSlicePitch = 0;

HRESULT result = engine->GetDevice()->CreateTexture2D( &stagingTextureDesc, &stagingTextureData, stagingTexture.ReleaseAndGetAddressOf() );
if ( FAILED( result ) )
return XR_FAILED;

engine->GetContext()->CopySubresourceRegion( Texture.Get(), mip, 0, 0, 0, stagingTexture.Get(), 0, nullptr );

return XR_SUCCESS;
}

/** Updates the Texture-Object using the deferred context (For loading in an other thread) */
XRESULT D3D11Texture::UpdateDataDeferred( void* data, int mip, bool noLock ) {
XRESULT D3D11Texture::UpdateDataDeferred( void* data, int mip ) {
D3D11GraphicsEngineBase* engine = (D3D11GraphicsEngineBase*)Engine::GraphicsEngine;

// Enter the critical section for safety while executing the deferred command list
if ( !noLock )
Engine::GAPI->EnterResourceCriticalSection();

engine->GetDeferredMediaContext1()->UpdateSubresource( Texture.Get(), mip, nullptr, data, GetRowPitchBytes( mip ), GetSizeInBytes( mip ) );
UINT TextureWidth = (TextureSize.x >> mip);
UINT TextureHeight = (TextureSize.y >> mip);

ID3D11Texture2D* stagingTexture;
D3D11_TEXTURE2D_DESC stagingTextureDesc;
Texture.Get()->GetDesc( &stagingTextureDesc );
stagingTextureDesc.Width = TextureWidth;
stagingTextureDesc.Height = TextureHeight;
stagingTextureDesc.MipLevels = 1;
stagingTextureDesc.BindFlags = 0;
stagingTextureDesc.MiscFlags = 0;
stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
stagingTextureDesc.Usage = D3D11_USAGE_STAGING;

D3D11_SUBRESOURCE_DATA stagingTextureData;
stagingTextureData.pSysMem = data;
stagingTextureData.SysMemPitch = GetRowPitchBytes( mip );
stagingTextureData.SysMemSlicePitch = 0;

HRESULT result = engine->GetDevice()->CreateTexture2D( &stagingTextureDesc, &stagingTextureData, &stagingTexture );
if ( FAILED( result ) )
return XR_FAILED;

if ( !noLock )
Engine::GAPI->LeaveResourceCriticalSection();
Engine::GAPI->AddStagingTexture( mip, stagingTexture, Texture.Get() );

return XR_SUCCESS;
}

/** Returns the RowPitch-Bytes */
UINT D3D11Texture::GetRowPitchBytes( int mip ) {
int px = static_cast<int>( std::max<float>( 1.0f, floor( TextureSize.x / pow( 2.0f, mip ) ) ) );
//int py = (int)std::max( 1.0, floor( TextureSize.y / pow( 2.0f, mip ) ) );
//int px = TextureSize.x;
//int py = TextureSize.y;
int px = (TextureSize.x >> mip);
//int py = (TextureSize.y >> mip);

if ( TextureFormat == DXGI_FORMAT_BC1_UNORM || TextureFormat == DXGI_FORMAT_BC2_UNORM ||
TextureFormat == DXGI_FORMAT_BC3_UNORM ) {
Expand All @@ -138,10 +164,8 @@ UINT D3D11Texture::GetRowPitchBytes( int mip ) {

/** Returns the size of the texture in bytes */
UINT D3D11Texture::GetSizeInBytes( int mip ) {
int px = static_cast<int>( std::max<float>( 1.0f, floor( TextureSize.x / pow( 2.0f, mip ) ) ) );
int py = static_cast<int>( std::max<float>( 1.0f, floor( TextureSize.y / pow( 2.0f, mip ) ) ) );
//int px = TextureSize.x;
//int py = TextureSize.y;
int px = (TextureSize.x >> mip);
int py = (TextureSize.y >> mip);

if ( TextureFormat == DXGI_FORMAT_BC1_UNORM || TextureFormat == DXGI_FORMAT_BC2_UNORM ||
TextureFormat == DXGI_FORMAT_BC3_UNORM ) {
Expand Down Expand Up @@ -233,20 +257,25 @@ XRESULT D3D11Texture::GenerateMipMaps() {

D3D11GraphicsEngineBase* engine = (D3D11GraphicsEngineBase*)Engine::GraphicsEngine;

Engine::GAPI->EnterResourceCriticalSection();
std::unique_ptr<RenderToTextureBuffer> b = std::make_unique<RenderToTextureBuffer>( engine->GetDevice().Get(), TextureSize.x, TextureSize.y, DXGI_FORMAT_R8G8B8A8_UNORM, nullptr, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, MipMapCount );

RenderToTextureBuffer* b = new RenderToTextureBuffer( engine->GetDevice().Get(), TextureSize.x, TextureSize.y, DXGI_FORMAT_R8G8B8A8_UNORM, nullptr, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, MipMapCount );

engine->GetDeferredMediaContext1()->CopySubresourceRegion( b->GetTexture().Get(), 0, 0, 0, 0, Texture.Get(), 0, nullptr );
// Copy the main image
engine->GetContext()->CopySubresourceRegion( b->GetTexture().Get(), 0, 0, 0, 0, Texture.Get(), 0, nullptr );

// Generate mips
engine->GetDeferredMediaContext1()->GenerateMips( b->GetShaderResView().Get() );
engine->GetContext()->GenerateMips( b->GetShaderResView().Get() );

// Copy the full chain back
engine->GetDeferredMediaContext1()->CopyResource( Texture.Get(), b->GetTexture().Get() );
delete b;
engine->GetContext()->CopyResource( Texture.Get(), b->GetTexture().Get() );

return XR_SUCCESS;
}

XRESULT D3D11Texture::GenerateMipMapsDeferred() {
if ( MipMapCount == 1 )
return XR_SUCCESS;

Engine::GAPI->LeaveResourceCriticalSection();
Engine::GAPI->AddMipMapGeneration( this );

return XR_SUCCESS;
}
3 changes: 2 additions & 1 deletion D3D11Engine/D3D11Texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class D3D11Texture {
XRESULT UpdateData( void* data, int mip = 0 );

/** Updates the Texture-Object using the deferred context (For loading in an other thread) */
XRESULT UpdateDataDeferred( void* data, int mip, bool noLock = false );
XRESULT UpdateDataDeferred( void* data, int mip );

/** Returns the RowPitch-Bytes */
UINT GetRowPitchBytes( int mip );
Expand Down Expand Up @@ -55,6 +55,7 @@ class D3D11Texture {

/** Generates mipmaps for this texture (may be slow!) */
XRESULT GenerateMipMaps();
XRESULT GenerateMipMapsDeferred();

/** Returns this textures ID */
UINT16 GetID() { return ID; };
Expand Down
13 changes: 8 additions & 5 deletions D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,13 @@ HRESULT FakeDirectDrawSurface7::Lock( LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSu
*lpDDSurfaceDesc = OriginalDesc;

// Allocate some temporary data
delete [] Data;
Data = new unsigned char[Resource->GetEngineTexture()->GetSizeInBytes( MipLevel )];
lpDDSurfaceDesc->lpSurface = Data;
lpDDSurfaceDesc->lPitch = Resource->GetEngineTexture()->GetRowPitchBytes( MipLevel );

int px = static_cast<int>( std::max<float>( 1.0f, floor( OriginalDesc.dwWidth / pow( 2.0f, MipLevel ) ) ) );
int py = static_cast<int>( std::max<float>( 1.0f, floor( OriginalDesc.dwHeight / pow( 2.0f, MipLevel ) ) ) );
int px = (OriginalDesc.dwWidth >> MipLevel);
int py = (OriginalDesc.dwHeight >> MipLevel);

lpDDSurfaceDesc->dwWidth = px;
lpDDSurfaceDesc->dwHeight = py;
Expand All @@ -201,9 +202,11 @@ HRESULT FakeDirectDrawSurface7::Unlock( LPRECT lpRect ) {
int bpp = redBits + greenBits + blueBits + alphaBits;

if ( bpp != 16 ) {
Resource->GetEngineTexture()->UpdateDataDeferred( Data, MipLevel );
Resource->IncreaseQueuedMipMapCount();
Engine::GAPI->AddFrameLoadedTexture( Resource );
if ( Engine::GAPI->GetMainThreadID() != GetCurrentThreadId() ) {
Resource->GetEngineTexture()->UpdateDataDeferred( Data, MipLevel );
} else {
Resource->GetEngineTexture()->UpdateData( Data, MipLevel );
}
}

delete [] Data;
Expand Down
25 changes: 2 additions & 23 deletions D3D11Engine/D3D7/MyDirectDrawSurface7.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ MyDirectDrawSurface7::MyDirectDrawSurface7() {
GothicTexture = nullptr;
IsReady = false;
TextureType = ETextureType::TX_UNDEF;

QueuedMipMaps = 0;
LockType = 0;

// Check for test-bind mode to figure out what zCTexture-Object we are associated with
Expand Down Expand Up @@ -372,7 +370,6 @@ HRESULT MyDirectDrawSurface7::Lock( LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurf
// don't deallocate the memory after unlock, since only the changing parts in videos will get updated
if ( !LockedData )
LockedData = new unsigned char[EngineTexture->GetSizeInBytes( 0 ) / divisor];

} else {
// Allocate some temporary data
delete[] LockedData;
Expand Down Expand Up @@ -434,21 +431,15 @@ HRESULT MyDirectDrawSurface7::Unlock( LPRECT lpRect ) {

if ( Engine::GAPI->GetMainThreadID() != GetCurrentThreadId() ) {
EngineTexture->UpdateDataDeferred( dst, 0 );
EngineTexture->GenerateMipMapsDeferred();
Engine::GAPI->AddFrameLoadedTexture( this );
} else {
EngineTexture->UpdateData( dst, 0 );
Engine::GAPI->AddFrameLoadedTexture( this );
EngineTexture->GenerateMipMaps();
SetReady( true ); // No need to load other stuff to get this ready
}

delete[] dst;

EngineTexture->GenerateMipMaps();

// We don't actuall load mipmaps for this type, so set this
// so that it says the texture is fully loaded
QueuedMipMaps = OriginalSurfaceDesc.dwMipMapCount - 1;

} else {
if ( bpp == 24 ) {
// This is a movie frame, draw it to the sceen
Expand Down Expand Up @@ -477,7 +468,6 @@ HRESULT MyDirectDrawSurface7::Unlock( LPRECT lpRect ) {
// select the smaller one
float scale = std::min( scaleX, scaleY ) * 0.75f;


// I am honestly not sure how this is correct, but after an hour of fiddeling this works fine. You probably don't want to touch it.
float tlx = -engineRes.x * scale + (float)engineRes.x;
float tly = -engineRes.y * scale + (float)engineRes.y;
Expand All @@ -499,7 +489,6 @@ HRESULT MyDirectDrawSurface7::Unlock( LPRECT lpRect ) {
Engine::GAPI->AddFrameLoadedTexture( this );
} else {
EngineTexture->UpdateData( LockedData, 0 );
Engine::GAPI->AddFrameLoadedTexture( this );
SetReady( true ); // No need to load other stuff to get this ready
}
}
Expand Down Expand Up @@ -702,13 +691,3 @@ HRESULT MyDirectDrawSurface7::GetLOD( LPDWORD dwLOD ) {
const std::string& MyDirectDrawSurface7::GetTextureName() {
return TextureName;
}

/** Returns whether the mip-maps were put into the command queue or not */
bool MyDirectDrawSurface7::MipMapsInQueue() {
return OriginalSurfaceDesc.dwMipMapCount == QueuedMipMaps + 1;
}

/** Adds one to the queued mipmap count */
void MyDirectDrawSurface7::IncreaseQueuedMipMapCount() {
QueuedMipMaps++;
}
Loading

0 comments on commit 11766cb

Please sign in to comment.