📄 dx9texture.cpp
字号:
// dx9texture.cpp#include "dx9texture.hpp"using namespace brook;DX9Texture::DX9Texture( GPUContextDX9* inContext, int inWidth, int inHeight, int inComponents ) : width(inWidth), height(inHeight), components(inComponents), internalComponents(inComponents), dirtyFlags(0), device(NULL), textureHandle(NULL), surfaceHandle(NULL), shadowSurface(NULL){ _context = inContext; device = _context->getDevice(); device->AddRef();}static D3DFORMAT getFormatForComponentCount( int inComponentCount ){ switch( inComponentCount ) { case 1: return D3DFMT_R32F; case 2: return D3DFMT_G32R32F; case 4: return D3DFMT_A32B32G32R32F; default: return D3DFMT_UNKNOWN; }}bool DX9Texture::initialize(){ HRESULT result; D3DFORMAT dxFormat; bool validFormat = false; for( int i = components; i <= 4 && !validFormat; i++ ) { dxFormat = getFormatForComponentCount( i ); if( dxFormat != D3DFMT_UNKNOWN && _context->isRenderTextureFormatValid( dxFormat ) ) { validFormat = true; internalComponents = i; } } if( !validFormat ) { DX9WARN << "Could not find supported floating-point texture format." << std::endl; return false; } result = device->CreateTexture( width, height, 1, D3DUSAGE_RENDERTARGET, dxFormat, D3DPOOL_DEFAULT, &textureHandle, NULL ); if( FAILED( result ) ) { DX9WARN << "Unable to create floating-point render target texture of size " << width << " by " << height << " by float" << components << "."; return false; } result = textureHandle->GetSurfaceLevel( 0, &surfaceHandle ); DX9AssertResult( result, "GetSurfaceLevel failed" ); result = device->CreateOffscreenPlainSurface( width, height, dxFormat, D3DPOOL_SYSTEMMEM, &shadowSurface, NULL ); if( FAILED( result ) ) { DX9WARN << "Unable to create floating-point plain surface of size " << width << " by " << height << "."; return false; } return true;}DX9Texture::~DX9Texture(){ DX9LOG(2) << "~DX9Texture"; if( shadowSurface != NULL ) shadowSurface->Release(); if( surfaceHandle != NULL ) surfaceHandle->Release(); if( textureHandle != NULL ) textureHandle->Release(); if( device != NULL ) device->Release();}DX9Texture* DX9Texture::create( GPUContextDX9* inContext, int inWidth, int inHeight, int inComponents ){ DX9PROFILE("DX9Texture::create") DX9Texture* result = new DX9Texture( inContext, inWidth, inHeight, inComponents ); if( result->initialize() ) return result; delete result; return NULL;}void DX9Texture::setData( const float* inData, unsigned int inStride, unsigned int inCount, unsigned int inRank, const unsigned int* inDomainMin, const unsigned int* inDomainMax, const unsigned int* inExtents, bool inUsesAddressTranslation ){ DX9PROFILE("DX9Texture::setData") setShadowData( inData, inStride, inCount, inRank, inDomainMin, inDomainMax, inExtents, inUsesAddressTranslation ); markShadowDataChanged();}void DX9Texture::getData( float* outData, unsigned int inStride, unsigned int inCount, unsigned int inRank, const unsigned int* inDomainMin, const unsigned int* inDomainMax, const unsigned int* inExtents, bool inUsesAddressTranslation ){ DX9PROFILE("DX9Texture::getData") if( dirtyFlags & kShadowDataDirty ) flushCachedToShadow(); getShadowData( outData, inStride, inCount, inRank, inDomainMin, inDomainMax, inExtents, inUsesAddressTranslation );}void DX9Texture::markCachedDataChanged(){ dirtyFlags = kShadowDataDirty;}void DX9Texture::markShadowDataChanged(){ dirtyFlags = kCachedDataDirty;}void DX9Texture::validateCachedData(){ if( !(dirtyFlags & kCachedDataDirty) ) return; flushShadowToCached();}void DX9Texture::validateShadowData(){ if( !(dirtyFlags & kShadowDataDirty) ) return; flushCachedToShadow();}void DX9Texture::flushCachedToShadow(){ DX9PROFILE("DX9Texture::flushCachedToShadow") HRESULT result = device->GetRenderTargetData( surfaceHandle, shadowSurface ); DX9AssertResult( result, "Failed to copy floating-point render target to plain surface." ); dirtyFlags &= ~kShadowDataDirty;}void DX9Texture::flushShadowToCached(){ DX9PROFILE("DX9Texture::flushShadowToCached") HRESULT result = device->UpdateSurface( shadowSurface, NULL, surfaceHandle, NULL ); DX9AssertResult( result, "Failed to copy floating-point plain surface to render target." ); dirtyFlags &= ~kCachedDataDirty;}void DX9Texture::getShadowData( void* outData, unsigned int inStride, unsigned int inCount, unsigned int inRank, const unsigned int* inDomainMin, const unsigned int* inDomainMax, const unsigned int* inExtents, bool inUsesAddressTranslation ){ DX9PROFILE("DX9Texture::getShadowData") if( !inUsesAddressTranslation ) {
HRESULT result; RECT rectToLock; bool isWholeBuffer; findRectForCopy( inRank, inDomainMin, inDomainMax, inExtents, inUsesAddressTranslation, rectToLock, isWholeBuffer ); int domainWidth = rectToLock.right - rectToLock.left;
int domainHeight = rectToLock.bottom - rectToLock.top;
D3DLOCKED_RECT info; result = shadowSurface->LockRect( &info, &rectToLock, D3DLOCK_READONLY ); DX9AssertResult( result, "LockRect failed" ); copyData( outData, domainWidth*inStride, inStride, info.pBits, info.Pitch, internalComponents*sizeof(float), domainWidth, domainHeight, components*sizeof(float) ); result = shadowSurface->UnlockRect(); DX9AssertResult( result, "UnlockRect failed" ); } else // using address translation {
HRESULT result; RECT rectToLock; bool isWholeBuffer; size_t baseX, baseY; findRectForCopyAT( inRank, inDomainMin, inDomainMax, inExtents, inUsesAddressTranslation, rectToLock, isWholeBuffer, width, height, baseX, baseY ); int rectWidth = rectToLock.right - rectToLock.left;
int rectHeight = rectToLock.bottom - rectToLock.top;
D3DLOCKED_RECT info; result = shadowSurface->LockRect( &info, &rectToLock, D3DLOCK_READONLY ); DX9AssertResult( result, "LockRect failed" ); if( isWholeBuffer ) {
copyAllDataAT( outData, width*inStride, inStride, info.pBits, info.Pitch, internalComponents*sizeof(float), width, height, components*sizeof(float), inRank, inExtents ); } else {
getDataAT( outData, inRank, inDomainMin, inDomainMax, inExtents, components*sizeof(float),
info.pBits, info.Pitch, rectWidth, rectHeight, internalComponents*sizeof(float), baseX, baseY ); } result = shadowSurface->UnlockRect(); DX9AssertResult( result, "UnlockRect failed" );
}}void DX9Texture::setShadowData( const void* inData, unsigned int inStride, unsigned int inCount, unsigned int inRank, const unsigned int* inDomainMin, const unsigned int* inDomainMax, const unsigned int* inExtents, bool inUsesAddressTranslation ){ DX9PROFILE("DX9Texture::setShadowData") if( !inUsesAddressTranslation ) { RECT rectToLock; bool isWholeBuffer; findRectForCopy( inRank, inDomainMin, inDomainMax, inExtents, inUsesAddressTranslation, rectToLock, isWholeBuffer ); int domainWidth = rectToLock.right - rectToLock.left;
int domainHeight = rectToLock.bottom - rectToLock.top;
if( !isWholeBuffer )
{
// we are only writing to a portion of the buffer,
// and so we must be sure to validate the rest of it
validateShadowData();
}
HRESULT result; D3DLOCKED_RECT info; result = shadowSurface->LockRect( &info, &rectToLock, 0 ); DX9AssertResult( result, "LockRect failed" ); copyData( info.pBits, info.Pitch, internalComponents*sizeof(float), inData, domainWidth*inStride, inStride, domainWidth, domainHeight, components*sizeof(float) ); result = shadowSurface->UnlockRect(); DX9AssertResult( result, "UnlockRect failed" ); } else // using address translation {
RECT rectToLock; bool isWholeBuffer; size_t baseX, baseY; findRectForCopyAT( inRank, inDomainMin, inDomainMax, inExtents, inUsesAddressTranslation, rectToLock, isWholeBuffer, width, height, baseX, baseY ); int rectWidth = rectToLock.right - rectToLock.left;
int rectHeight = rectToLock.bottom - rectToLock.top;
if( !isWholeBuffer )
{
// we are only writing to a portion of the buffer,
// and so we must be sure to validate the rest of it
validateShadowData();
}
HRESULT result; D3DLOCKED_RECT info; result = shadowSurface->LockRect( &info, &rectToLock, 0 ); DX9AssertResult( result, "LockRect failed" ); if( isWholeBuffer ) {
copyAllDataAT( info.pBits, info.Pitch, internalComponents*sizeof(float),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -