GBitmap *AtlasTexChunk::loadDDSIntoGBitmap(const U8 *ddsBuffer, U32 ddsBufferSize)
{
    D3DXIMAGE_INFO info;
    D3D9Assert(GFXD3DX.D3DXGetImageInfoFromFileInMemory(ddsBuffer, ddsBufferSize, &info),
               "AtlasTexChunk::loadDDSIntoGBitmap - failed to get image info.");

    IDirect3DSurface9 *surf = NULL;
    D3D9Assert(((GFXD3D9Device*)GFX)->getDevice()->CreateOffscreenPlainSurface(
                   info.Width, info.Height, info.Format, D3DPOOL_SCRATCH, &surf, NULL),
               "AtlasTexChunk::loadDDSIntoGBitmap - failed to allocate scratch surface.");

    // We want JPEGs, let's convert it in a klunky way...
    D3D9Assert(GFXD3DX.D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL,
               ddsBuffer, ddsBufferSize, NULL,
               D3DX_DEFAULT, 0, NULL),
               "AtlasTexChunk::loadDDSIntoGBitmap - D3DX failed to load from buffer.");

    ID3DXBuffer *buff = NULL;
    D3D9Assert(GFXD3DX.D3DXSaveSurfaceToFileInMemory(&buff, D3DXIFF_PNG, surf, NULL, NULL),
               "AtlasTexChunk::loadDDSIntoGBitmap - D3DX failed to save back to buffer.");
    MemStream ms(buff->GetBufferSize(), buff->GetBufferPointer(), true, false);

    GBitmap *bitmap = new GBitmap[1];
    bitmap->readBitmap( "png", ms );

    // Cleanup!
    buff->Release();
    surf->Release();

    return bitmap;
}
Example #2
0
void GFXD3D9Device::reacquireDefaultPoolResources() 
{
   // Now do the dynamic index buffers
   if( mDynamicPB == NULL )
      mDynamicPB = new GFXD3D9PrimitiveBuffer(this, 0, 0, GFXBufferTypeDynamic);

   D3D9Assert( mD3DDevice->CreateIndexBuffer( sizeof( U16 ) * MAX_DYNAMIC_INDICES, 
#ifdef TORQUE_OS_XENON
      D3DUSAGE_WRITEONLY,
#else
      D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
#endif
      GFXD3D9IndexFormat[GFXIndexFormat16], D3DPOOL_DEFAULT, &mDynamicPB->ib, NULL ), "Failed to allocate dynamic IB" );

   // Grab the depth-stencil...
   SAFE_RELEASE(mDeviceDepthStencil);   
   D3D9Assert(mD3DDevice->GetDepthStencilSurface(&mDeviceDepthStencil), 
      "GFXD3D9Device::reacquireDefaultPoolResources - couldn't grab reference to device's depth-stencil surface.");  

   SAFE_RELEASE(mDeviceBackbuffer);
   mD3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &mDeviceBackbuffer );

   // Walk the resource list and zombify everything.
   GFXResource *walk = mResourceListHead;
   while(walk)
   {
      walk->resurrect();
      walk = walk->getNextResource();
   }

   if(mTextureManager)
      mTextureManager->resurrect();
}
Example #3
0
void GFXPCD3D9WindowTarget::createAdditionalSwapChain()
{
   AssertFatal(!mImplicit, "Invalid swap chain type!  Implicit swap chains use the device");

   // Since we're not going to do a device reset for an additional swap
   // chain, we can just release our resources and regrab them.
   SAFE_RELEASE(mSwapChain);
   SAFE_RELEASE(mDepthStencil);
   SAFE_RELEASE(mBackbuffer);

   // If there's a fullscreen window active, don't try to create these additional swap chains.
   // CodeReview, we need to store the window target with the implicit swap chain better, this line below 
   // could fail if the current render target isn't what we expect.
   GFXPCD3D9WindowTarget* currTarget = dynamic_cast<GFXPCD3D9WindowTarget*>(mDevice->getActiveRenderTarget());
   if (currTarget && currTarget->getWindow()->getVideoMode().fullScreen)
      return;

   // Setup our presentation params.
   initPresentationParams();

   // Create our resources!
   D3D9Assert(mDevice->getDevice()->CreateAdditionalSwapChain(&mPresentationParams, &mSwapChain),
      "GFXPCD3D9WindowTarget::createAdditionalSwapChain - couldn't reallocate additional swap chain!");
   D3D9Assert(mDevice->getDevice()->CreateDepthStencilSurface(mPresentationParams.BackBufferWidth, mPresentationParams.BackBufferHeight,
      D3DFMT_D24S8, mPresentationParams.MultiSampleType, mPresentationParams.MultiSampleQuality, false, &mDepthStencil, NULL), 
      "GFXPCD3D9WindowTarget::createAdditionalSwapChain: Unable to create stencil/depth surface");
   D3D9Assert(mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackbuffer),
      "GFXPCD3D9WindowTarget::createAdditionalSwapChain: Unable to get backbuffer!");   
}
//-----------------------------------------------------------------------------
// unLock
//-----------------------------------------------------------------------------
void GFXD3D9TextureObject::unlock(U32 mipLevel)
{
   AssertFatal( mLocked, "GFXD3D9TextureObject::unlock - Attempting to unlock a surface that has not been locked" );

#ifndef TORQUE_OS_XENON
   if( mProfile->isRenderTarget() )
   {
      IDirect3DSurface9 *dest;
      GFXD3D9TextureObject *to = (GFXD3D9TextureObject *) &(*mLockTex);
      D3D9Assert( to->get2DTex()->GetSurfaceLevel( 0, &dest ), NULL );

      dest->UnlockRect();
      dest->Release();

      mLocked = false;
   }
   else
#endif
   {
      D3D9Assert( get2DTex()->UnlockRect(mipLevel), 
         "GFXD3D9TextureObject::unlock - could not unlock non-RT texture." );

      mLocked = false;
   }
}
Example #5
0
void GFXD3D9Device::setVB( GFXVertexBuffer *buffer ) 
{
   AssertFatal( mCurrentOpenAllocVB == NULL, "Calling setVertexBuffer() when a vertex buffer is still open for editing" );

   mCurrentVB = static_cast<GFXD3D9VertexBuffer *>( buffer );

   D3D9Assert( mD3DDevice->SetVertexDeclaration( mCurrentVB->decl ), "Failed to set vertex declaration" );
   D3D9Assert( mD3DDevice->SetStreamSource( 0, mCurrentVB->vb, 0, mCurrentVB->mVertexSize ), "Failed to set stream source" );
}
Example #6
0
//-----------------------------------------------------------------------------
// This function should ONLY be called from GFXDevice::updateStates() !!!
//-----------------------------------------------------------------------------
void GFXD3D9Device::setTextureInternal( U32 textureUnit, const GFXTextureObject *texture)
{
   if( texture == NULL )
   {
      D3D9Assert(mD3DDevice->SetTexture( textureUnit, NULL ), "Failed to set texture to null!");
      return;
   }

   GFXD3D9TextureObject *tex = (GFXD3D9TextureObject *) texture;
   D3D9Assert(mD3DDevice->SetTexture( textureUnit, tex->getTex()), "Failed to set texture to valid value!");
}
Example #7
0
void GFXPCD3D9WindowTarget::resolveTo( GFXTextureObject *tex )
{
   GFXDEBUGEVENT_SCOPE( GFXPCD3D9WindowTarget_resolveTo, ColorI::RED );

   IDirect3DSurface9 *surf;
   D3D9Assert( ((GFXD3D9TextureObject*)(tex))->get2DTex()->GetSurfaceLevel( 0, &surf ),
      "GFXPCD3D9WindowTarget::resolveTo() - GetSurfaceLevel failed!" );

   D3D9Assert( mDevice->getDevice()->StretchRect( mBackbuffer, NULL, surf, NULL, D3DTEXF_NONE ),
      "GFXPCD3D9WindowTarget::resolveTo() - StretchRect failed!" );

   surf->Release();    
}
Example #8
0
void GFXPCD3D9WindowTarget::activate()
{
   GFXDEBUGEVENT_SCOPE( GFXPCD3D9WindowTarget_activate, ColorI::RED );

   LPDIRECT3DDEVICE9 d3dDevice = mDevice->getDevice();
   
   // In debug lets do a complete test to be sure we don't
   // have a bad depth format for this display mode.   
   #ifdef TORQUE_DEBUG
      if ( mDepthStencil && mBackbuffer )
      {

         D3DSURFACE_DESC desc;
         D3D9Assert( mBackbuffer->GetDesc( &desc ), 
            "GFXPCD3D9TextureTarget::activate() - Failed to get surface description!");
         D3DFORMAT renderFormat = desc.Format;

         D3D9Assert( mDepthStencil->GetDesc( &desc ), 
            "GFXPCD3D9TextureTarget::activate() - Failed to get surface description!");
         D3DFORMAT depthFormat = desc.Format;

         HRESULT hr = mDevice->getD3D()->CheckDepthStencilMatch(  mDevice->getAdaterIndex(),
                                                                  D3DDEVTYPE_HAL,
                                                                  mDevice->mDisplayMode.Format,
                                                                  renderFormat,
                                                                  depthFormat );

         D3D9Assert( hr, "GFXPCD3D9WindowTarget::activate() - Bad depth format for this back buffer!" );
      }
   #endif
   
   D3D9Assert( d3dDevice->SetRenderTarget( 0, mBackbuffer ), 
      "GFXPCD3D9WindowTarget::activate() - Failed to set backbuffer target!" );

   D3D9Assert( d3dDevice->SetDepthStencilSurface( mDepthStencil ), 
      "GFXPCD3D9WindowTarget::activate() - Failed to set depthstencil target!" );

   D3DPRESENT_PARAMETERS pp;

   mSwapChain->GetPresentParameters(&pp);

   // Update our video mode here, too.
   GFXVideoMode vm;
   vm = mWindow->getVideoMode();
   vm.resolution.x = pp.BackBufferWidth;
   vm.resolution.y = pp.BackBufferHeight;
   vm.fullScreen = !pp.Windowed;

   mSize = vm.resolution;
}
void GFXD3D9CardProfiler::init()
{
   mD3DDevice = dynamic_cast<GFXD3D9Device *>(GFX)->getDevice();
   AssertISV( mD3DDevice, "GFXD3D9CardProfiler::init() - No D3D9 Device found!");

   // Grab the caps so we can get our adapter ordinal and look up our name.
   D3DCAPS9 caps;
   D3D9Assert(mD3DDevice->GetDeviceCaps(&caps), "GFXD3D9CardProfiler::init - failed to get device caps!");

#ifdef TORQUE_OS_XENON
   mCardDescription = "Xbox360 GPU";
   mChipSet = "ATI";
   mVersionString = String::ToString(_XDK_VER);
   mVideoMemory = 512 * 1024 * 1024;
#else
   WMIVideoInfo wmiVidInfo;
   if( wmiVidInfo.profileAdapters() )
   {
      const PlatformVideoInfo::PVIAdapter &adapter = wmiVidInfo.getAdapterInformation( caps.AdapterOrdinal );

      mCardDescription = adapter.description;
      mChipSet = adapter.chipSet;
      mVersionString = adapter.driverVersion;
      mVideoMemory = adapter.vram;
   }
#endif

   Parent::init();
}
Example #10
0
//-----------------------------------------------------------------------------
GFXD3D9VertexBuffer * GFXD3D9Device::createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize )
{
   // this is a bit funky, but it will avoid problems with (lack of) copy constructors
   //    with a push_back() situation
   mVolatileVBList.increment();
   StrongRefPtr<GFXD3D9VertexBuffer> newBuff;
   mVolatileVBList.last() = new GFXD3D9VertexBuffer();
   newBuff = mVolatileVBList.last();

   newBuff->mNumVerts   = 0;
   newBuff->mBufferType = GFXBufferTypeVolatile;
   newBuff->mVertexFormat = vertexFormat;
   newBuff->mVertexSize = vertSize;
   newBuff->mDevice = this;

   allocVertexDecl( newBuff );

   //   Con::printf("Created buff with type %x", vertFlags);

   D3D9Assert( mD3DDevice->CreateVertexBuffer( vertSize * MAX_DYNAMIC_VERTS, 
#ifdef TORQUE_OS_XENON
      D3DUSAGE_WRITEONLY,
#else
      D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
#endif
      0, 
      D3DPOOL_DEFAULT, 
      &newBuff->vb, 
      NULL ), 
      "Failed to allocate dynamic VB" );
   return newBuff;
}
void GFXD3D9Device::setVertexDecl( const GFXVertexDecl *decl )
{
   IDirect3DVertexDeclaration9 *dx9Decl = NULL;
   if ( decl )
      dx9Decl = static_cast<const D3D9VertexDecl*>( decl )->decl;
   D3D9Assert( mD3DDevice->SetVertexDeclaration( dx9Decl ), "GFXD3D9Device::setVertexDecl - Failed to set vertex declaration." );
}
void GFXD3D9Device::drawIndexedPrimitive( GFXPrimitiveType primType, 
                                          U32 startVertex, 
                                          U32 minIndex, 
                                          U32 numVerts, 
                                          U32 startIndex, 
                                          U32 primitiveCount ) 
{
   // This is done to avoid the function call overhead if possible
   if( mStateDirty )
      updateStates();
   if (mCurrentShaderConstBuffer)
      setShaderConstBufferInternal(mCurrentShaderConstBuffer);

   AssertFatal( mCurrentPB != NULL, "Trying to call drawIndexedPrimitive with no current index buffer, call setIndexBuffer()" );

   if ( mVolatileVB )
      startVertex += mVolatileVB->mVolatileStart;

   D3D9Assert( mD3DDevice->DrawIndexedPrimitive(   GFXD3D9PrimType[primType], 
      startVertex, 
      /* mCurrentPB->mVolatileStart + */ minIndex,
      numVerts, 
      mCurrentPB->mVolatileStart + startIndex, 
      primitiveCount ), "Failed to draw indexed primitive" );

   mDeviceStatistics.mDrawCalls++;
   if ( mVertexBufferFrequency[0] > 1 )
      mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
   else
      mDeviceStatistics.mPolyCount += primitiveCount;
}
Example #13
0
void GFXD3D9Device::drawIndexedPrimitive( GFXPrimitiveType primType, 
                                         U32 startVertex, 
                                         U32 minIndex, 
                                         U32 numVerts, 
                                         U32 startIndex, 
                                         U32 primitiveCount ) 
{
   // This is done to avoid the function call overhead if possible
   if( mStateDirty )
      updateStates();
   if (mCurrentShaderConstBuffer)
      setShaderConstBufferInternal(mCurrentShaderConstBuffer);

   AssertFatal( mCurrentOpenAllocVB == NULL, "Calling drawIndexedPrimitive() when a vertex buffer is still open for editing" );
   AssertFatal( mCurrentVB != NULL, "Trying to call drawIndexedPrimitive with no current vertex buffer, call setVertexBuffer()" );

   AssertFatal( mCurrentOpenAllocPB == NULL, "Calling drawIndexedPrimitive() when a index buffer is still open for editing" );
   AssertFatal( mCurrentPB != NULL, "Trying to call drawIndexedPrimitive with no current index buffer, call setIndexBuffer()" );

   D3D9Assert( mD3DDevice->DrawIndexedPrimitive(   GFXD3D9PrimType[primType], 
      mCurrentVB->mVolatileStart + startVertex, 
      /* mCurrentPB->mVolatileStart + */ minIndex,
      numVerts, 
      mCurrentPB->mVolatileStart + startIndex, 
      primitiveCount ), "Failed to draw indexed primitive" );

   mDeviceStatistics.mDrawCalls++;
   mDeviceStatistics.mPolyCount += primitiveCount;
}
void GFXD3D9Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
{
   GFXD3D9VertexBuffer *d3dBuffer = static_cast<GFXD3D9VertexBuffer*>( buffer );

   if ( stream == 0 )
   {
      // Set the volatile buffer which is used to 
      // offset the start index when doing draw calls.
      if ( d3dBuffer && d3dBuffer->mVolatileStart > 0 )
         mVolatileVB = d3dBuffer;
      else
         mVolatileVB = NULL;
   }

   // NOTE: We do not use the stream offset here for stream 0
   // as that feature is *supposedly* not as well supported as 
   // using the start index in drawPrimitive.
   //
   // If we can verify that this is not the case then we should
   // start using this method exclusively for all streams.
   
   D3D9Assert( mD3DDevice->SetStreamSource(  stream, 
                                             d3dBuffer ? d3dBuffer->vb : NULL,
                                             d3dBuffer && stream != 0 ? d3dBuffer->mVolatileStart * d3dBuffer->mVertexSize : 0, 
                                             d3dBuffer ? d3dBuffer->mVertexSize : 0 ),
                                             "GFXD3D9Device::setVertexStream - Failed to set stream source." );
}
Example #15
0
bool GFXD3D9Device::beginSceneInternal() 
{
   HRESULT hr = mD3DDevice->BeginScene();
   D3D9Assert(hr, "GFXD3D9Device::beginSceneInternal - failed to BeginScene");
   mCanCurrentlyRender = SUCCEEDED(hr);
   return mCanCurrentlyRender;      
}
Example #16
0
void GFXD3D9Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer ) 
{
   AssertFatal( mCurrentOpenAllocPB == NULL, "Calling setIndexBuffer() when a index buffer is still open for editing" );

   mCurrentPB = static_cast<GFXD3D9PrimitiveBuffer *>( buffer );

   D3D9Assert( mD3DDevice->SetIndices( mCurrentPB->ib ), "Failed to set indices" );
}
Example #17
0
//-----------------------------------------------------------------------------
// allocVertexBuffer
//-----------------------------------------------------------------------------
GFXVertexBuffer * GFXD3D9Device::allocVertexBuffer(   U32 numVerts, 
                                                   const GFXVertexFormat *vertexFormat, 
                                                   U32 vertSize, 
                                                   GFXBufferType bufferType )
{
   GFXD3D9VertexBuffer *res = new GFXD3D9VertexBuffer( this, numVerts, vertexFormat, vertSize, bufferType );

   // Determine usage flags
   U32 usage = 0;
   D3DPOOL pool = D3DPOOL_DEFAULT;

   res->mNumVerts = 0;

   // Assumptions:
   //    - static buffers are write once, use many
   //    - dynamic buffers are write many, use many
   //    - volatile buffers are write once, use once
   // You may never read from a buffer.
   switch(bufferType)
   {
   case GFXBufferTypeStatic:
      pool = D3DPOOL_MANAGED;
      res->registerResourceWithDevice(this);
      break;

   case GFXBufferTypeDynamic:
   case GFXBufferTypeVolatile:
      pool = D3DPOOL_DEFAULT;
      res->registerResourceWithDevice(this);
      usage |= D3DUSAGE_WRITEONLY;
#ifndef TORQUE_OS_XENON
      usage |= D3DUSAGE_DYNAMIC;
#endif
      break;
   }

   // Create vertex buffer
   if(bufferType == GFXBufferTypeVolatile)
   {
      // Get volatile stuff from a pool...
      AssertFatal( numVerts <= MAX_DYNAMIC_VERTS, "Cannot allocate that many verts in a volatile vertex buffer, increase MAX_DYNAMIC_VERTS! -- BJG" );

      // This is all we need here, everything else lives in the lock method on the 
      // buffer... -- BJG

   }
   else
   {
      allocVertexDecl( res );

      // Get a new buffer...
      D3D9Assert( mD3DDevice->CreateVertexBuffer( vertSize * numVerts, usage, 0, pool, &res->vb, NULL ), 
         "Failed to allocate VB" );
   }

   res->mNumVerts = numVerts;
   return res;
}
Example #18
0
//-----------------------------------------------------------------------------
// Reset D3D device
//-----------------------------------------------------------------------------
void GFXPCD3D9Device::reset( D3DPRESENT_PARAMETERS &d3dpp )
{
   if(!mD3DDevice)
      return;

   mInitialized = false;

   mMultisampleType = d3dpp.MultiSampleType;
   mMultisampleLevel = d3dpp.MultiSampleQuality;
   _validateMultisampleParams(d3dpp.BackBufferFormat, mMultisampleType, mMultisampleLevel);

   // Clean up some commonly dangling state. This helps prevents issues with
   // items that are destroyed by the texture manager callbacks and recreated
   // later, but still left bound.
   setVertexBuffer(NULL);
   setPrimitiveBuffer(NULL);
   for(S32 i=0; i<getNumSamplers(); i++)
      setTexture(i, NULL);

   // Deal with the depth/stencil buffer.
   if(mDeviceDepthStencil)
   {
      Con::printf("GFXPCD3D9Device::reset - depthstencil %x has %d ref's", mDeviceDepthStencil, mDeviceDepthStencil->AddRef()-1);
      mDeviceDepthStencil->Release();
   }

   // First release all the stuff we allocated from D3DPOOL_DEFAULT
   releaseDefaultPoolResources();

   // reset device
   Con::printf( "--- Resetting D3D Device ---" );
   HRESULT hres = S_OK;
   hres = mD3DDevice->Reset( &d3dpp );

   if( FAILED( hres ) )
   {
      while( mD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST )
      {
         Sleep( 100 );
      }

      hres = mD3DDevice->Reset( &d3dpp );
   }

   D3D9Assert( hres, "GFXD3D9Device::reset - Failed to create D3D Device!" );
   mInitialized = true;

   // Setup default states
   initStates();

   // Now re aquire all the resources we trashed earlier
   reacquireDefaultPoolResources();

   // Mark everything dirty and flush to card, for sanity.
   updateStates(true);
}
//-----------------------------------------------------------------------------
// allocPrimitiveBuffer
//-----------------------------------------------------------------------------
GFXPrimitiveBuffer * GFXD3D9Device::allocPrimitiveBuffer(   U32 numIndices, 
                                                            U32 numPrimitives, 
                                                            GFXBufferType bufferType )
{
   // Allocate a buffer to return
   GFXD3D9PrimitiveBuffer * res = new GFXD3D9PrimitiveBuffer(this, numIndices, numPrimitives, bufferType);

   // Determine usage flags
   U32 usage = 0;
   D3DPOOL pool = D3DPOOL_DEFAULT;

   // Assumptions:
   //    - static buffers are write once, use many
   //    - dynamic buffers are write many, use many
   //    - volatile buffers are write once, use once
   // You may never read from a buffer.
   switch(bufferType)
   {
   case GFXBufferTypeStatic:
      pool = isD3D9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
      break;

   case GFXBufferTypeDynamic:
   case GFXBufferTypeVolatile:
#ifndef TORQUE_OS_XENON
      usage |= D3DUSAGE_DYNAMIC;
#endif
      break;
   }

   // Register resource
   res->registerResourceWithDevice(this);

   // We never allow reading from a primitive buffer.
   usage |= D3DUSAGE_WRITEONLY;

   // Create d3d index buffer
   if(bufferType == GFXBufferTypeVolatile)
   {
      // Get it from the pool if it's a volatile...
      AssertFatal( numIndices < MAX_DYNAMIC_INDICES, "Cannot allocate that many indices in a volatile buffer, increase MAX_DYNAMIC_INDICES." );

      res->ib              = mDynamicPB->ib;
      // mDynamicPB->ib->AddRef();
      res->mVolatileBuffer = mDynamicPB;
   }
   else
   {
      // Otherwise, get it as a seperate buffer...
      D3D9Assert(mD3DDevice->CreateIndexBuffer( sizeof(U16) * numIndices , usage, GFXD3D9IndexFormat[GFXIndexFormat16], pool, &res->ib, 0),
         "Failed to allocate an index buffer.");
   }

   return res;
}
Example #20
0
void GFXPCD3D9TextureTarget::resolve()
{
   GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_resolve, ColorI::RED );

   for (U32 i = 0; i < MaxRenderSlotId; i++)
   {
      // We use existance @ mResolveTargets as a flag that we need to copy
      // data from the rendertarget into the texture.
      if (mResolveTargets[i])
      {
         IDirect3DSurface9 *surf;
         D3D9Assert( mResolveTargets[i]->get2DTex()->GetSurfaceLevel( 0, &surf ),
            "GFXPCD3D9TextureTarget::resolve() - GetSurfaceLevel failed!" );

         D3D9Assert( mDevice->getDevice()->StretchRect( mTargets[i], NULL, surf, NULL, D3DTEXF_NONE ),
            "GFXPCD3D9TextureTarget::resolve() - StretchRect failed!" );

         surf->Release();
      }
   }
}
Example #21
0
void GFXPCD3D9TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ )
{
   GFXDEBUGEVENT_SCOPE( GFXPCD3D9TextureTarget_attachTexture_Cubemap, ColorI::RED );

   AssertFatal(slot < MaxRenderSlotId, "GFXPCD3D9TextureTarget::attachTexture - out of range slot.");

   // Mark state as dirty so device can know to update.
   invalidateState();

   // Release what we had, it's definitely going to change.
   mDevice->destroyD3DResource( mTargets[slot] ); // SAFE_RELEASE
   mTargets[slot] = NULL;
   mResolveTargets[slot] = NULL;

   // Cast the texture object to D3D...
   AssertFatal(!tex || dynamic_cast<GFXD3D9Cubemap*>(tex), 
      "GFXD3DTextureTarget::attachTexture - invalid cubemap object.");

   GFXD3D9Cubemap *cube = static_cast<GFXD3D9Cubemap*>(tex);

   if(slot == Color0)
   {
      mTargetSize = Point2I::Zero;
      mTargetFormat = GFXFormatR8G8B8A8;
   }

   // Are we clearing?
   if(!tex)
   {
      // Yup - just exit, it'll stay NULL.      
      return;
   }

   D3D9Assert(cube->mCubeTex->GetCubeMapSurface( (D3DCUBEMAP_FACES)face, mipLevel, &mTargets[slot] ),
      "GFXD3DTextureTarget::attachTexture - could not get surface level for the passed texture!");

   // Update surface size
   if(slot == Color0)
   {
      IDirect3DSurface9 *surface = mTargets[Color0];
      if ( surface )
      {
         D3DSURFACE_DESC sd;
         surface->GetDesc(&sd);
         mTargetSize = Point2I(sd.Width, sd.Height);

         S32 format = sd.Format;
         GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, format );
         mTargetFormat = (GFXFormat)format;
      }
   }
}
void GFXD3D9PrimitiveBuffer::lock(U16 indexStart, U16 indexEnd, U16 **indexPtr)
{
   AssertFatal(!mLocked, "GFXD3D9PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
   mLocked = true;
   U32 flags=0;
   switch(mBufferType)
   {
   case GFXBufferTypeStatic:
      // flags |= D3DLOCK_DISCARD;
      break;

   case GFXBufferTypeDynamic:
      // Always discard the content within a locked region.
      flags |= D3DLOCK_DISCARD;
      break;

   case GFXBufferTypeVolatile:
      // Get our range now...
      AssertFatal(indexStart == 0,                "Cannot get a subrange on a volatile buffer.");
      AssertFatal(indexEnd < MAX_DYNAMIC_INDICES, "Cannot get more than MAX_DYNAMIC_INDICES in a volatile buffer. Up the constant!");

      // Get the primtive buffer
      mVolatileBuffer = ((GFXD3D9Device*)mDevice)->mDynamicPB;

      AssertFatal( mVolatileBuffer, "GFXD3D9PrimitiveBuffer::lock - No dynamic primitive buffer was available!");

      // We created the pool when we requested this volatile buffer, so assume it exists...
      if( mVolatileBuffer->mIndexCount + indexEnd > MAX_DYNAMIC_INDICES ) 
      {
         flags |= D3DLOCK_DISCARD;
         mVolatileStart = indexStart  = 0;
         indexEnd       = indexEnd;
      }
      else 
      {
         flags |= D3DLOCK_NOOVERWRITE;
         mVolatileStart = indexStart  = mVolatileBuffer->mIndexCount;
         indexEnd                    += mVolatileBuffer->mIndexCount;
      }

      mVolatileBuffer->mIndexCount = indexEnd + 1;
      ib = mVolatileBuffer->ib;

      break;
   }

   D3D9Assert( ib->Lock(indexStart * sizeof(U16), (indexEnd - indexStart) * sizeof(U16), (void**)indexPtr, flags),
      "GFXD3D9PrimitiveBuffer::lock - Could not lock primitive buffer.");

}
void GFXD3D9Device::setVertexStreamFrequency( U32 stream, U32 frequency )
{
   if ( frequency == 0 )
      frequency = 1;
   else
   {
      if ( stream == 0 )
         frequency = D3DSTREAMSOURCE_INDEXEDDATA | frequency;
      else
         frequency = D3DSTREAMSOURCE_INSTANCEDATA | frequency;
   }

   D3D9Assert( mD3DDevice->SetStreamSourceFreq( stream, frequency ),
      "GFXD3D9Device::setVertexStreamFrequency - Failed to set stream frequency." );
}
void GFXD3D9Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount ) 
{
   // This is done to avoid the function call overhead if possible
   if( mStateDirty )
      updateStates();
   if (mCurrentShaderConstBuffer)
      setShaderConstBufferInternal(mCurrentShaderConstBuffer);

   if ( mVolatileVB )
      vertexStart += mVolatileVB->mVolatileStart;

   D3D9Assert( mD3DDevice->DrawPrimitive( GFXD3D9PrimType[primType], vertexStart, primitiveCount ), "Failed to draw primitives" );  

   mDeviceStatistics.mDrawCalls++;
   if ( mVertexBufferFrequency[0] > 1 )
      mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
   else
      mDeviceStatistics.mPolyCount += primitiveCount;
}
Example #25
0
GFXFormat GFXPCD3D9Device::selectSupportedFormat(GFXTextureProfile *profile,
		const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter)
{
	DWORD usage = 0;

	if(profile->isDynamic())
		usage |= D3DUSAGE_DYNAMIC;

	if(profile->isRenderTarget())
		usage |= D3DUSAGE_RENDERTARGET;

	if(profile->isZTarget())
		usage |= D3DUSAGE_DEPTHSTENCIL;

	if(mustblend)
		usage |= D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;

   if(mustfilter)
		usage |= D3DUSAGE_QUERY_FILTER;

	D3DDISPLAYMODE mode;
	D3D9Assert(mD3D->GetAdapterDisplayMode(mAdapterIndex, &mode), "Unable to get adapter mode.");

	D3DRESOURCETYPE type;
	if(texture)
		type = D3DRTYPE_TEXTURE;
	else
		type = D3DRTYPE_SURFACE;

	for(U32 i=0; i<formats.size(); i++)
	{
		if(mD3D->CheckDeviceFormat(mAdapterIndex, D3DDEVTYPE_HAL, mode.Format,
			usage, type, GFXD3D9TextureFormat[formats[i]]) == D3D_OK)
			return formats[i];
	}

	return GFXFormatR8G8B8A8;
}
Example #26
0
void GFXD3D9Device::_updateRenderTargets()
{
   if ( mRTDirty || ( mCurrentRT && mCurrentRT->isPendingState() ) )
   {
      if ( mRTDeactivate )
      {
         mRTDeactivate->deactivate();
         mRTDeactivate = NULL;   
      }

      // NOTE: The render target changes are not really accurate
      // as the GFXTextureTarget supports MRT internally.  So when
      // we activate a GFXTarget it could result in multiple calls
      // to SetRenderTarget on the actual device.
      mDeviceStatistics.mRenderTargetChanges++;

      mCurrentRT->activate();

      mRTDirty = false;
   }  

   if ( mViewportDirty )
   {
      D3DVIEWPORT9 viewport;
      viewport.X       = mViewport.point.x;
      viewport.Y       = mViewport.point.y;
      viewport.Width   = mViewport.extent.x;
      viewport.Height  = mViewport.extent.y;
      viewport.MinZ    = 0.0;
      viewport.MaxZ    = 1.0;

      D3D9Assert( mD3DDevice->SetViewport( &viewport ), 
         "GFXD3D9Device::_updateRenderTargets() - Error setting viewport!" );

      mViewportDirty = false;
   }
}
/// Load a texture from a proper DDSFile instance.
bool GFXD3D9TextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
{
   PROFILE_SCOPE(GFXD3D9TextureManager_loadTextureDDS);

   GFXD3D9TextureObject *texture = static_cast<GFXD3D9TextureObject*>(aTexture);

   // Fill the texture...
   for( int i = 0; i < aTexture->mMipLevels; i++ )
   {
      PROFILE_SCOPE(GFXD3DTexMan_loadSurface);

      LPDIRECT3DSURFACE9 surf = NULL;
      D3D9Assert(texture->get2DTex()->GetSurfaceLevel( i, &surf ), "Failed to get surface");

#if defined(TORQUE_OS_XENON)
      XGTEXTURE_DESC surfDesc;
      dMemset(&surfDesc, 0, sizeof(XGTEXTURE_DESC));
      XGGetSurfaceDesc(surf, &surfDesc);

      RECT srcRect;
      srcRect.top = srcRect.left = 0;
      srcRect.bottom = dds->getHeight(i);
      srcRect.right = dds->getWidth(i);

      D3DXLoadSurfaceFromMemory(surf, NULL, NULL, dds->mSurfaces[0]->mMips[i],
         (D3DFORMAT)MAKELINFMT(GFXD3D9TextureFormat[dds->mFormat]), dds->getSurfacePitch(i), 
         NULL, &srcRect, false, 0, 0, D3DX_FILTER_NONE, 0);
#else

      GFXD3D9Device* dev = static_cast<GFXD3D9Device *>(GFX);

      if (dev->isD3D9Ex())
      {
         RECT r;
         r.top = r.left = 0;
         r.bottom = dds->getHeight(i);
         r.right = dds->getWidth(i);
         D3DXLoadSurfaceFromMemory(surf, NULL, NULL, dds->mSurfaces[0]->mMips[i], GFXD3D9TextureFormat[dds->mFormat], dds->getSurfacePitch(i), NULL, &r, D3DX_DEFAULT, 0);
      }
      else
      {
         D3DLOCKED_RECT lockedRect;
         D3D9Assert( surf->LockRect( &lockedRect, NULL, 0 ), "Failed to lock surface level for load" );

         AssertFatal( dds->mSurfaces.size() > 0, "Assumption failed. DDSFile has no surfaces." );

         if ( dds->getSurfacePitch( i ) != lockedRect.Pitch )
         {
            // Do a row-by-row copy.
            U32 srcPitch = dds->getSurfacePitch( i );
            U32 srcHeight = dds->getHeight();
            U8* srcBytes = dds->mSurfaces[0]->mMips[i];
            U8* dstBytes = (U8*)lockedRect.pBits;
            for (U32 i = 0; i<srcHeight; i++)          
            {
               dMemcpy( dstBytes, srcBytes, srcPitch );
               dstBytes += lockedRect.Pitch;
               srcBytes += srcPitch;
            }           
            surf->UnlockRect();
            surf->Release();

            return true;
         }

         dMemcpy( lockedRect.pBits, dds->mSurfaces[0]->mMips[i], dds->getSurfaceSize(i) );

         surf->UnlockRect();
      }
#endif

      surf->Release();
   }

   return true;
}
Example #28
0
void GFXD3D9Device::allocVertexDecl( GFXD3D9VertexBuffer *vertBuff )
{
   PROFILE_SCOPE( GFXD3D9Device_AllocVertexDecl );

   if ( vertBuff->decl )
      return;

   const GFXVertexFormat *vertexFormat = vertBuff->mVertexFormat;

   // First check the map... you shouldn't allocate VBs very often
   // if you want performance.  The map lookup should never become
   // a performance bottleneck.
   vertBuff->decl = mVertexDecls[vertexFormat->getDescription()];
   if ( vertBuff->decl )
      return;

   // Setup the declaration struct.
   U32 elemCount = vertexFormat->getElementCount();
   U32 offset = 0;
   D3DVERTEXELEMENT9 *vd = new D3DVERTEXELEMENT9[ elemCount + 1 ];
   for ( U32 i=0; i < elemCount; i++ )
   {
      const GFXVertexElement &element = vertexFormat->getElement( i );

      vd[i].Stream = 0;
      vd[i].Offset = offset;
      vd[i].Type = GFXD3D9DeclType[element.getType()];
      vd[i].Method = D3DDECLMETHOD_DEFAULT;

      // We force the usage index of 0 for everything but 
      // texture coords for now... this may change later.
      vd[i].UsageIndex = 0;

      if ( element.isSemantic( GFXSemantic::POSITION ) )
         vd[i].Usage = D3DDECLUSAGE_POSITION;
      else if ( element.isSemantic( GFXSemantic::NORMAL ) )
         vd[i].Usage = D3DDECLUSAGE_NORMAL;
      else if ( element.isSemantic( GFXSemantic::COLOR ) )
         vd[i].Usage = D3DDECLUSAGE_COLOR;
      else if ( element.isSemantic( GFXSemantic::TANGENT ) )
         vd[i].Usage = D3DDECLUSAGE_TANGENT;
      else if ( element.isSemantic( GFXSemantic::BINORMAL ) )
         vd[i].Usage = D3DDECLUSAGE_BINORMAL;
      else
      {
         // Anything that falls thru to here will be a texture coord.
         vd[i].Usage = D3DDECLUSAGE_TEXCOORD;
         vd[i].UsageIndex = element.getSemanticIndex();
      }

      offset += element.getSizeInBytes();
   }

   D3DVERTEXELEMENT9 declEnd = D3DDECL_END();
   vd[elemCount] = declEnd;

   D3D9Assert( mD3DDevice->CreateVertexDeclaration( vd, &vertBuff->decl ), 
      "GFXD3D9Device::allocVertexDecl - Failed to create vertex declaration!" );

   delete[] vd;

   // Store it in the cache.
   mVertexDecls[vertexFormat->getDescription()] = vertBuff->decl;
}
//-----------------------------------------------------------------------------
// loadTexture - raw
//-----------------------------------------------------------------------------
bool GFXD3D9TextureManager::_loadTexture( GFXTextureObject *inTex, void *raw )
{
   PROFILE_SCOPE(GFXD3D9TextureManager_loadTextureRaw);

   GFXD3D9TextureObject *texture = (GFXD3D9TextureObject *) inTex;

   // currently only for volume textures...
   if( texture->getDepth() < 1 ) return false;

   
   U32 bytesPerPix = 1;

   switch( texture->mFormat )
   {
      case GFXFormatR8G8B8:
         bytesPerPix = 3;
         break;
      case GFXFormatR8G8B8A8:
      case GFXFormatR8G8B8X8:
         bytesPerPix = 4;
         break;
   }

   U32 rowPitch = texture->getWidth() * bytesPerPix;
   U32 slicePitch = texture->getWidth() * texture->getHeight() * bytesPerPix;

   D3DBOX box;
   box.Left    = 0;
   box.Right   = texture->getWidth();
   box.Front   = 0;
   box.Back    = texture->getDepth();
   box.Top     = 0;
   box.Bottom  = texture->getHeight();


   LPDIRECT3DVOLUME9 volume = NULL;
   D3D9Assert( texture->get3DTex()->GetVolumeLevel( 0, &volume ), "Failed to load volume" );

#ifdef TORQUE_OS_XENON
   D3DLOCKED_BOX lockedBox;
   volume->LockBox( &lockedBox, &box, 0 );
   
   dMemcpy( lockedBox.pBits, raw, slicePitch * texture->getDepth() );

   volume->UnlockBox();
#else
   D3D9Assert(
      GFXD3DX.D3DXLoadVolumeFromMemory(
         volume,
         NULL,
         NULL,
         raw,
         GFXD3D9TextureFormat[texture->mFormat],
         rowPitch,
         slicePitch,
         NULL,
         &box,
#ifdef TORQUE_OS_XENON
         false, 0, 0, 0, // Unique to Xenon -pw
#endif
         D3DX_FILTER_NONE,
         0
      ),
      "Failed to load volume texture" 
   );
#endif

   volume->Release();


   return true;
}
//-----------------------------------------------------------------------------
// _innerCreateTexture
//-----------------------------------------------------------------------------
void GFXD3D9TextureManager::_innerCreateTexture( GFXD3D9TextureObject *retTex, 
                                               U32 height, 
                                               U32 width, 
                                               U32 depth,
                                               GFXFormat format, 
                                               GFXTextureProfile *profile, 
                                               U32 numMipLevels,
                                               bool forceMips,
                                               S32 antialiasLevel)
{
   GFXD3D9Device* d3d = static_cast<GFXD3D9Device*>(GFX);

   // Some relevant helper information...
   bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
   
   DWORD usage = 0;   // 0, D3DUSAGE_RENDERTARGET, or D3DUSAGE_DYNAMIC
   D3DPOOL pool = D3DPOOL_DEFAULT;

   retTex->mProfile = profile;

   D3DFORMAT d3dTextureFormat = GFXD3D9TextureFormat[format];

#ifndef TORQUE_OS_XENON
   if( retTex->mProfile->isDynamic() )
   {
      usage = D3DUSAGE_DYNAMIC;
   }
   else
   {
      usage = 0;
      pool = d3d->isD3D9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
   }

   if( retTex->mProfile->isRenderTarget() )
   {
      pool = D3DPOOL_DEFAULT;
      usage |= D3DUSAGE_RENDERTARGET;
   }

   if(retTex->mProfile->isZTarget())
   {
      usage |= D3DUSAGE_DEPTHSTENCIL;
      pool = D3DPOOL_DEFAULT;
   }

   if( retTex->mProfile->isSystemMemory() )
   {
      pool = D3DPOOL_SYSTEMMEM;
   }

   if( supportsAutoMips && 
       !forceMips &&
       !retTex->mProfile->isSystemMemory() &&
       numMipLevels == 0 &&
       !(depth > 0) )
   {
      usage |= D3DUSAGE_AUTOGENMIPMAP;
   }
#else
   if(retTex->mProfile->isRenderTarget())
   {
      d3dTextureFormat = (D3DFORMAT)MAKELEFMT(d3dTextureFormat);
   }
#endif

   // Set the managed flag...
   retTex->isManaged = (pool == D3DPOOL_MANAGED) || d3d->isD3D9Ex();
   
   if( depth > 0 )
   {
#ifdef TORQUE_OS_XENON
      D3D9Assert( mD3DDevice->CreateVolumeTexture( width, height, depth, numMipLevels, 0 /* usage ignored on the 360 */, 
         d3dTextureFormat, pool, retTex->get3DTexPtr(), NULL), "Failed to create volume texture" );
#else
      D3D9Assert(
         GFXD3DX.D3DXCreateVolumeTexture(
            mD3DDevice,
            width,
            height,
            depth,
            numMipLevels,
            usage,
            d3dTextureFormat,
            pool,
            retTex->get3DTexPtr()
         ), "GFXD3D9TextureManager::_createTexture - failed to create volume texture!"
      );
#endif

      retTex->mTextureSize.set( width, height, depth );
      retTex->mMipLevels = retTex->get3DTex()->GetLevelCount();
      // required for 3D texture support - John Kabus
	  retTex->mFormat = format;
   }
   else
   {
#ifdef TORQUE_OS_XENON
      D3D9Assert( mD3DDevice->CreateTexture(width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr(), NULL), "Failed to create texture" );
      retTex->mMipLevels = retTex->get2DTex()->GetLevelCount();
#else
      // Figure out AA settings for depth and render targets
      D3DMULTISAMPLE_TYPE mstype;
      DWORD mslevel;

      switch (antialiasLevel)
      {
         case 0 :
            mstype = D3DMULTISAMPLE_NONE;
            mslevel = 0;
            break;
         case AA_MATCH_BACKBUFFER :
            mstype = d3d->getMultisampleType();
            mslevel = d3d->getMultisampleLevel();
            break;
         default :
            {
               mstype = D3DMULTISAMPLE_NONMASKABLE;
               mslevel = antialiasLevel;
#ifdef TORQUE_DEBUG
               DWORD MaxSampleQualities;      
               d3d->getD3D()->CheckDeviceMultiSampleType(mAdapterIndex, D3DDEVTYPE_HAL, d3dTextureFormat, FALSE, D3DMULTISAMPLE_NONMASKABLE, &MaxSampleQualities);
               AssertFatal(mslevel < MaxSampleQualities, "Invalid AA level!");
#endif
            }
            break;
      }
     
      bool fastCreate = true;
      // Check for power of 2 textures - this is a problem with FX 5xxx cards
      // with current drivers - 3/2/05
      if( !isPow2(width) || !isPow2(height) )
      {
         fastCreate = false;
      }

      if(retTex->mProfile->isZTarget())
      {
         D3D9Assert(mD3DDevice->CreateDepthStencilSurface(width, height, d3dTextureFormat,
            mstype, mslevel, retTex->mProfile->canDiscard(), retTex->getSurfacePtr(), NULL), "Failed to create Z surface" );

         retTex->mFormat = format; // Assigning format like this should be fine.
      }
      else
      {
         // Try to create the texture directly - should gain us a bit in high
         // performance cases where we know we're creating good stuff and we
         // don't want to bother with D3DX - slow function.
         HRESULT res = D3DERR_INVALIDCALL;
         if( fastCreate )
         {
            res = mD3DDevice->CreateTexture(width, height, numMipLevels, usage, d3dTextureFormat, pool, retTex->get2DTexPtr(), NULL);
         }

         if( !fastCreate || (res != D3D_OK) )
         {
            D3D9Assert(
               GFXD3DX.D3DXCreateTexture(
               mD3DDevice,
               width,
               height,
               numMipLevels,
               usage,
               d3dTextureFormat,
               pool,
               retTex->get2DTexPtr()
               ), "GFXD3D9TextureManager::_createTexture - failed to create texture!"
               );
         }

         // If this is a render target, and it wants AA or wants to match the backbuffer (for example, to share the z)
         // Check the caps though, if we can't stretchrect between textures, use the old RT method.  (Which hopefully means
         // that they can't force AA on us as well.)
         if (retTex->mProfile->isRenderTarget() && mslevel != 0 && (mDeviceCaps.Caps2 && D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES))
         {
            D3D9Assert(mD3DDevice->CreateRenderTarget(width, height, d3dTextureFormat, 
               mstype, mslevel, false, retTex->getSurfacePtr(), NULL),
               "GFXD3D9TextureManager::_createTexture - unable to create render target");
         }

         // All done!
         retTex->mMipLevels = retTex->get2DTex()->GetLevelCount();
      }
#endif

      // Get the actual size of the texture...
      D3DSURFACE_DESC probeDesc;
      ZeroMemory(&probeDesc, sizeof probeDesc);

      if( retTex->get2DTex() != NULL )
         D3D9Assert( retTex->get2DTex()->GetLevelDesc( 0, &probeDesc ), "Failed to get surface description");
      else if( retTex->getSurface() != NULL )
         D3D9Assert( retTex->getSurface()->GetDesc( &probeDesc ), "Failed to get surface description");

      retTex->mTextureSize.set(probeDesc.Width, probeDesc.Height, 0);
      
      int fmt = probeDesc.Format;

#if !defined(TORQUE_OS_XENON)
      GFXREVERSE_LOOKUP( GFXD3D9TextureFormat, GFXFormat, fmt );
      retTex->mFormat = (GFXFormat)fmt;
#else
      retTex->mFormat = format;
#endif
   }
}