Skip to content

Commit

Permalink
Render/Depth target viewing updates
Browse files Browse the repository at this point in the history
Makes render target view a little more robust when viewing non a8r8g8b8
types. Still needs a little work.

Supports more depth buffer formats (but renders them all in INTZ)

Support for showing depth buffers as floats in the gui.

Fix for texture coordinates being wrong in the texture/render
target/depth target viewing window.
  • Loading branch information
imccown committed Feb 16, 2015
1 parent 63a5530 commit 11f7493
Show file tree
Hide file tree
Showing 15 changed files with 252 additions and 112 deletions.
5 changes: 3 additions & 2 deletions Dissector/Dissector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1121,15 +1121,16 @@ namespace Dissector
}

void ImageRetrievalCallback( void* iTexture, unsigned int iRSType, void* iImage, unsigned int iSizeX,
unsigned int iSizeY, unsigned int iPitch )
unsigned int iSizeY, unsigned int iPitch, PixelTypes iType )
{
char header[ 8 + 4 + 4 + 4 + 4 ];
char header[ 8 + 4 + 4 + 4 + 4 + 4 ];
char* iter = header;
StoreBufferData( __int64(iTexture), iter );
StoreBufferData( iRSType, iter );
StoreBufferData( iSizeX, iter );
StoreBufferData( iSizeY, iter );
StoreBufferData( iPitch, iter );
StoreBufferData<unsigned int>( iType, iter );

SendResponse(Dissector::RSP_IMAGE, header, (unsigned int)(sizeof(header)),
iImage, (unsigned int)(iSizeY * iPitch), 0);
Expand Down
25 changes: 21 additions & 4 deletions Dissector/Dissector.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ namespace Dissector
ST_HULL,
};

enum PixelTypes
{
PIXEL_A8R8G8B8 = 0,
PIXEL_R32F,
};

enum CommandTypes
{
CMD_NONE = 0,
Expand Down Expand Up @@ -286,14 +292,11 @@ namespace Dissector

// Call this from GetTextureImageCallback to supply the image.
void ImageRetrievalCallback( void* iTexture, unsigned int iVisualizerType, void* iImage, unsigned int iSizeX,
unsigned int iSizeY, unsigned int iPitch );
unsigned int iSizeY, unsigned int iPitch, PixelTypes iType );

// Call this from GetCurrentRTCallback to supply the image.
void CurrentRTRetrievalCallback( void* iImage, unsigned int iSizeX, unsigned int iSizeY, unsigned int iPitch );

// Call this from GetTextureImageCallback to supply the image.
void ImageRetrievalCallback( void* iTexture, unsigned int iVisualizerType, void* iImage, unsigned int iSizeX,
unsigned int iSizeY, unsigned int iPitch );

// Call this from GetTextureThumbnailCallback to supply the image.
void ThumbnailRetrievalCallback( void* iTexture, unsigned int iVisualizerType, void* iImage, unsigned int iSizeX,
Expand Down Expand Up @@ -346,6 +349,20 @@ namespace Dissector
// For other libs to use easily
void* MallocCallback( size_t size );
void FreeCallback( void* ptr );

// Utilities
inline size_t GetPixelSize( PixelTypes iType )
{
switch( iType )
{
case( PIXEL_A8R8G8B8 ):
case( PIXEL_R32F ):
return 4;

default:
return 1;
}
}
};

#define SAFE_DEALLOC( iObject ) if( iObject ){ Dissector::FreeCallback( iObject ); iObject = 0; }
Expand Down
4 changes: 1 addition & 3 deletions Dissector/Todo.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
Tasks:

--- Shortlist ---
Crashes in BGFX
x64 support
Better depth/stencil viewing support
Add wireframe viewing support.
Choose which render target to view, and/or show all render targets.

-- Try to get in --
Expand Down
11 changes: 7 additions & 4 deletions DissectorDX9/DX9Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -976,9 +976,8 @@ namespace DissectorDX9
D3DFORMAT fmt;
switch( desc.Format )
{
// Implement the lockable type someday.
//case( D3DFMT_D16 ): fmt = D3DFMT_D16_LOCKABLE; break;
//case( D3DFMT_D32 ): fmt = D3DFMT_D32_LOCKABLE; break;
case( D3DFMT_D16 ):
case( D3DFMT_D32 ):
case( D3DFMT_D24X8 ):
case( D3DFMT_D24S8 ): fmt = (D3DFORMAT)MAKEFOURCC( 'I', 'N', 'T', 'Z' ); break;
default: return iSurface; // Can't replace certain types of depth buffer formats.
Expand All @@ -1004,7 +1003,7 @@ namespace DissectorDX9
}

void RenderTextureToRT( IDirect3DDevice9* iD3DDevice, IDirect3DBaseTexture9* iTexture, IDirect3DSurface9* iRenderTarget,
IDirect3DPixelShader9* overrideShader, bool iInFrame )
IDirect3DPixelShader9* overrideShader, bool iInFrame, float* iExtraConstants, int iNumConstants )
{
if( !iInFrame )
iD3DDevice->BeginScene();
Expand All @@ -1028,6 +1027,10 @@ namespace DissectorDX9
uvOffset[2] = uvOffset[3] = 0.f;

iD3DDevice->SetPixelShaderConstantF( 0, uvOffset, 1 );
if( iExtraConstants && iNumConstants )
{
iD3DDevice->SetPixelShaderConstantF( 1, iExtraConstants, iNumConstants );
}

DrawFullScreenQuad( iD3DDevice );

Expand Down
2 changes: 1 addition & 1 deletion DissectorDX9/DX9Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace DissectorDX9
IDirect3DSurface9* GetDepthBufferReplacement( IDirect3DDevice9* iD3DDevice, IDirect3DSurface9* iSurface );

void RenderTextureToRT( IDirect3DDevice9* iD3DDevice, IDirect3DBaseTexture9* iTexture, IDirect3DSurface9* iRenderTarget,
IDirect3DPixelShader9* overrideShader = NULL, bool iInFrame = false );
IDirect3DPixelShader9* overrideShader = NULL, bool iInFrame = false, float* extraConstants = NULL, int numConstants = 0 );

UINT GetVertexCountFromPrimitiveCount( D3DPRIMITIVETYPE iPrimitiveType, UINT iNumElements );
UINT GetPrimtiveCountFromVertexCount( D3DPRIMITIVETYPE iPrimitiveType, UINT iNumVertices );
Expand Down
2 changes: 2 additions & 0 deletions DissectorDX9/DX9Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ struct DX9Data
IUnknown** mAssetHandles;
unsigned int mAssetHandlesCount;
unsigned int mAssetHandlesSize;

const Dissector::DrawCallData* mLastEvent;
};

struct RegisterData
Expand Down
158 changes: 82 additions & 76 deletions DissectorDX9/DissectorDX9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,8 @@ namespace DissectorDX9
DepthBufferReplacement* delPtr = iter;
iter = iter->mNext;
ULONG ref = delPtr->mReplacement->Release();
ref = delPtr->mTexture->Release();
if( delPtr->mTexture )
ref = delPtr->mTexture->Release();
Dissector::FreeCallback( delPtr );
}

Expand Down Expand Up @@ -1913,14 +1914,47 @@ namespace DissectorDX9
VertexStreamZeroStride );
}

void GetDepthForTextureImage( void* iDevice, void* iTexture, unsigned int iRSType, unsigned int iEventId )
bool ConvertRenderTargetToTexture( void* iDevice, IDirect3DSurface9* iSurface, IDirect3DTexture9** oTex )
{
IDirect3DDevice9* D3DDevice = (IDirect3DDevice9*)iDevice;

D3DSURFACE_DESC desc;
iSurface->GetDesc( &desc );

if( desc.Format == MAKEFOURCC( 'N', 'U', 'L', 'L' ) )
return false;

ScopedRelease<IDirect3DTexture9> tex;
HRESULT res = D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex.mPtr, NULL);
if (res != S_OK || !tex.mPtr)
return false;

ScopedRelease<IDirect3DSurface9> mip;
tex->GetSurfaceLevel( 0, &mip.mPtr );
if( S_OK != D3DDevice->GetRenderTargetData( iSurface, mip.mPtr ) )
return false;

res = D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_DEFAULT, oTex, NULL);
if (res != S_OK || !*oTex)
return false;

if( D3DDevice->UpdateTexture( tex.mPtr, *oTex ) != S_OK )
{
(*oTex)->Release();
return false;
}

return true;
}

bool GetDepthForTextureImage( void* iDevice, void* iTexture, unsigned int iRSType, unsigned int iEventId )
{
IDirect3DDevice9* D3DDevice = (IDirect3DDevice9*)iDevice;

Dissector::DrawCallData* drawIter = NULL;
drawIter = ExecuteToEvent( iDevice, iEventId+1 );
if( !drawIter )
return;
return false;

ScopedEndFrame endScene( D3DDevice );

Expand All @@ -1929,74 +1963,58 @@ namespace DissectorDX9

IDirect3DTexture9* surface = GetDepthBufferTexture( ds.mPtr );
if( !surface )
return;
return false;

D3DSURFACE_DESC desc;
surface->GetLevelDesc( 0, &desc );

unsigned int minVal = 0xFFFFFFFF, maxVal = 0;
if( desc.Format == MAKEFOURCC( 'I', 'N', 'T', 'Z' ) )
{
ScopedRelease<IDirect3DSurface9> destMinMax, dest;
D3DDevice->CreateRenderTarget( desc.Width, desc.Height, D3DFMT_R32F, D3DMULTISAMPLE_NONE, 0, true, &destMinMax.mPtr, NULL );
D3DDevice->CreateRenderTarget( desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, true, &dest.mPtr, NULL );
if( dest.mPtr && destMinMax.mPtr )
ScopedRelease<IDirect3DSurface9> dest;
D3DDevice->CreateRenderTarget( desc.Width, desc.Height, D3DFMT_R32F, D3DMULTISAMPLE_NONE, 0, true, &dest.mPtr, NULL );
if( dest.mPtr )
{
RenderTextureToRT( D3DDevice, surface, dest, NULL, true );

D3DLOCKED_RECT rect;
HRESULT res = dest->LockRect( &rect, NULL, D3DLOCK_READONLY );
Dissector::ImageRetrievalCallback( iTexture, iRSType, rect.pBits, desc.Width, desc.Height, rect.Pitch );

for( unsigned int ii = 0; ii < desc.Height; ++ii )
{
unsigned int* iter = (unsigned int*)((char*)(rect.pBits) + rect.Pitch * ii);
unsigned int* endIter = iter + desc.Width;
while( iter < endIter )
{
minVal = min( minVal, *iter );
maxVal = min( minVal, *iter );
++iter;
}

}

Dissector::ImageRetrievalCallback( iTexture, iRSType, rect.pBits, desc.Width, desc.Height, rect.Pitch, Dissector::PIXEL_R32F );
dest->UnlockRect();

}
}

return true;
}

void GetRTForTextureImage( void* iDevice, void* iTexture, unsigned int iRSType, unsigned int iNum )
bool GetRTForTextureImage( void* iDevice, void* iTexture, unsigned int iRSType, unsigned int iNum )
{
IDirect3DDevice9* D3DDevice = (IDirect3DDevice9*)iDevice;

ScopedRelease<IDirect3DTexture9> gputex;

ScopedRelease<IDirect3DSurface9> rt, newRt;
D3DDevice->GetRenderTarget( iNum, &rt.mPtr );
if( !rt )
return;
return false;

D3DSURFACE_DESC desc;

rt->GetDesc( &desc );

if( desc.Format != D3DFMT_A8R8G8B8 )
{
// TODO: Make this work.
}
if( !ConvertRenderTargetToTexture( iDevice, rt, &gputex.mPtr ) )
return false;

D3DDevice->CreateRenderTarget( desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, true, &newRt.mPtr, NULL );
if( !newRt )
return;
return false;

D3DDevice->StretchRect( rt, NULL, newRt, NULL, D3DTEXF_POINT );
RenderTextureToRT( D3DDevice, gputex.mPtr, newRt.mPtr, NULL, false );

D3DLOCKED_RECT rect;
newRt->LockRect( &rect, NULL, 0 );
if( rect.pBits )
{
Dissector::ImageRetrievalCallback( iTexture, iRSType, rect.pBits, desc.Width, desc.Height, rect.Pitch );
}
newRt->UnlockRect();
HRESULT res = newRt->LockRect( &rect, NULL, D3DLOCK_READONLY );
Dissector::ImageRetrievalCallback( iTexture, iRSType, rect.pBits, desc.Width, desc.Height, rect.Pitch, Dissector::PIXEL_A8R8G8B8 );

return true;
}

void GetTextureThumbnailInternal( void* iDevice, void* iTexture, unsigned int iVisualizerType, int iEventNum, void* iIDOveride = NULL )
Expand Down Expand Up @@ -2033,54 +2051,25 @@ namespace DissectorDX9
}
}

void GetRTThumbnail( void* iDevice, void* iTexture, unsigned int iVisualizerType, int iEventNum )
bool GetRTThumbnail( void* iDevice, void* iTexture, unsigned int iVisualizerType, int iEventNum )
{
IDirect3DDevice9* D3DDevice = (IDirect3DDevice9*)iDevice;

ScopedRelease<IDirect3DSurface9> rt, newRt;
D3DDevice->GetRenderTarget( 0, &rt.mPtr );
if( !rt )
return;
return false;

D3DSURFACE_DESC desc;

rt->GetDesc( &desc );

if( desc.Format == MAKEFOURCC( 'N', 'U', 'L', 'L' ) )
return;

D3DDevice->CreateRenderTarget( desc.Width, desc.Height, desc.Format, D3DMULTISAMPLE_NONE, 0, true, &newRt.mPtr, NULL );
if( !newRt )
return;

D3DDevice->StretchRect( rt, NULL, newRt, NULL, D3DTEXF_POINT );

D3DLOCKED_RECT rect;
if( S_OK == newRt->LockRect( &rect, NULL, 0 ) && rect.pBits )
{
ScopedRelease<IDirect3DTexture9> tempTex;
if( S_OK == D3DDevice->CreateTexture( desc.Width, desc.Height, 1, D3DUSAGE_DYNAMIC, desc.Format, D3DPOOL_DEFAULT, &tempTex.mPtr, NULL ) )
{
D3DLOCKED_RECT writeRect;
HRESULT res = tempTex->LockRect( 0, &writeRect, NULL, 0 );
if( S_OK == res )
{
char* readIter = (char*)rect.pBits;
char* writeIter = (char*)writeRect.pBits;
int pitch = min( writeRect.Pitch, rect.Pitch );
for( unsigned int ii = 0; ii < desc.Height; ++ii, writeIter += writeRect.Pitch, readIter += rect.Pitch )
{
memcpy( writeIter, readIter, pitch );
}
ScopedRelease<IDirect3DTexture9> gputex;
if( !ConvertRenderTargetToTexture( iDevice, rt.mPtr, &gputex.mPtr ) )
return false;

tempTex->UnlockRect( 0 );
GetTextureThumbnailInternal( iDevice, tempTex.mPtr, iVisualizerType, iEventNum, iTexture );
}
}
GetTextureThumbnailInternal( iDevice, gputex.mPtr, iVisualizerType, iEventNum, iTexture );

//Dissector::CurrentRTRetrievalCallback( rect.pBits, desc.Width, desc.Height, rect.Pitch );
newRt->UnlockRect();
}
return true;
}

bool EndFrameExternal( void* iDevice )
Expand Down Expand Up @@ -2111,12 +2100,14 @@ namespace DissectorDX9

virtual void ResimulateStart(void* iDevice)
{
sDX9Data.mLastEvent = NULL;
BeginFrame( iDevice );
}

virtual void ResimulateEvent(void* iDevice, const Dissector::DrawCallData& iData, bool iRecordTiming, Dissector::TimingData* oTiming )
{
DissectorDX9::ResimulateEvent( iDevice, iData, iRecordTiming, oTiming );
sDX9Data.mLastEvent = &iData;
}

virtual void GatherStatsForEvent(void* iDevice, const Dissector::DrawCallData& iData)
Expand Down Expand Up @@ -2188,6 +2179,21 @@ namespace DissectorDX9

virtual bool ResimulateEnd(void* iDevice)
{
if( sDX9Data.mLastEvent )
{
if( sDX9Data.mLastEvent->mEventType == ET_DRAWINDEXED ||
sDX9Data.mLastEvent->mEventType == ET_DRAW ||
sDX9Data.mLastEvent->mEventType == ET_DRAWINDEXEDUP ||
sDX9Data.mLastEvent->mEventType == ET_DRAWUP )
{
// TODO: Make this use a special shader to show wireframe stuff.
//IDirect3DDevice9* D3DDevice = (IDirect3DDevice9*)iDevice;
//ResetDevice( D3DDevice );
//D3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
//ExecuteEvent( D3DDevice, *sDX9Data.mLastEvent );
}
}

return EndFrameExternal( iDevice );
}

Expand Down Expand Up @@ -2270,7 +2276,7 @@ namespace DissectorDX9

D3DLOCKED_RECT rect;
HRESULT res = dest->LockRect( &rect, NULL, D3DLOCK_READONLY );
Dissector::ImageRetrievalCallback( iTexture, iRSType, rect.pBits, desc.Width, desc.Height, rect.Pitch );
Dissector::ImageRetrievalCallback( iTexture, iRSType, rect.pBits, desc.Width, desc.Height, rect.Pitch, Dissector::PIXEL_A8R8G8B8 );
dest->UnlockRect();
}

Expand Down
Loading

0 comments on commit 11f7493

Please sign in to comment.