Direct3D11 GFX device.

This commit is contained in:
rextimmy 2016-03-20 21:48:52 +10:00
parent 7bba3ee2de
commit 1ff6f221fb
28 changed files with 7847 additions and 0 deletions

View file

@ -0,0 +1,72 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11CardProfiler.h"
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "platformWin32/videoInfo/wmiVideoInfo.h"
#include "console/console.h"
#include "gfx/primBuilder.h"
GFXD3D11CardProfiler::GFXD3D11CardProfiler() : GFXCardProfiler()
{
}
GFXD3D11CardProfiler::~GFXD3D11CardProfiler()
{
}
void GFXD3D11CardProfiler::init()
{
U32 adapterIndex = D3D11->getAdaterIndex();
WMIVideoInfo wmiVidInfo;
if (wmiVidInfo.profileAdapters())
{
const PlatformVideoInfo::PVIAdapter &adapter = wmiVidInfo.getAdapterInformation(adapterIndex);
mCardDescription = adapter.description;
mChipSet = adapter.chipSet;
mVersionString = adapter.driverVersion;
mVideoMemory = adapter.vram;
}
Parent::init();
}
void GFXD3D11CardProfiler::setupCardCapabilities()
{
setCapability("maxTextureWidth", D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
setCapability("maxTextureHeight", D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
setCapability("maxTextureSize", D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION);
}
bool GFXD3D11CardProfiler::_queryCardCap(const String &query, U32 &foundResult)
{
return false;
}
bool GFXD3D11CardProfiler::_queryFormat( const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips )
{
// D3D11 feature level should guarantee that any format is valid!
return GFXD3D11TextureFormat[fmt] != DXGI_FORMAT_UNKNOWN;
}

View file

@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11CARDPROFILER_H_
#define _GFXD3D11CARDPROFILER_H_
#include "gfx/gfxCardProfile.h"
class GFXD3D11CardProfiler : public GFXCardProfiler
{
private:
typedef GFXCardProfiler Parent;
public:
GFXD3D11CardProfiler();
~GFXD3D11CardProfiler();
void init();
protected:
const String &getRendererString() const { static String sRS("Direct3D11"); return sRS; }
void setupCardCapabilities();
bool _queryCardCap(const String &query, U32 &foundResult);
bool _queryFormat(const GFXFormat fmt, const GFXTextureProfile *profile, bool &inOutAutogenMips);
};
#endif

View file

@ -0,0 +1,352 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Cubemap.h"
#include "gfx/gfxCardProfile.h"
#include "gfx/gfxTextureManager.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL)
{
mDynamic = false;
mAutoGenMips = false;
mFaceFormat = GFXFormatR8G8B8A8;
for (U32 i = 0; i < CubeFaces; i++)
{
mRTView[i] = NULL;
}
}
GFXD3D11Cubemap::~GFXD3D11Cubemap()
{
releaseSurfaces();
}
void GFXD3D11Cubemap::releaseSurfaces()
{
if (mDynamic)
GFXTextureManager::removeEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
for (U32 i = 0; i < CubeFaces; i++)
{
SAFE_RELEASE(mRTView[i]);
}
SAFE_RELEASE(mDSView);
SAFE_RELEASE(mSRView);
SAFE_RELEASE(mTexture);
}
void GFXD3D11Cubemap::_onTextureEvent(GFXTexCallbackCode code)
{
if (code == GFXZombify)
releaseSurfaces();
else if (code == GFXResurrect)
initDynamic(mTexSize);
}
bool GFXD3D11Cubemap::isCompressed(GFXFormat format)
{
if (format >= GFXFormatDXT1 && format <= GFXFormatDXT5)
return true;
return false;
}
void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
{
AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
AssertFatal( *faces, "empty texture passed to CubeMap::create" );
// NOTE - check tex sizes on all faces - they MUST be all same size
mTexSize = faces->getWidth();
mFaceFormat = faces->getFormat();
bool compressed = isCompressed(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
if (!compressed)
{
bindFlags |= D3D11_BIND_RENDER_TARGET;
miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
}
U32 mipLevels = faces->getPointer()->getMipLevels();
if (mipLevels > 1)
mAutoGenMips = true;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = mAutoGenMips ? 0 : mipLevels;
desc.ArraySize = 6;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = bindFlags;
desc.MiscFlags = miscFlags;
desc.CPUAccessFlags = 0;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture");
}
for (U32 i = 0; i < CubeFaces; i++)
{
GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
U32 subResource = D3D11CalcSubresource(0, i, mipLevels);
D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), 0, NULL);
}
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view creation failure");
}
if (mAutoGenMips && !compressed)
D3D11DEVICECONTEXT->GenerateMips(mSRView);
}
void GFXD3D11Cubemap::initStatic(DDSFile *dds)
{
AssertFatal(dds, "GFXD3D11Cubemap::initStatic - Got null DDS file!");
AssertFatal(dds->isCubemap(), "GFXD3D11Cubemap::initStatic - Got non-cubemap DDS file!");
AssertFatal(dds->mSurfaces.size() == 6, "GFXD3D11Cubemap::initStatic - DDS has less than 6 surfaces!");
// NOTE - check tex sizes on all faces - they MUST be all same size
mTexSize = dds->getWidth();
mFaceFormat = dds->getFormat();
U32 levels = dds->getMipLevels();
D3D11_TEXTURE2D_DESC desc;
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = levels;
desc.ArraySize = 6;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS;
D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[6 + levels];
for (U32 i = 0; i<CubeFaces; i++)
{
if (!dds->mSurfaces[i])
continue;
for(U32 j = 0; j < levels; j++)
{
pData[i + j].pSysMem = dds->mSurfaces[i]->mMips[j];
pData[i + j].SysMemPitch = dds->getSurfacePitch(j);
pData[i + j].SysMemSlicePitch = dds->getSurfaceSize(j);
}
}
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
delete [] pData;
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = levels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D call failure");
}
}
void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
{
if(!mDynamic)
GFXTextureManager::addEventDelegate(this, &GFXD3D11Cubemap::_onTextureEvent);
mDynamic = true;
mAutoGenMips = true;
mTexSize = texSize;
mFaceFormat = faceFormat;
bool compressed = isCompressed(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
if (!compressed)
{
bindFlags |= D3D11_BIND_RENDER_TARGET;
miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
}
D3D11_TEXTURE2D_DESC desc;
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = 0;
desc.ArraySize = 6;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = bindFlags;
desc.CPUAccessFlags = 0;
desc.MiscFlags = miscFlags;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mTexture);
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = -1;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D call failure");
}
D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
viewDesc.Format = desc.Format;
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
viewDesc.Texture2DArray.ArraySize = 1;
viewDesc.Texture2DArray.MipSlice = 0;
for (U32 i = 0; i < CubeFaces; i++)
{
viewDesc.Texture2DArray.FirstArraySlice = i;
hr = D3D11DEVICE->CreateRenderTargetView(mTexture, &viewDesc, &mRTView[i]);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateRenderTargetView call failure");
}
}
D3D11_TEXTURE2D_DESC depthTexDesc;
depthTexDesc.Width = mTexSize;
depthTexDesc.Height = mTexSize;
depthTexDesc.MipLevels = 1;
depthTexDesc.ArraySize = 1;
depthTexDesc.SampleDesc.Count = 1;
depthTexDesc.SampleDesc.Quality = 0;
depthTexDesc.Format = DXGI_FORMAT_D32_FLOAT;
depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthTexDesc.CPUAccessFlags = 0;
depthTexDesc.MiscFlags = 0;
ID3D11Texture2D* depthTex = 0;
hr = D3D11DEVICE->CreateTexture2D(&depthTexDesc, 0, &depthTex);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D for depth stencil call failure");
}
// Create the depth stencil view for the entire cube
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
dsvDesc.Format = depthTexDesc.Format; //The format must match the depth texture we created above
dsvDesc.Flags = 0;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsvDesc.Texture2D.MipSlice = 0;
hr = D3D11DEVICE->CreateDepthStencilView(depthTex, &dsvDesc, &mDSView);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateDepthStencilView call failure");
}
SAFE_RELEASE(depthTex);
}
//-----------------------------------------------------------------------------
// Set the cubemap to the specified texture unit num
//-----------------------------------------------------------------------------
void GFXD3D11Cubemap::setToTexUnit(U32 tuNum)
{
D3D11DEVICECONTEXT->PSSetShaderResources(tuNum, 1, &mSRView);
}
void GFXD3D11Cubemap::zombify()
{
// Static cubemaps are handled by D3D
if( mDynamic )
releaseSurfaces();
}
void GFXD3D11Cubemap::resurrect()
{
// Static cubemaps are handled by D3D
if( mDynamic )
initDynamic( mTexSize, mFaceFormat );
}
ID3D11ShaderResourceView* GFXD3D11Cubemap::getSRView()
{
return mSRView;
}
ID3D11RenderTargetView* GFXD3D11Cubemap::getRTView(U32 faceIdx)
{
AssertFatal(faceIdx < CubeFaces, "GFXD3D11Cubemap::getRTView - face index out of bounds");
return mRTView[faceIdx];
}
ID3D11RenderTargetView** GFXD3D11Cubemap::getRTViewArray()
{
return mRTView;
}
ID3D11DepthStencilView* GFXD3D11Cubemap::getDSView()
{
return mDSView;
}
ID3D11Texture2D* GFXD3D11Cubemap::get2DTex()
{
return mTexture;
}

View file

@ -0,0 +1,80 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11CUBEMAP_H_
#define _GFXD3D11CUBEMAP_H_
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/gfxCubemap.h"
#include "gfx/gfxResource.h"
#include "gfx/gfxTarget.h"
const U32 CubeFaces = 6;
class GFXD3D11Cubemap : public GFXCubemap
{
public:
virtual void initStatic( GFXTexHandle *faces );
virtual void initStatic( DDSFile *dds );
virtual void initDynamic( U32 texSize, GFXFormat faceFormat = GFXFormatR8G8B8A8 );
virtual void setToTexUnit( U32 tuNum );
virtual U32 getSize() const { return mTexSize; }
virtual GFXFormat getFormat() const { return mFaceFormat; }
GFXD3D11Cubemap();
virtual ~GFXD3D11Cubemap();
// GFXResource interface
virtual void zombify();
virtual void resurrect();
// Get functions
ID3D11ShaderResourceView* getSRView();
ID3D11RenderTargetView* getRTView(U32 faceIdx);
ID3D11RenderTargetView** getRTViewArray();
ID3D11DepthStencilView* getDSView();
ID3D11Texture2D* get2DTex();
private:
friend class GFXD3D11TextureTarget;
friend class GFXD3D11Device;
ID3D11Texture2D* mTexture;
ID3D11ShaderResourceView* mSRView; // for shader resource input
ID3D11RenderTargetView* mRTView[CubeFaces]; // for render targets, 6 faces of the cubemap
ID3D11DepthStencilView* mDSView; //render target view for depth stencil
bool mAutoGenMips;
bool mDynamic;
U32 mTexSize;
GFXFormat mFaceFormat;
void releaseSurfaces();
bool isCompressed(GFXFormat format);
/// The callback used to get texture events.
/// @see GFXTextureManager::addEventDelegate
void _onTextureEvent(GFXTexCallbackCode code);
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,295 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11DEVICE_H_
#define _GFXD3D11DEVICE_H_
#include <d3d11.h>
#include "platform/tmm_off.h"
#include "platformWin32/platformWin32.h"
#include "gfx/D3D11/gfxD3D11Shader.h"
#include "gfx/D3D11/gfxD3D11StateBlock.h"
#include "gfx/D3D11/gfxD3D11TextureManager.h"
#include "gfx/D3D11/gfxD3D11Cubemap.h"
#include "gfx/D3D11/gfxD3D11PrimitiveBuffer.h"
#include "gfx/gfxInit.h"
#include "gfx/gfxResource.h"
#include "platform/tmm_on.h"
#define D3D11 static_cast<GFXD3D11Device*>(GFX)
#define D3D11DEVICE D3D11->getDevice()
#define D3D11DEVICECONTEXT D3D11->getDeviceContext()
class PlatformWindow;
class GFXD3D11ShaderConstBuffer;
//------------------------------------------------------------------------------
class GFXD3D11Device : public GFXDevice
{
friend class GFXResource;
friend class GFXD3D11PrimitiveBuffer;
friend class GFXD3D11VertexBuffer;
friend class GFXD3D11TextureObject;
friend class GFXD3D11TextureTarget;
friend class GFXD3D11WindowTarget;
virtual GFXFormat selectSupportedFormat(GFXTextureProfile *profile,
const Vector<GFXFormat> &formats, bool texture, bool mustblend, bool mustfilter);
virtual void enumerateVideoModes();
virtual GFXWindowTarget *allocWindowTarget(PlatformWindow *window);
virtual GFXTextureTarget *allocRenderToTextureTarget();
virtual void enterDebugEvent(ColorI color, const char *name){};
virtual void leaveDebugEvent(){};
virtual void setDebugMarker(ColorI color, const char *name){};
protected:
class D3D11VertexDecl : public GFXVertexDecl
{
public:
virtual ~D3D11VertexDecl()
{
SAFE_RELEASE( decl );
}
ID3D11InputLayout *decl;
};
virtual void initStates() { };
static GFXAdapter::CreateDeviceInstanceDelegate mCreateDeviceInstance;
MatrixF mTempMatrix; ///< Temporary matrix, no assurances on value at all
RectI mClipRect;
typedef StrongRefPtr<GFXD3D11VertexBuffer> RPGDVB;
Vector<RPGDVB> mVolatileVBList;
/// Used to lookup a vertex declaration for the vertex format.
/// @see allocVertexDecl
typedef Map<String,D3D11VertexDecl*> VertexDeclMap;
VertexDeclMap mVertexDecls;
ID3D11RenderTargetView* mDeviceBackBufferView;
ID3D11DepthStencilView* mDeviceDepthStencilView;
ID3D11Texture2D *mDeviceBackbuffer;
ID3D11Texture2D *mDeviceDepthStencil;
/// The stream 0 vertex buffer used for volatile VB offseting.
GFXD3D11VertexBuffer *mVolatileVB;
//-----------------------------------------------------------------------
StrongRefPtr<GFXD3D11PrimitiveBuffer> mDynamicPB;
GFXD3D11PrimitiveBuffer *mCurrentPB;
ID3D11VertexShader *mLastVertShader;
ID3D11PixelShader *mLastPixShader;
S32 mCreateFenceType;
IDXGISwapChain *mSwapChain;
ID3D11Device* mD3DDevice;
ID3D11DeviceContext* mD3DDeviceContext;
GFXShader* mCurrentShader;
GFXShaderRef mGenericShader[GS_COUNT];
GFXShaderConstBufferRef mGenericShaderBuffer[GS_COUNT];
GFXShaderConstHandle *mModelViewProjSC[GS_COUNT];
U32 mAdapterIndex;
F32 mPixVersion;
bool mDebugLayers;
DXGI_SAMPLE_DESC mMultisampleDesc;
bool mOcclusionQuerySupported;
U32 mDrawInstancesCount;
/// To manage creating and re-creating of these when device is aquired
void reacquireDefaultPoolResources();
/// To release all resources we control from D3DPOOL_DEFAULT
void releaseDefaultPoolResources();
virtual GFXD3D11VertexBuffer* findVBPool( const GFXVertexFormat *vertexFormat, U32 numVertsNeeded );
virtual GFXD3D11VertexBuffer* createVBPool( const GFXVertexFormat *vertexFormat, U32 vertSize );
IDXGISwapChain* getSwapChain();
// State overrides
// {
///
virtual void setTextureInternal(U32 textureUnit, const GFXTextureObject* texture);
/// Called by GFXDevice to create a device specific stateblock
virtual GFXStateBlockRef createStateBlockInternal(const GFXStateBlockDesc& desc);
/// Called by GFXDevice to actually set a stateblock.
virtual void setStateBlockInternal(GFXStateBlock* block, bool force);
/// Track the last const buffer we've used. Used to notify new constant buffers that
/// they should send all of their constants up
StrongRefPtr<GFXD3D11ShaderConstBuffer> mCurrentConstBuffer;
/// Called by base GFXDevice to actually set a const buffer
virtual void setShaderConstBufferInternal(GFXShaderConstBuffer* buffer);
virtual void setMatrix( GFXMatrixType /*mtype*/, const MatrixF &/*mat*/ ) { };
virtual void setLightInternal(U32 /*lightStage*/, const GFXLightInfo /*light*/, bool /*lightEnable*/) { };
virtual void setLightMaterialInternal(const GFXLightMaterial /*mat*/) { };
virtual void setGlobalAmbientInternal(ColorF /*color*/) { };
// }
// Index buffer management
// {
virtual void _setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount );
// }
virtual GFXShader* createShader();
/// Device helper function
virtual DXGI_SWAP_CHAIN_DESC setupPresentParams( const GFXVideoMode &mode, const HWND &hwnd );
String _createTempShaderInternal(const GFXVertexFormat *vertexFormat);
// Supress any debug layer messages we don't want to see
void _suppressDebugMessages();
public:
static GFXDevice *createInstance( U32 adapterIndex );
static void enumerateAdapters( Vector<GFXAdapter*> &adapterList );
GFXTextureObject* createRenderSurface( U32 width, U32 height, GFXFormat format, U32 mipLevel );
ID3D11DepthStencilView* getDepthStencilView() { return mDeviceDepthStencilView; }
ID3D11RenderTargetView* getRenderTargetView() { return mDeviceBackBufferView; }
ID3D11Texture2D* getBackBufferTexture() { return mDeviceBackbuffer; }
/// Constructor
/// @param d3d Direct3D object to instantiate this device with
/// @param index Adapter index since D3D can use multiple graphics adapters
GFXD3D11Device( U32 index );
virtual ~GFXD3D11Device();
// Activate/deactivate
// {
virtual void init( const GFXVideoMode &mode, PlatformWindow *window = NULL );
virtual void preDestroy() { GFXDevice::preDestroy(); if(mTextureManager) mTextureManager->kill(); }
GFXAdapterType getAdapterType(){ return Direct3D11; }
U32 getAdaterIndex() const { return mAdapterIndex; }
virtual GFXCubemap *createCubemap();
virtual F32 getPixelShaderVersion() const { return mPixVersion; }
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;}
virtual void setShader(GFXShader *shader, bool force = false);
virtual U32 getNumSamplers() const { return 16; }
virtual U32 getNumRenderTargets() const { return 8; }
// }
// Misc rendering control
// {
virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil );
virtual bool beginSceneInternal();
virtual void endSceneInternal();
virtual void setClipRect( const RectI &rect );
virtual const RectI& getClipRect() const { return mClipRect; }
// }
/// @name Render Targets
/// @{
virtual void _updateRenderTargets();
/// @}
// Vertex/Index buffer management
// {
virtual GFXVertexBuffer* allocVertexBuffer( U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertSize,
GFXBufferType bufferType,
void* data = NULL);
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
U32 numPrimitives,
GFXBufferType bufferType,
void* data = NULL);
virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat );
virtual void setVertexDecl( const GFXVertexDecl *decl );
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer );
virtual void setVertexStreamFrequency( U32 stream, U32 frequency );
// }
virtual U32 getMaxDynamicVerts() { return MAX_DYNAMIC_VERTS; }
virtual U32 getMaxDynamicIndices() { return MAX_DYNAMIC_INDICES; }
inline U32 primCountToIndexCount(GFXPrimitiveType primType, U32 primitiveCount);
// Rendering
// {
virtual void drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount );
// }
ID3D11DeviceContext* getDeviceContext(){ return mD3DDeviceContext; }
ID3D11Device* getDevice(){ return mD3DDevice; }
/// Reset
void reset( DXGI_SWAP_CHAIN_DESC &d3dpp );
virtual void setupGenericShaders( GenericShaderType type = GSColor );
inline virtual F32 getFillConventionOffset() const { return 0.0f; }
virtual void doParanoidStateCheck() {};
GFXFence *createFence();
GFXOcclusionQuery* createOcclusionQuery();
// Default multisample parameters
DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
};
#endif

View file

@ -0,0 +1,155 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "console/console.h"
//------------------------------------------------------------------------------
DXGI_FORMAT GFXD3D11TextureFormat[GFXFormat_COUNT];
D3D11_FILTER GFXD3D11TextureFilter[GFXTextureFilter_COUNT];
D3D11_BLEND GFXD3D11Blend[GFXBlend_COUNT];
D3D11_BLEND_OP GFXD3D11BlendOp[GFXBlendOp_COUNT];
D3D11_STENCIL_OP GFXD3D11StencilOp[GFXStencilOp_COUNT];
D3D11_COMPARISON_FUNC GFXD3D11CmpFunc[GFXCmp_COUNT];
D3D11_CULL_MODE GFXD3D11CullMode[GFXCull_COUNT];
D3D11_FILL_MODE GFXD3D11FillMode[GFXFill_COUNT];
D3D11_PRIMITIVE_TOPOLOGY GFXD3D11PrimType[GFXPT_COUNT];
D3D11_TEXTURE_ADDRESS_MODE GFXD3D11TextureAddress[GFXAddress_COUNT];
DXGI_FORMAT GFXD3D11DeclType[GFXDeclType_COUNT];
//------------------------------------------------------------------------------
void GFXD3D11EnumTranslate::init()
{
GFXD3D11TextureFormat[GFXFormatR8G8B8] = DXGI_FORMAT_B8G8R8X8_UNORM;
GFXD3D11TextureFormat[GFXFormatR8G8B8A8] = DXGI_FORMAT_B8G8R8A8_UNORM;
GFXD3D11TextureFormat[GFXFormatR8G8B8X8] = DXGI_FORMAT_B8G8R8X8_UNORM;
GFXD3D11TextureFormat[GFXFormatB8G8R8A8] = DXGI_FORMAT_B8G8R8A8_UNORM;
GFXD3D11TextureFormat[GFXFormatR5G6B5] = DXGI_FORMAT_B5G6R5_UNORM;
GFXD3D11TextureFormat[GFXFormatR5G5B5A1] = DXGI_FORMAT_B5G5R5A1_UNORM;
GFXD3D11TextureFormat[GFXFormatR5G5B5X1] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatR32F] = DXGI_FORMAT_R32_FLOAT;
GFXD3D11TextureFormat[GFXFormatA4L4] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatA8L8] = DXGI_FORMAT_R8G8_UNORM;
GFXD3D11TextureFormat[GFXFormatA8] = DXGI_FORMAT_A8_UNORM;
GFXD3D11TextureFormat[GFXFormatL8] = DXGI_FORMAT_R8_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT1] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT2] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT3] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT4] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT5] = DXGI_FORMAT_BC3_UNORM;
GFXD3D11TextureFormat[GFXFormatR32G32B32A32F] = DXGI_FORMAT_R32G32B32A32_FLOAT;
GFXD3D11TextureFormat[GFXFormatR16G16B16A16F] = DXGI_FORMAT_R16G16B16A16_FLOAT;
GFXD3D11TextureFormat[GFXFormatL16] = DXGI_FORMAT_R16_UNORM;
GFXD3D11TextureFormat[GFXFormatR16G16B16A16] = DXGI_FORMAT_R16G16B16A16_UNORM;
GFXD3D11TextureFormat[GFXFormatR16G16] = DXGI_FORMAT_R16G16_UNORM;
GFXD3D11TextureFormat[GFXFormatR16F] = DXGI_FORMAT_R16_FLOAT;
GFXD3D11TextureFormat[GFXFormatR16G16F] = DXGI_FORMAT_R16G16_FLOAT;
GFXD3D11TextureFormat[GFXFormatR10G10B10A2] = DXGI_FORMAT_R10G10B10A2_UNORM;
GFXD3D11TextureFormat[GFXFormatD32] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD24X8] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;
GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_UNORM;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11TextureFilter[GFXTextureFilterNone] = D3D11_FILTER_MIN_MAG_MIP_POINT;
GFXD3D11TextureFilter[GFXTextureFilterPoint] = D3D11_FILTER_MIN_MAG_MIP_POINT;
GFXD3D11TextureFilter[GFXTextureFilterLinear] = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
GFXD3D11TextureFilter[GFXTextureFilterAnisotropic] = D3D11_FILTER_ANISOTROPIC;
GFXD3D11TextureFilter[GFXTextureFilterPyramidalQuad] = D3D11_FILTER_ANISOTROPIC;
GFXD3D11TextureFilter[GFXTextureFilterGaussianQuad] = D3D11_FILTER_ANISOTROPIC;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11Blend[GFXBlendZero] = D3D11_BLEND_ZERO;
GFXD3D11Blend[GFXBlendOne] = D3D11_BLEND_ONE;
GFXD3D11Blend[GFXBlendSrcColor] = D3D11_BLEND_SRC_COLOR;
GFXD3D11Blend[GFXBlendInvSrcColor] = D3D11_BLEND_INV_SRC_COLOR;
GFXD3D11Blend[GFXBlendSrcAlpha] = D3D11_BLEND_SRC_ALPHA;
GFXD3D11Blend[GFXBlendInvSrcAlpha] = D3D11_BLEND_INV_SRC_ALPHA;
GFXD3D11Blend[GFXBlendDestAlpha] = D3D11_BLEND_DEST_ALPHA;
GFXD3D11Blend[GFXBlendInvDestAlpha] = D3D11_BLEND_INV_DEST_ALPHA;
GFXD3D11Blend[GFXBlendDestColor] = D3D11_BLEND_DEST_COLOR;
GFXD3D11Blend[GFXBlendInvDestColor] = D3D11_BLEND_INV_DEST_COLOR;
GFXD3D11Blend[GFXBlendSrcAlphaSat] = D3D11_BLEND_SRC_ALPHA_SAT;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11BlendOp[GFXBlendOpAdd] = D3D11_BLEND_OP_ADD;
GFXD3D11BlendOp[GFXBlendOpSubtract] = D3D11_BLEND_OP_SUBTRACT;
GFXD3D11BlendOp[GFXBlendOpRevSubtract] = D3D11_BLEND_OP_REV_SUBTRACT;
GFXD3D11BlendOp[GFXBlendOpMin] = D3D11_BLEND_OP_MIN;
GFXD3D11BlendOp[GFXBlendOpMax] = D3D11_BLEND_OP_MAX;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11StencilOp[GFXStencilOpKeep] = D3D11_STENCIL_OP_KEEP;
GFXD3D11StencilOp[GFXStencilOpZero] = D3D11_STENCIL_OP_ZERO;
GFXD3D11StencilOp[GFXStencilOpReplace] = D3D11_STENCIL_OP_REPLACE;
GFXD3D11StencilOp[GFXStencilOpIncrSat] = D3D11_STENCIL_OP_INCR_SAT;
GFXD3D11StencilOp[GFXStencilOpDecrSat] = D3D11_STENCIL_OP_DECR_SAT;
GFXD3D11StencilOp[GFXStencilOpInvert] = D3D11_STENCIL_OP_INVERT;
GFXD3D11StencilOp[GFXStencilOpIncr] = D3D11_STENCIL_OP_INCR;
GFXD3D11StencilOp[GFXStencilOpDecr] = D3D11_STENCIL_OP_DECR;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11CmpFunc[GFXCmpNever] = D3D11_COMPARISON_NEVER;
GFXD3D11CmpFunc[GFXCmpLess] = D3D11_COMPARISON_LESS;
GFXD3D11CmpFunc[GFXCmpEqual] = D3D11_COMPARISON_EQUAL;
GFXD3D11CmpFunc[GFXCmpLessEqual] = D3D11_COMPARISON_LESS_EQUAL;
GFXD3D11CmpFunc[GFXCmpGreater] = D3D11_COMPARISON_GREATER;
GFXD3D11CmpFunc[GFXCmpNotEqual] = D3D11_COMPARISON_NOT_EQUAL;
GFXD3D11CmpFunc[GFXCmpGreaterEqual] = D3D11_COMPARISON_GREATER_EQUAL;
GFXD3D11CmpFunc[GFXCmpAlways] = D3D11_COMPARISON_ALWAYS;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11CullMode[GFXCullNone] = D3D11_CULL_NONE;
GFXD3D11CullMode[GFXCullCW] = D3D11_CULL_FRONT;
GFXD3D11CullMode[GFXCullCCW] = D3D11_CULL_BACK;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11FillMode[GFXFillPoint] = D3D11_FILL_SOLID;
GFXD3D11FillMode[GFXFillWireframe] = D3D11_FILL_WIREFRAME;
GFXD3D11FillMode[GFXFillSolid] = D3D11_FILL_SOLID;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11PrimType[GFXPointList] = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
GFXD3D11PrimType[GFXLineList] = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
GFXD3D11PrimType[GFXLineStrip] = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
GFXD3D11PrimType[GFXTriangleList] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
GFXD3D11PrimType[GFXTriangleStrip] = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11TextureAddress[GFXAddressWrap] = D3D11_TEXTURE_ADDRESS_WRAP;
GFXD3D11TextureAddress[GFXAddressMirror] = D3D11_TEXTURE_ADDRESS_MIRROR;
GFXD3D11TextureAddress[GFXAddressClamp] = D3D11_TEXTURE_ADDRESS_CLAMP;
GFXD3D11TextureAddress[GFXAddressBorder] = D3D11_TEXTURE_ADDRESS_BORDER;
GFXD3D11TextureAddress[GFXAddressMirrorOnce] = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GFXD3D11DeclType[GFXDeclType_Float] = DXGI_FORMAT_R32_FLOAT;
GFXD3D11DeclType[GFXDeclType_Float2] = DXGI_FORMAT_R32G32_FLOAT;
GFXD3D11DeclType[GFXDeclType_Float3] = DXGI_FORMAT_R32G32B32_FLOAT;
GFXD3D11DeclType[GFXDeclType_Float4] = DXGI_FORMAT_R32G32B32A32_FLOAT;
GFXD3D11DeclType[GFXDeclType_Color] = DXGI_FORMAT_B8G8R8A8_UNORM; // DXGI_FORMAT_R8G8B8A8_UNORM;
}

View file

@ -0,0 +1,51 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11ENUMTRANSLATE_H_
#define _GFXD3D11ENUMTRANSLATE_H_
#include "gfx/D3D11/gfxD3D11Shader.h"
#include "gfx/gfxEnums.h"
//------------------------------------------------------------------------------
namespace GFXD3D11EnumTranslate
{
void init();
};
//------------------------------------------------------------------------------
extern DXGI_FORMAT GFXD3D11TextureFormat[GFXFormat_COUNT];
extern D3D11_FILTER GFXD3D11TextureFilter[GFXTextureFilter_COUNT];
extern D3D11_BLEND GFXD3D11Blend[GFXBlend_COUNT];
extern D3D11_BLEND_OP GFXD3D11BlendOp[GFXBlendOp_COUNT];
extern D3D11_STENCIL_OP GFXD3D11StencilOp[GFXStencilOp_COUNT];
extern D3D11_COMPARISON_FUNC GFXD3D11CmpFunc[GFXCmp_COUNT];
extern D3D11_CULL_MODE GFXD3D11CullMode[GFXCull_COUNT];
extern D3D11_FILL_MODE GFXD3D11FillMode[GFXFill_COUNT];
extern D3D11_PRIMITIVE_TOPOLOGY GFXD3D11PrimType[GFXPT_COUNT];
extern D3D11_TEXTURE_ADDRESS_MODE GFXD3D11TextureAddress[GFXAddress_COUNT];
extern DXGI_FORMAT GFXD3D11DeclType[GFXDeclType_COUNT];
#endif

View file

@ -0,0 +1,177 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11OcclusionQuery.h"
#include "gui/3d/guiTSControl.h"
#ifdef TORQUE_GATHER_METRICS
// For TickMs define
#include "T3D/gameBase/processList.h"
#endif
GFXD3D11OcclusionQuery::GFXD3D11OcclusionQuery(GFXDevice *device)
: GFXOcclusionQuery(device),
mQuery(NULL)
{
#ifdef TORQUE_GATHER_METRICS
mTimer = PlatformTimer::create();
mTimer->getElapsedMs();
mTimeSinceEnd = 0;
mBeginFrame = 0;
#endif
}
GFXD3D11OcclusionQuery::~GFXD3D11OcclusionQuery()
{
SAFE_RELEASE(mQuery);
#ifdef TORQUE_GATHER_METRICS
SAFE_DELETE(mTimer);
#endif
}
bool GFXD3D11OcclusionQuery::begin()
{
if(GFXDevice::getDisableOcclusionQuery())
return true;
if (mQuery == NULL)
{
D3D11_QUERY_DESC queryDesc;
queryDesc.Query = D3D11_QUERY_OCCLUSION;
queryDesc.MiscFlags = 0;
HRESULT hRes = D3D11DEVICE->CreateQuery(&queryDesc, &mQuery);
if(FAILED(hRes))
{
AssertFatal(false, "GFXD3D11OcclusionQuery::begin - Hardware does not support D3D11 Occlusion-Queries, this should be caught before this type is created");
}
AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11OcclusionQuery::begin - Out of memory");
}
// Add a begin marker to the command buffer queue.
D3D11DEVICECONTEXT->Begin(mQuery);
#ifdef TORQUE_GATHER_METRICS
mBeginFrame = GuiTSCtrl::getFrameCount();
#endif
return true;
}
void GFXD3D11OcclusionQuery::end()
{
if (GFXDevice::getDisableOcclusionQuery())
return;
// Add an end marker to the command buffer queue.
D3D11DEVICECONTEXT->End(mQuery);
#ifdef TORQUE_GATHER_METRICS
AssertFatal( mBeginFrame == GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::end - ended query on different frame than begin!" );
mTimer->getElapsedMs();
mTimer->reset();
#endif
}
GFXD3D11OcclusionQuery::OcclusionQueryStatus GFXD3D11OcclusionQuery::getStatus(bool block, U32 *data)
{
// If this ever shows up near the top of a profile then your system is
// GPU bound or you are calling getStatus too soon after submitting it.
//
// To test if you are GPU bound resize your window very small and see if
// this profile no longer appears at the top.
//
// To test if you are calling getStatus to soon after submitting it,
// check the value of mTimeSinceEnd in a debug build. If it is < half the length
// of time to render an individual frame you could have problems.
PROFILE_SCOPE(GFXD3D11OcclusionQuery_getStatus);
if ( GFXDevice::getDisableOcclusionQuery() )
return NotOccluded;
if ( mQuery == NULL )
return Unset;
#ifdef TORQUE_GATHER_METRICS
//AssertFatal( mBeginFrame < GuiTSCtrl::getFrameCount(), "GFXD3D11OcclusionQuery::getStatus - called on the same frame as begin!" );
//U32 mTimeSinceEnd = mTimer->getElapsedMs();
//AssertFatal( mTimeSinceEnd >= 5, "GFXD3DOcculsionQuery::getStatus - less than TickMs since called ::end!" );
#endif
HRESULT hRes;
U64 dwOccluded = 0;
if ( block )
{
while ((hRes = D3D11DEVICECONTEXT->GetData(mQuery, &dwOccluded, sizeof(U64), 0)) == S_FALSE);
}
else
{
hRes = D3D11DEVICECONTEXT->GetData(mQuery, &dwOccluded, sizeof(U64), 0);
}
if (hRes == S_OK)
{
if (data != NULL)
*data = (U32)dwOccluded;
return dwOccluded > 0 ? NotOccluded : Occluded;
}
if (hRes == S_FALSE)
return Waiting;
return Error;
}
void GFXD3D11OcclusionQuery::zombify()
{
SAFE_RELEASE( mQuery );
}
void GFXD3D11OcclusionQuery::resurrect()
{
// Recreate the query
if( mQuery == NULL )
{
D3D11_QUERY_DESC queryDesc;
queryDesc.Query = D3D11_QUERY_OCCLUSION;
queryDesc.MiscFlags = 0;
HRESULT hRes = D3D11DEVICE->CreateQuery(&queryDesc, &mQuery);
AssertISV( hRes != E_OUTOFMEMORY, "GFXD3D9QueryFence::resurrect - Out of memory" );
}
}
const String GFXD3D11OcclusionQuery::describeSelf() const
{
// We've got nothing
return String();
}

View file

@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFX_D3D11_OCCLUSIONQUERY_H_
#define _GFX_D3D11_OCCLUSIONQUERY_H_
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/gfxOcclusionQuery.h"
#ifdef TORQUE_GATHER_METRICS
#include "platform/platformTimer.h"
#endif
class GFXD3D11OcclusionQuery : public GFXOcclusionQuery
{
private:
mutable ID3D11Query *mQuery;
#ifdef TORQUE_GATHER_METRICS
U32 mBeginFrame;
U32 mTimeSinceEnd;
PlatformTimer *mTimer;
#endif
public:
GFXD3D11OcclusionQuery(GFXDevice *device);
virtual ~GFXD3D11OcclusionQuery();
virtual bool begin();
virtual void end();
virtual OcclusionQueryStatus getStatus(bool block, U32 *data = NULL);
// GFXResource
virtual void zombify();
virtual void resurrect();
virtual const String describeSelf() const;
};
#endif

View file

@ -0,0 +1,222 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/D3D11/gfxD3D11PrimitiveBuffer.h"
#include "core/util/safeRelease.h"
void GFXD3D11PrimitiveBuffer::prepare()
{
D3D11->_setPrimitiveBuffer(this);
}
void GFXD3D11PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
{
AssertFatal(!mLocked, "GFXD3D11PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
mLocked = true;
D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD;
switch(mBufferType)
{
case GFXBufferTypeImmutable:
case GFXBufferTypeStatic:
case GFXBufferTypeDynamic:
flags = D3D11_MAP_WRITE_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 = D3D11->mDynamicPB;
AssertFatal( mVolatileBuffer, "GFXD3D11PrimitiveBuffer::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 = D3D11_MAP_WRITE_DISCARD;
mVolatileStart = indexStart = 0;
indexEnd = indexEnd;
}
else
{
flags = D3D11_MAP_WRITE_NO_OVERWRITE;
mVolatileStart = indexStart = mVolatileBuffer->mIndexCount;
indexEnd += mVolatileBuffer->mIndexCount;
}
mVolatileBuffer->mIndexCount = indexEnd + 1;
ib = mVolatileBuffer->ib;
break;
}
mIndexStart = indexStart;
mIndexEnd = indexEnd;
if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
{
U32 sizeToLock = (indexEnd - indexStart) * sizeof(U16);
*indexPtr = new U8[sizeToLock];
mLockedBuffer = *indexPtr;
}
else
{
D3D11_MAPPED_SUBRESOURCE pIndexData;
ZeroMemory(&pIndexData, sizeof(D3D11_MAPPED_SUBRESOURCE));
HRESULT hr = D3D11DEVICECONTEXT->Map(ib, 0, flags, 0, &pIndexData);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11PrimitiveBuffer::lock - Could not lock primitive buffer.");
}
*indexPtr = (U8*)pIndexData.pData + (indexStart * sizeof(U16)) ;
}
#ifdef TORQUE_DEBUG
// Allocate a debug buffer large enough for the lock
// plus space for over and under run guard strings.
mLockedSize = (indexEnd - indexStart) * sizeof(U16);
const U32 guardSize = sizeof( _PBGuardString );
mDebugGuardBuffer = new U8[mLockedSize+(guardSize*2)];
// Setup the guard strings.
dMemcpy( mDebugGuardBuffer, _PBGuardString, guardSize );
dMemcpy( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize );
// Store the real lock pointer and return our debug pointer.
mLockedBuffer = *indexPtr;
*indexPtr = (U16*)( mDebugGuardBuffer + guardSize );
#endif // TORQUE_DEBUG
}
void GFXD3D11PrimitiveBuffer::unlock()
{
#ifdef TORQUE_DEBUG
if ( mDebugGuardBuffer )
{
const U32 guardSize = sizeof( _PBGuardString );
// First check the guard areas for overwrites.
AssertFatal( dMemcmp( mDebugGuardBuffer, _PBGuardString, guardSize ) == 0,
"GFXD3D11PrimitiveBuffer::unlock - Caught lock memory underrun!" );
AssertFatal( dMemcmp( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize ) == 0,
"GFXD3D11PrimitiveBuffer::unlock - Caught lock memory overrun!" );
// Copy the debug content down to the real PB.
dMemcpy( mLockedBuffer, mDebugGuardBuffer + guardSize, mLockedSize );
// Cleanup.
delete [] mDebugGuardBuffer;
mDebugGuardBuffer = NULL;
//mLockedBuffer = NULL;
mLockedSize = 0;
}
#endif // TORQUE_DEBUG
const U32 totalSize = this->mIndexCount * sizeof(U16);
if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
{
//set up the update region of the buffer
D3D11_BOX box;
box.back = 1;
box.front = 0;
box.top = 0;
box.bottom =1;
box.left = mIndexStart *sizeof(U16);
box.right = mIndexEnd * sizeof(U16);
//update the real ib buffer
D3D11DEVICECONTEXT->UpdateSubresource(ib, 0, &box,mLockedBuffer,totalSize, 0);
//clean up the old buffer
delete[] mLockedBuffer;
mLockedBuffer = NULL;
}
else
{
D3D11DEVICECONTEXT->Unmap(ib,0);
}
mLocked = false;
mIsFirstLock = false;
mVolatileBuffer = NULL;
}
GFXD3D11PrimitiveBuffer::~GFXD3D11PrimitiveBuffer()
{
if( mBufferType != GFXBufferTypeVolatile )
{
SAFE_RELEASE(ib);
}
}
void GFXD3D11PrimitiveBuffer::zombify()
{
if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
return;
AssertFatal(!mLocked, "GFXD3D11PrimitiveBuffer::zombify - Cannot zombify a locked buffer!");
if (mBufferType == GFXBufferTypeVolatile)
{
// We must null the volatile buffer else we're holding
// a dead pointer which can be set on the device.
ib = NULL;
return;
}
// Dynamic buffers get released.
SAFE_RELEASE(ib);
}
void GFXD3D11PrimitiveBuffer::resurrect()
{
if ( mBufferType != GFXBufferTypeDynamic )
return;
D3D11_BUFFER_DESC desc;
desc.ByteWidth = sizeof(U16) * mIndexCount;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &ib);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11PrimitiveBuffer::resurrect - Failed to allocate an index buffer.");
}
}

View file

@ -0,0 +1,83 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11PRIMITIVEBUFFER_H_
#define _GFXD3D11PRIMITIVEBUFFER_H_
#include "gfx/gfxPrimitiveBuffer.h"
class GFXD3D11PrimitiveBuffer : public GFXPrimitiveBuffer
{
public:
ID3D11Buffer *ib;
StrongRefPtr<GFXD3D11PrimitiveBuffer> mVolatileBuffer;
U32 mVolatileStart;
U32 mIndexStart;
U32 mIndexEnd;
#ifdef TORQUE_DEBUG
#define _PBGuardString "GFX_PRIMTIVE_BUFFER_GUARD_STRING"
U8 *mDebugGuardBuffer;
U32 mLockedSize;
#endif TORQUE_DEBUG
void *mLockedBuffer;
bool mLocked;
bool mIsFirstLock;
GFXD3D11PrimitiveBuffer( GFXDevice *device,
U32 indexCount,
U32 primitiveCount,
GFXBufferType bufferType );
virtual ~GFXD3D11PrimitiveBuffer();
virtual void lock(U32 indexStart, U32 indexEnd, void **indexPtr);
virtual void unlock();
virtual void prepare();
// GFXResource interface
virtual void zombify();
virtual void resurrect();
};
inline GFXD3D11PrimitiveBuffer::GFXD3D11PrimitiveBuffer( GFXDevice *device,
U32 indexCount,
U32 primitiveCount,
GFXBufferType bufferType )
: GFXPrimitiveBuffer( device, indexCount, primitiveCount, bufferType )
{
mVolatileStart = 0;
ib = NULL;
mIsFirstLock = true;
mLocked = false;
#ifdef TORQUE_DEBUG
mDebugGuardBuffer = NULL;
mLockedBuffer = NULL;
mLockedSize = 0;
mIndexStart = 0;
mIndexEnd = 0;
#endif
}
#endif

View file

@ -0,0 +1,110 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11QueryFence.h"
GFXD3D11QueryFence::~GFXD3D11QueryFence()
{
SAFE_RELEASE(mQuery);
}
void GFXD3D11QueryFence::issue()
{
PROFILE_START(GFXD3D11QueryFence_issue);
// Create the query if we need to
if(mQuery == NULL)
{
D3D11_QUERY_DESC QueryDesc;
QueryDesc.Query = D3D11_QUERY_EVENT;
QueryDesc.MiscFlags = 0;
HRESULT hRes = D3D11DEVICE->CreateQuery(&QueryDesc, &mQuery);
if(FAILED(hRes))
{
AssertFatal(false, "Hardware does not support D3D11 Queries, this should be caught before this fence type is created" );
}
AssertISV(hRes != E_OUTOFMEMORY, "Out of memory");
}
// Issue the query
D3D11DEVICECONTEXT->End(mQuery);
PROFILE_END();
}
GFXFence::FenceStatus GFXD3D11QueryFence::getStatus() const
{
if(mQuery == NULL)
return GFXFence::Unset;
HRESULT hRes = D3D11DEVICECONTEXT->GetData(mQuery, NULL, 0, 0);
return (hRes == S_OK ? GFXFence::Processed : GFXFence::Pending);
}
void GFXD3D11QueryFence::block()
{
PROFILE_SCOPE(GFXD3D11QueryFence_block);
// Calling block() before issue() is valid, catch this case
if( mQuery == NULL )
return;
HRESULT hRes;
while((hRes = D3D11DEVICECONTEXT->GetData(mQuery, NULL, 0, 0)) == S_FALSE); //D3DGETDATA_FLUSH
}
void GFXD3D11QueryFence::zombify()
{
// Release our query
SAFE_RELEASE( mQuery );
}
void GFXD3D11QueryFence::resurrect()
{
// Recreate the query
if(mQuery == NULL)
{
D3D11_QUERY_DESC QueryDesc;
QueryDesc.Query = D3D11_QUERY_EVENT;
QueryDesc.MiscFlags = 0;
HRESULT hRes = D3D11DEVICE->CreateQuery(&QueryDesc, &mQuery);
if(FAILED(hRes))
{
AssertFatal(false, "GFXD3D11QueryFence::resurrect - Hardware does not support D3D11 Queries, this should be caught before this fence type is created");
}
AssertISV(hRes != E_OUTOFMEMORY, "GFXD3D11QueryFence::resurrect - Out of memory");
}
}
const String GFXD3D11QueryFence::describeSelf() const
{
// We've got nothing
return String();
}

View file

@ -0,0 +1,49 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFX_D3D11_QUERYFENCE_H_
#define _GFX_D3D11_QUERYFENCE_H_
#include "gfx/gfxFence.h"
#include "gfx/gfxResource.h"
#include "gfx/D3D11/gfxD3D11Device.h"
class GFXD3D11QueryFence : public GFXFence
{
private:
mutable ID3D11Query *mQuery;
public:
GFXD3D11QueryFence( GFXDevice *device ) : GFXFence( device ), mQuery( NULL ) {};
virtual ~GFXD3D11QueryFence();
virtual void issue();
virtual FenceStatus getStatus() const;
virtual void block();
// GFXResource interface
virtual void zombify();
virtual void resurrect();
virtual const String describeSelf() const;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,471 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11SHADER_H_
#define _GFXD3D11SHADER_H_
#include <d3dcompiler.h>
#include "core/util/path.h"
#include "core/util/tDictionary.h"
#include "gfx/gfxShader.h"
#include "gfx/gfxResource.h"
#include "gfx/genericConstBuffer.h"
#include "gfx/D3D11/gfxD3D11Device.h"
class GFXD3D11Shader;
enum CONST_CLASS
{
D3DPC_SCALAR,
D3DPC_VECTOR,
D3DPC_MATRIX_ROWS,
D3DPC_MATRIX_COLUMNS,
D3DPC_OBJECT,
D3DPC_STRUCT
};
enum CONST_TYPE
{
D3DPT_VOID,
D3DPT_BOOL,
D3DPT_INT,
D3DPT_FLOAT,
D3DPT_STRING,
D3DPT_TEXTURE,
D3DPT_TEXTURE1D,
D3DPT_TEXTURE2D,
D3DPT_TEXTURE3D,
D3DPT_TEXTURECUBE,
D3DPT_SAMPLER,
D3DPT_SAMPLER1D,
D3DPT_SAMPLER2D,
D3DPT_SAMPLER3D,
D3DPT_SAMPLERCUBE,
D3DPT_PIXELSHADER,
D3DPT_VERTEXSHADER,
D3DPT_PIXELFRAGMENT,
D3DPT_VERTEXFRAGMENT
};
enum REGISTER_TYPE
{
D3DRS_BOOL,
D3DRS_INT4,
D3DRS_FLOAT4,
D3DRS_SAMPLER
};
struct ConstantDesc
{
String Name;
S32 RegisterIndex;
S32 RegisterCount;
S32 Rows;
S32 Columns;
S32 Elements;
S32 StructMembers;
REGISTER_TYPE RegisterSet;
CONST_CLASS Class;
CONST_TYPE Type;
U32 Bytes;
};
class ConstantTable
{
public:
bool Create(const void* data);
U32 GetConstantCount() const { return m_constants.size(); }
const String& GetCreator() const { return m_creator; }
const ConstantDesc* GetConstantByIndex(U32 i) const { return &m_constants[i]; }
const ConstantDesc* GetConstantByName(const String& name) const;
void ClearConstants() { m_constants.clear(); }
private:
Vector<ConstantDesc> m_constants;
String m_creator;
};
// Structs
struct CTHeader
{
U32 Size;
U32 Creator;
U32 Version;
U32 Constants;
U32 ConstantInfo;
U32 Flags;
U32 Target;
};
struct CTInfo
{
U32 Name;
U16 RegisterSet;
U16 RegisterIndex;
U16 RegisterCount;
U16 Reserved;
U32 TypeInfo;
U32 DefaultValue;
};
struct CTType
{
U16 Class;
U16 Type;
U16 Rows;
U16 Columns;
U16 Elements;
U16 StructMembers;
U32 StructMemberInfo;
};
// Shader instruction opcodes
const U32 SIO_COMMENT = 0x0000FFFE;
const U32 SIO_END = 0x0000FFFF;
const U32 SI_OPCODE_MASK = 0x0000FFFF;
const U32 SI_COMMENTSIZE_MASK = 0x7FFF0000;
const U32 CTAB_CONSTANT = 0x42415443;
// Member functions
inline bool ConstantTable::Create(const void* data)
{
const U32* ptr = static_cast<const U32*>(data);
while(*++ptr != SIO_END)
{
if((*ptr & SI_OPCODE_MASK) == SIO_COMMENT)
{
// Check for CTAB comment
U32 comment_size = (*ptr & SI_COMMENTSIZE_MASK) >> 16;
if(*(ptr+1) != CTAB_CONSTANT)
{
ptr += comment_size;
continue;
}
// Read header
const char* ctab = reinterpret_cast<const char*>(ptr+2);
size_t ctab_size = (comment_size-1)*4;
const CTHeader* header = reinterpret_cast<const CTHeader*>(ctab);
if(ctab_size < sizeof(*header) || header->Size != sizeof(*header))
return false;
m_creator = ctab + header->Creator;
// Read constants
m_constants.reserve(header->Constants);
const CTInfo* info = reinterpret_cast<const CTInfo*>(ctab + header->ConstantInfo);
for(U32 i = 0; i < header->Constants; ++i)
{
const CTType* type = reinterpret_cast<const CTType*>(ctab + info[i].TypeInfo);
// Fill struct
ConstantDesc desc;
desc.Name = ctab + info[i].Name;
desc.RegisterSet = static_cast<REGISTER_TYPE>(info[i].RegisterSet);
desc.RegisterIndex = info[i].RegisterIndex;
desc.RegisterCount = info[i].RegisterCount;
desc.Rows = type->Rows;
desc.Class = static_cast<CONST_CLASS>(type->Class);
desc.Type = static_cast<CONST_TYPE>(type->Type);
desc.Columns = type->Columns;
desc.Elements = type->Elements;
desc.StructMembers = type->StructMembers;
desc.Bytes = 4 * desc.Elements * desc.Rows * desc.Columns;
m_constants.push_back(desc);
}
return true;
}
}
return false;
}
inline const ConstantDesc* ConstantTable::GetConstantByName(const String& name) const
{
Vector<ConstantDesc>::const_iterator it;
for(it = m_constants.begin(); it != m_constants.end(); ++it)
{
if(it->Name == name)
return &(*it);
}
return NULL;
}
/////////////////// Constant Buffers /////////////////////////////
// Maximum number of CBuffers ($Globals & $Params)
const U32 CBUFFER_MAX = 2;
struct ConstSubBufferDesc
{
U32 start;
U32 size;
ConstSubBufferDesc() : start(0), size(0){}
};
class GFXD3D11ConstBufferLayout : public GenericConstBufferLayout
{
public:
GFXD3D11ConstBufferLayout();
/// Get our constant sub buffer data
Vector<ConstSubBufferDesc> &getSubBufferDesc(){ return mSubBuffers; }
/// We need to manually set the size due to D3D11 alignment
void setSize(U32 size){ mBufferSize = size;}
/// Set a parameter, given a base pointer
virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
protected:
/// Set a matrix, given a base pointer
virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
Vector<ConstSubBufferDesc> mSubBuffers;
};
class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
{
public:
// GFXShaderConstHandle
const String& getName() const;
GFXShaderConstType getType() const;
U32 getArraySize() const;
WeakRefPtr<GFXD3D11Shader> mShader;
bool mVertexConstant;
GenericConstBufferLayout::ParamDesc mVertexHandle;
bool mPixelConstant;
GenericConstBufferLayout::ParamDesc mPixelHandle;
/// Is true if this constant is for hardware mesh instancing.
///
/// Note: We currently store its settings in mPixelHandle.
///
bool mInstancingConstant;
void setValid( bool valid ) { mValid = valid; }
S32 getSamplerRegister() const;
// Returns true if this is a handle to a sampler register.
bool isSampler() const
{
return ( mPixelConstant && mPixelHandle.constType >= GFXSCT_Sampler ) || ( mVertexConstant && mVertexHandle.constType >= GFXSCT_Sampler );
}
/// Restore to uninitialized state.
void clear()
{
mShader = NULL;
mVertexConstant = false;
mPixelConstant = false;
mInstancingConstant = false;
mVertexHandle.clear();
mPixelHandle.clear();
mValid = false;
}
GFXD3D11ShaderConstHandle();
};
/// The D3D11 implementation of a shader constant buffer.
class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
{
friend class GFXD3D11Shader;
public:
GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader,
GFXD3D11ConstBufferLayout* vertexLayout,
GFXD3D11ConstBufferLayout* pixelLayout);
virtual ~GFXD3D11ShaderConstBuffer();
/// Called by GFXD3D11Device to activate this buffer.
/// @param mPrevShaderBuffer The previously active buffer
void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer);
/// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty.
bool isDirty();
/// Called from GFXD3D11Shader when constants have changed and need
/// to be the shader this buffer references is reloaded.
void onShaderReload(GFXD3D11Shader *shader);
// GFXShaderConstBuffer
virtual GFXShader* getShader();
virtual void set(GFXShaderConstHandle* handle, const F32 fv);
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
virtual void set(GFXShaderConstHandle* handle, const ColorF& fv);
virtual void set(GFXShaderConstHandle* handle, const S32 f);
virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
virtual void set(GFXShaderConstHandle* handle, const Point4I& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv);
virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv);
virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4);
virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
// GFXResource
virtual const String describeSelf() const;
virtual void zombify();
virtual void resurrect();
protected:
void _createBuffers();
template<class T>
inline void SET_CONSTANT(GFXShaderConstHandle* handle,
const T& fv,
GenericConstBuffer *vBuffer,
GenericConstBuffer *pBuffer);
// Constant buffers, VSSetConstantBuffers1 has issues on win 7. So unfortunately for now we have multiple constant buffers
ID3D11Buffer* mConstantBuffersV[CBUFFER_MAX];
ID3D11Buffer* mConstantBuffersP[CBUFFER_MAX];
/// We keep a weak reference to the shader
/// because it will often be deleted.
WeakRefPtr<GFXD3D11Shader> mShader;
//vertex
GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
GenericConstBuffer* mVertexConstBuffer;
//pixel
GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
GenericConstBuffer* mPixelConstBuffer;
};
class gfxD3D11Include;
typedef StrongRefPtr<gfxD3D11Include> gfxD3DIncludeRef;
/////////////////// GFXShader implementation /////////////////////////////
class GFXD3D11Shader : public GFXShader
{
friend class GFXD3D11Device;
friend class GFXD3D11ShaderConstBuffer;
public:
typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap;
GFXD3D11Shader();
virtual ~GFXD3D11Shader();
// GFXShader
virtual GFXShaderConstBufferRef allocConstBuffer();
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
virtual bool getDisassembly( String &outStr ) const;
// GFXResource
virtual void zombify();
virtual void resurrect();
protected:
virtual bool _init();
static const U32 smCompiledShaderTag;
ConstantTable table;
ID3D11VertexShader *mVertShader;
ID3D11PixelShader *mPixShader;
GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
static gfxD3DIncludeRef smD3DInclude;
HandleMap mHandles;
/// The shader disassembly from DX when this shader is compiled.
/// We only store this data in non-release builds.
String mDissasembly;
/// Vector of sampler type descriptions consolidated from _compileShader.
Vector<GFXShaderConstDesc> mSamplerDescriptions;
/// Vector of descriptions (consolidated for the getShaderConstDesc call)
Vector<GFXShaderConstDesc> mShaderConsts;
// These two functions are used when compiling shaders from hlsl
virtual bool _compileShader( const Torque::Path &filePath,
const String &target,
const D3D_SHADER_MACRO *defines,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
void _getShaderConstants( ID3D11ShaderReflection* table,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
bool _convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc);
bool _saveCompiledOutput( const Torque::Path &filePath,
ID3DBlob *buffer,
GenericConstBufferLayout *bufferLayout,
Vector<GFXShaderConstDesc> &samplerDescriptions );
// Loads precompiled shaders
bool _loadCompiledOutput( const Torque::Path &filePath,
const String &target,
GenericConstBufferLayout *bufferLayoutF,
Vector<GFXShaderConstDesc> &samplerDescriptions );
// This is used in both cases
virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst);
virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
/// Used to build the instancing shader constants from
/// the instancing vertex format.
void _buildInstancingShaderConstantHandles();
};
inline bool GFXD3D11Shader::getDisassembly(String &outStr) const
{
outStr = mDissasembly;
return (outStr.isNotEmpty());
}
#endif

View file

@ -0,0 +1,285 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/gfxDevice.h"
#include "gfx/D3D11/gfxD3D11StateBlock.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
{
AssertFatal(D3D11DEVICE, "Invalid D3DDevice!");
mDesc = desc;
mCachedHashValue = desc.getHashValue();
// Color writes
mColorMask = 0;
mColorMask |= (mDesc.colorWriteRed ? D3D11_COLOR_WRITE_ENABLE_RED : 0);
mColorMask |= (mDesc.colorWriteGreen ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0);
mColorMask |= (mDesc.colorWriteBlue ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0);
mColorMask |= (mDesc.colorWriteAlpha ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0);
mBlendState = NULL;
for (U32 i = 0; i < GFX->getNumSamplers(); i++)
{
mSamplerStates[i] = NULL;
}
mDepthStencilState = NULL;
mRasterizerState = NULL;
mBlendDesc.AlphaToCoverageEnable = false;
mBlendDesc.IndependentBlendEnable = false;
mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable;
mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp];
mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
HRESULT hr = D3D11DEVICE->CreateBlendState(&mBlendDesc, &mBlendState);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateBlendState call failure.");
}
mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
mDepthStencilDesc.DepthEnable = mDesc.zEnable;
mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc];
mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask;
mDepthStencilDesc.StencilReadMask = mDesc.stencilMask;
mDepthStencilDesc.StencilEnable = mDesc.stencilEnable;
mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc];
mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp];
mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp];
mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp];
mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace;
hr = D3D11DEVICE->CreateDepthStencilState(&mDepthStencilDesc, &mDepthStencilState);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
}
mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode];
mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode];
mRasterizerDesc.DepthBias = mDesc.zBias;
mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias;
mRasterizerDesc.AntialiasedLineEnable = FALSE;
mRasterizerDesc.MultisampleEnable = FALSE;
mRasterizerDesc.ScissorEnable = FALSE;
mRasterizerDesc.DepthClipEnable = TRUE;
mRasterizerDesc.FrontCounterClockwise = FALSE;
mRasterizerDesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
hr = D3D11DEVICE->CreateRasterizerState(&mRasterizerDesc, &mRasterizerState);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateDepthStencilState call failure.");
}
for ( U32 i = 0; i < GFX->getNumSamplers(); i++ )
{
mSamplerDesc[i].AddressU = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeU];
mSamplerDesc[i].AddressV = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeV];
mSamplerDesc[i].AddressW = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeW];
mSamplerDesc[i].MaxAnisotropy = mDesc.samplers[i].maxAnisotropy;
mSamplerDesc[i].MipLODBias = mDesc.samplers[i].mipLODBias;
mSamplerDesc[i].MinLOD = 0;
mSamplerDesc[i].MaxLOD = FLT_MAX;
if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
else
mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC;
mSamplerDesc[i].BorderColor[0] = 1.0f;
mSamplerDesc[i].BorderColor[1] = 1.0f;
mSamplerDesc[i].BorderColor[2] = 1.0f;
mSamplerDesc[i].BorderColor[3] = 1.0f;
mSamplerDesc[i].ComparisonFunc = D3D11_COMPARISON_NEVER;
hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11StateBlock::GFXD3D11StateBlock - CreateSamplerState call failure.");
}
}
}
GFXD3D11StateBlock::~GFXD3D11StateBlock()
{
SAFE_RELEASE(mBlendState);
SAFE_RELEASE(mRasterizerState);
SAFE_RELEASE(mDepthStencilState);
//Use TEXTURE_STAGE_COUNT here, not safe to rely on GFX pointer
for (U32 i = 0; i < TEXTURE_STAGE_COUNT; ++i)
{
SAFE_RELEASE(mSamplerStates[i]);
}
}
/// Returns the hash value of the desc that created this block
U32 GFXD3D11StateBlock::getHashValue() const
{
return mCachedHashValue;
}
/// Returns a GFXStateBlockDesc that this block represents
const GFXStateBlockDesc& GFXD3D11StateBlock::getDesc() const
{
return mDesc;
}
/// Called by D3D11 device to active this state block.
/// @param oldState The current state, used to make sure we don't set redundant states on the device. Pass NULL to reset all states.
void GFXD3D11StateBlock::activate(GFXD3D11StateBlock* oldState)
{
PROFILE_SCOPE( GFXD3D11StateBlock_Activate );
ID3D11DeviceContext* pDevCxt = D3D11DEVICECONTEXT;
mBlendDesc.AlphaToCoverageEnable = false;
mBlendDesc.IndependentBlendEnable = mDesc.separateAlphaBlendEnable;
mBlendDesc.RenderTarget[0].BlendEnable = mDesc.blendEnable;
mBlendDesc.RenderTarget[0].BlendOp = GFXD3D11BlendOp[mDesc.blendOp];
mBlendDesc.RenderTarget[0].BlendOpAlpha = GFXD3D11BlendOp[mDesc.separateAlphaBlendOp];
mBlendDesc.RenderTarget[0].DestBlend = GFXD3D11Blend[mDesc.blendDest];
mBlendDesc.RenderTarget[0].DestBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendDest];
mBlendDesc.RenderTarget[0].SrcBlend = GFXD3D11Blend[mDesc.blendSrc];
mBlendDesc.RenderTarget[0].SrcBlendAlpha = GFXD3D11Blend[mDesc.separateAlphaBlendSrc];
mBlendDesc.RenderTarget[0].RenderTargetWriteMask = mColorMask;
float blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
pDevCxt->OMSetBlendState(mBlendState, blendFactor, 0xFFFFFFFF);
mDepthStencilDesc.DepthWriteMask = mDesc.zWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
mDepthStencilDesc.DepthEnable = mDesc.zEnable;
mDepthStencilDesc.DepthFunc = GFXD3D11CmpFunc[mDesc.zFunc];
mDepthStencilDesc.StencilWriteMask = mDesc.stencilWriteMask;
mDepthStencilDesc.StencilReadMask = mDesc.stencilMask;
mDepthStencilDesc.StencilEnable = mDesc.stencilEnable;
mDepthStencilDesc.FrontFace.StencilFunc = GFXD3D11CmpFunc[mDesc.stencilFunc];
mDepthStencilDesc.FrontFace.StencilFailOp = GFXD3D11StencilOp[mDesc.stencilFailOp];
mDepthStencilDesc.FrontFace.StencilDepthFailOp = GFXD3D11StencilOp[mDesc.stencilZFailOp];
mDepthStencilDesc.FrontFace.StencilPassOp = GFXD3D11StencilOp[mDesc.stencilPassOp];
if (mDesc.stencilEnable)
mDepthStencilDesc.BackFace = mDepthStencilDesc.FrontFace;
else
{
mDepthStencilDesc.BackFace.StencilFunc = GFXD3D11CmpFunc[GFXCmpAlways];
mDepthStencilDesc.BackFace.StencilFailOp = GFXD3D11StencilOp[GFXStencilOpKeep];
mDepthStencilDesc.BackFace.StencilDepthFailOp = GFXD3D11StencilOp[GFXStencilOpKeep];
mDepthStencilDesc.BackFace.StencilPassOp = GFXD3D11StencilOp[GFXStencilOpKeep];
}
pDevCxt->OMSetDepthStencilState(mDepthStencilState, mDesc.stencilRef);
mRasterizerDesc.CullMode = GFXD3D11CullMode[mDesc.cullMode];
mRasterizerDesc.FillMode = GFXD3D11FillMode[mDesc.fillMode];
mRasterizerDesc.DepthBias = mDesc.zBias;
mRasterizerDesc.SlopeScaledDepthBias = mDesc.zSlopeBias;
mRasterizerDesc.AntialiasedLineEnable = FALSE;
mRasterizerDesc.MultisampleEnable = FALSE;
mRasterizerDesc.ScissorEnable = FALSE;
if (mDesc.zEnable)
mRasterizerDesc.DepthClipEnable = true;
else
mRasterizerDesc.DepthClipEnable = false;
mRasterizerDesc.FrontCounterClockwise = FALSE;
mRasterizerDesc.DepthBiasClamp = 0.0f;
pDevCxt->RSSetState(mRasterizerState);
U32 numSamplers = GFX->getNumSamplers();
for (U32 i = 0; i < numSamplers; i++)
{
mSamplerDesc[i].AddressU = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeU];
mSamplerDesc[i].AddressV = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeV];
mSamplerDesc[i].AddressW = GFXD3D11TextureAddress[mDesc.samplers[i].addressModeW];
mSamplerDesc[i].MaxAnisotropy = mDesc.samplers[i].maxAnisotropy;
mSamplerDesc[i].MipLODBias = mDesc.samplers[i].mipLODBias;
mSamplerDesc[i].MinLOD = 0;
mSamplerDesc[i].MaxLOD = FLT_MAX;
if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterPoint && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterPoint && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterPoint)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
else if(mDesc.samplers[i].magFilter == GFXTextureFilterLinear && mDesc.samplers[i].minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
else
mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC;
mSamplerDesc[i].BorderColor[0] = 0.0f;
mSamplerDesc[i].BorderColor[1] = 0.0f;
mSamplerDesc[i].BorderColor[2] = 0.0f;
mSamplerDesc[i].BorderColor[3] = 0.0f;
mSamplerDesc[i].ComparisonFunc = D3D11_COMPARISON_NEVER;
}
//TODO samplers for vertex shader
// Set all the samplers with one call
//pDevCxt->VSSetSamplers(0, numSamplers, &mSamplerStates[0]);
pDevCxt->PSSetSamplers(0, numSamplers, &mSamplerStates[0]);
}

View file

@ -0,0 +1,76 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11STATEBLOCK_H_
#define _GFXD3D11STATEBLOCK_H_
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/gfxStateBlock.h"
class GFXD3D11StateBlock : public GFXStateBlock
{
public:
GFXD3D11StateBlock(const GFXStateBlockDesc& desc);
virtual ~GFXD3D11StateBlock();
/// Called by D3D11 device to active this state block.
/// @param oldState The current state, used to make sure we don't set redundant states on the device. Pass NULL to reset all states.
void activate(GFXD3D11StateBlock* oldState);
//
// GFXStateBlock interface
//
/// Returns the hash value of the desc that created this block
virtual U32 getHashValue() const;
/// Returns a GFXStateBlockDesc that this block represents
virtual const GFXStateBlockDesc& getDesc() const;
//
// GFXResource
//
virtual void zombify() { }
/// When called the resource should restore all device sensitive information destroyed by zombify()
virtual void resurrect() { }
private:
D3D11_BLEND_DESC mBlendDesc;
D3D11_RASTERIZER_DESC mRasterizerDesc;
D3D11_DEPTH_STENCIL_DESC mDepthStencilDesc;
D3D11_SAMPLER_DESC mSamplerDesc[TEXTURE_STAGE_COUNT];
ID3D11BlendState* mBlendState;
ID3D11DepthStencilState* mDepthStencilState;
ID3D11RasterizerState* mRasterizerState;
ID3D11SamplerState* mSamplerStates[TEXTURE_STAGE_COUNT];
GFXStateBlockDesc mDesc;
U32 mCachedHashValue;
// Cached D3D specific things, these are "calculated" from GFXStateBlock
U32 mColorMask;
};
typedef StrongRefPtr<GFXD3D11StateBlock> GFXD3D11StateBlockRef;
#endif

View file

@ -0,0 +1,409 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/D3D11/gfxD3D11Target.h"
#include "gfx/D3D11/gfxD3D11Cubemap.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/gfxDebugEvent.h"
#include "gfx/gfxStringEnumTranslate.h"
#include "windowManager/win32/win32Window.h"
GFXD3D11TextureTarget::GFXD3D11TextureTarget()
: mTargetSize( Point2I::Zero ),
mTargetFormat( GFXFormatR8G8B8A8 )
{
for(S32 i=0; i<MaxRenderSlotId; i++)
{
mTargets[i] = NULL;
mResolveTargets[i] = NULL;
mTargetViews[i] = NULL;
mTargetSRViews[i] = NULL;
}
}
GFXD3D11TextureTarget::~GFXD3D11TextureTarget()
{
// Release anything we might be holding.
for(S32 i=0; i<MaxRenderSlotId; i++)
{
mResolveTargets[i] = NULL;
SAFE_RELEASE(mTargetViews[i]);
SAFE_RELEASE(mTargets[i]);
SAFE_RELEASE(mTargetSRViews[i]);
}
zombify();
}
void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXTextureObject *tex, U32 mipLevel/*=0*/, U32 zOffset /*= 0*/ )
{
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture, ColorI::RED );
AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::attachTexture - out of range slot.");
// TODO: The way this is implemented... you can attach a texture
// object multiple times and it will release and reset it.
//
// We should rework this to detect when no change has occured
// and skip out early.
// Mark state as dirty so device can know to update.
invalidateState();
// Release what we had, it's definitely going to change.
SAFE_RELEASE(mTargetViews[slot]);
SAFE_RELEASE(mTargets[slot]);
SAFE_RELEASE(mTargetSRViews[slot]);
mResolveTargets[slot] = NULL;
if(slot == Color0)
{
mTargetSize = Point2I::Zero;
mTargetFormat = GFXFormatR8G8B8A8;
}
// Are we clearing?
if(!tex)
{
// Yup - just exit, it'll stay NULL.
return;
}
// TODO: Mip map generation currently only supported on dynamic cubemaps
mTargetSRViews[slot] = NULL;
// Take care of default targets
if( tex == GFXTextureTarget::sDefaultDepthStencil )
{
mTargets[slot] = D3D11->mDeviceDepthStencil;
mTargetViews[slot] = D3D11->mDeviceDepthStencilView;
mTargets[slot]->AddRef();
mTargetViews[slot]->AddRef();
}
else
{
// Cast the texture object to D3D...
AssertFatal(static_cast<GFXD3D11TextureObject*>(tex), "GFXD3D11TextureTarget::attachTexture - invalid texture object.");
GFXD3D11TextureObject *d3dto = static_cast<GFXD3D11TextureObject*>(tex);
// Grab the surface level.
if( slot == DepthStencil )
{
mTargets[slot] = d3dto->getSurface();
if ( mTargets[slot] )
mTargets[slot]->AddRef();
mTargetViews[slot] = d3dto->getDSView();
if( mTargetViews[slot])
mTargetViews[slot]->AddRef();
}
else
{
// getSurface will almost always return NULL. It will only return non-NULL
// if the surface that it needs to render to is different than the mip level
// in the actual texture. This will happen with MSAA.
if( d3dto->getSurface() == NULL )
{
mTargets[slot] = d3dto->get2DTex();
mTargets[slot]->AddRef();
mTargetViews[slot] = d3dto->getRTView();
mTargetViews[slot]->AddRef();
}
else
{
mTargets[slot] = d3dto->getSurface();
mTargets[slot]->AddRef();
mTargetViews[slot]->AddRef();
// Only assign resolve target if d3dto has a surface to give us.
//
// That usually means there is an MSAA target involved, which is why
// the resolve is needed to get the data out of the target.
mResolveTargets[slot] = d3dto;
if ( tex && slot == Color0 )
{
mTargetSize.set( tex->getSize().x, tex->getSize().y );
mTargetFormat = tex->getFormat();
}
}
}
// Update surface size
if(slot == Color0)
{
ID3D11Texture2D *surface = mTargets[Color0];
if ( surface )
{
D3D11_TEXTURE2D_DESC sd;
surface->GetDesc(&sd);
mTargetSize = Point2I(sd.Width, sd.Height);
S32 format = sd.Format;
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
mTargetFormat = (GFXFormat)format;
}
}
}
}
void GFXD3D11TextureTarget::attachTexture( RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel/*=0*/ )
{
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_attachTexture_Cubemap, ColorI::RED );
AssertFatal(slot < MaxRenderSlotId, "GFXD3D11TextureTarget::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.
SAFE_RELEASE(mTargetViews[slot]);
SAFE_RELEASE(mTargets[slot]);
SAFE_RELEASE(mTargetSRViews[slot]);
mResolveTargets[slot] = NULL;
// Cast the texture object to D3D...
AssertFatal(!tex || static_cast<GFXD3D11Cubemap*>(tex), "GFXD3DTextureTarget::attachTexture - invalid cubemap object.");
if(slot == Color0)
{
mTargetSize = Point2I::Zero;
mTargetFormat = GFXFormatR8G8B8A8;
}
// Are we clearing?
if(!tex)
{
// Yup - just exit, it'll stay NULL.
return;
}
GFXD3D11Cubemap *cube = static_cast<GFXD3D11Cubemap*>(tex);
mTargets[slot] = cube->get2DTex();
mTargets[slot]->AddRef();
mTargetViews[slot] = cube->getRTView(face);
mTargetViews[slot]->AddRef();
mTargetSRViews[slot] = cube->getSRView();
mTargetSRViews[slot]->AddRef();
// Update surface size
if(slot == Color0)
{
ID3D11Texture2D *surface = mTargets[Color0];
if ( surface )
{
D3D11_TEXTURE2D_DESC sd;
surface->GetDesc(&sd);
mTargetSize = Point2I(sd.Width, sd.Height);
S32 format = sd.Format;
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
mTargetFormat = (GFXFormat)format;
}
}
}
void GFXD3D11TextureTarget::activate()
{
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_activate, ColorI::RED );
AssertFatal( mTargets[GFXTextureTarget::Color0], "GFXD3D11TextureTarget::activate() - You can never have a NULL primary render target!" );
// Clear the state indicator.
stateApplied();
// Now set all the new surfaces into the appropriate slots.
ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL};
ID3D11DepthStencilView* dsView = (ID3D11DepthStencilView*)(mTargetViews[GFXTextureTarget::DepthStencil]);
for (U32 i = 0; i < 4; i++)
{
rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
}
D3D11DEVICECONTEXT->OMSetRenderTargets(MaxRenderSlotId, rtViews, dsView);
}
void GFXD3D11TextureTarget::deactivate()
{
//re-gen mip maps
for (U32 i = 0; i < 4; i++)
{
ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
if (pSRView)
D3D11DEVICECONTEXT->GenerateMips(pSRView);
}
}
void GFXD3D11TextureTarget::resolve()
{
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_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])
{
D3D11_TEXTURE2D_DESC desc;
mTargets[i]->GetDesc(&desc);
D3D11DEVICECONTEXT->CopySubresourceRegion(mResolveTargets[i]->get2DTex(), 0, 0, 0, 0, mTargets[i], 0, NULL);
}
}
}
void GFXD3D11TextureTarget::resolveTo( GFXTextureObject *tex )
{
GFXDEBUGEVENT_SCOPE( GFXPCD3D11TextureTarget_resolveTo, ColorI::RED );
if ( mTargets[Color0] == NULL )
return;
D3D11_TEXTURE2D_DESC desc;
mTargets[Color0]->GetDesc(&desc);
D3D11DEVICECONTEXT->CopySubresourceRegion(((GFXD3D11TextureObject*)(tex))->get2DTex(), 0, 0, 0, 0, mTargets[Color0], 0, NULL);
}
void GFXD3D11TextureTarget::zombify()
{
for(U32 i = 0; i < MaxRenderSlotId; i++)
attachTexture(RenderSlot(i), NULL);
}
void GFXD3D11TextureTarget::resurrect()
{
}
GFXD3D11WindowTarget::GFXD3D11WindowTarget()
{
mWindow = NULL;
mBackbuffer = NULL;
}
GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
{
SAFE_RELEASE(mBackbuffer);
}
void GFXD3D11WindowTarget::initPresentationParams()
{
// Get some video mode related info.
GFXVideoMode vm = mWindow->getVideoMode();
Win32Window* win = static_cast<Win32Window*>(mWindow);
HWND hwnd = win->getHWND();
mPresentationParams = D3D11->setupPresentParams(vm, hwnd);
}
const Point2I GFXD3D11WindowTarget::getSize()
{
return mWindow->getVideoMode().resolution;
}
GFXFormat GFXD3D11WindowTarget::getFormat()
{
S32 format = mPresentationParams.BufferDesc.Format;
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, format );
return (GFXFormat)format;
}
bool GFXD3D11WindowTarget::present()
{
return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK);
}
void GFXD3D11WindowTarget::setImplicitSwapChain()
{
if (!mBackbuffer)
D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer);
}
void GFXD3D11WindowTarget::resetMode()
{
mWindow->setSuppressReset(true);
// Setup our presentation params.
initPresentationParams();
// Otherwise, we have to reset the device, if we're the implicit swapchain.
D3D11->reset(mPresentationParams);
// Update our size, too.
mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
mWindow->setSuppressReset(false);
GFX->beginReset();
}
void GFXD3D11WindowTarget::zombify()
{
SAFE_RELEASE(mBackbuffer);
}
void GFXD3D11WindowTarget::resurrect()
{
setImplicitSwapChain();
}
void GFXD3D11WindowTarget::activate()
{
GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_activate, ColorI::RED);
//clear ther rendertargets first
ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
D3D11DEVICECONTEXT->OMSetRenderTargets(1, &D3D11->mDeviceBackBufferView, D3D11->mDeviceDepthStencilView);
DXGI_SWAP_CHAIN_DESC pp;
D3D11->mSwapChain->GetDesc(&pp);
// Update our video mode here, too.
GFXVideoMode vm;
vm = mWindow->getVideoMode();
vm.resolution.x = pp.BufferDesc.Width;
vm.resolution.y = pp.BufferDesc.Height;
vm.fullScreen = !pp.Windowed;
mSize = vm.resolution;
}
void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
{
GFXDEBUGEVENT_SCOPE(GFXPCD3D11WindowTarget_resolveTo, ColorI::RED);
D3D11_TEXTURE2D_DESC desc;
ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
surf->GetDesc(&desc);
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format);
}

View file

@ -0,0 +1,110 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFX_D3D_GFXD3D11TARGET_H_
#define _GFX_D3D_GFXD3D11TARGET_H_
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11TextureObject.h"
#include "gfx/gfxTarget.h"
#include "math/mPoint3.h"
#include "math/mPoint2.h"
class GFXD3D11TextureTarget : public GFXTextureTarget
{
friend class GFXD3D11Device;
// Array of target surfaces, this is given to us by attachTexture
ID3D11Texture2D* mTargets[MaxRenderSlotId];
// Array of shader resource views
ID3D11ShaderResourceView* mTargetSRViews[MaxRenderSlotId];
//ID3D11DepthStencilView* mDepthTargetView;
ID3D11View* mTargetViews[MaxRenderSlotId];
// Array of texture objects which correspond to the target surfaces above,
// needed for copy from RenderTarget to texture situations. Current only valid in those situations
GFXD3D11TextureObject* mResolveTargets[MaxRenderSlotId];
Point2I mTargetSize;
GFXFormat mTargetFormat;
public:
GFXD3D11TextureTarget();
~GFXD3D11TextureTarget();
// Public interface.
virtual const Point2I getSize() { return mTargetSize; }
virtual GFXFormat getFormat() { return mTargetFormat; }
virtual void attachTexture(RenderSlot slot, GFXTextureObject *tex, U32 mipLevel=0, U32 zOffset = 0);
virtual void attachTexture(RenderSlot slot, GFXCubemap *tex, U32 face, U32 mipLevel=0);
virtual void resolve();
/// Note we always copy the Color0 RenderSlot.
virtual void resolveTo( GFXTextureObject *tex );
virtual void activate();
virtual void deactivate();
void zombify();
void resurrect();
};
class GFXD3D11WindowTarget : public GFXWindowTarget
{
friend class GFXD3D11Device;
/// Our backbuffer
ID3D11Texture2D *mBackbuffer;
/// Maximum size we can render to.
Point2I mSize;
/// D3D presentation info.
DXGI_SWAP_CHAIN_DESC mPresentationParams;
/// Internal interface that notifies us we need to reset our video mode.
void resetMode();
public:
GFXD3D11WindowTarget();
~GFXD3D11WindowTarget();
virtual const Point2I getSize();
virtual GFXFormat getFormat();
virtual bool present();
void initPresentationParams();
void setImplicitSwapChain();
virtual void activate();
void zombify();
void resurrect();
virtual void resolveTo( GFXTextureObject *tex );
};
#endif

View file

@ -0,0 +1,587 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/bitmap/bitmapUtils.h"
#include "gfx/gfxCardProfile.h"
#include "gfx/gfxStringEnumTranslate.h"
#include "core/strings/unicode.h"
#include "core/util/swizzle.h"
#include "core/util/safeDelete.h"
#include "console/console.h"
#include "core/resourceManager.h"
GFXD3D11TextureManager::GFXD3D11TextureManager()
{
ZeroMemory(mCurTexSet, sizeof(mCurTexSet));
}
GFXD3D11TextureManager::~GFXD3D11TextureManager()
{
// Destroy texture table now so just in case some texture objects
// are still left, we don't crash on a pure virtual method call.
SAFE_DELETE_ARRAY( mHashTable );
}
void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
U32 height,
U32 width,
U32 depth,
GFXFormat format,
GFXTextureProfile *profile,
U32 numMipLevels,
bool forceMips,
S32 antialiasLevel)
{
U32 usage = 0;
U32 bindFlags = 0;
U32 miscFlags = 0;
if(!retTex->mProfile->isZTarget() && !retTex->mProfile->isSystemMemory())
bindFlags = D3D11_BIND_SHADER_RESOURCE;
U32 cpuFlags = 0;
retTex->mProfile = profile;
retTex->isManaged = false;
DXGI_FORMAT d3dTextureFormat = GFXD3D11TextureFormat[format];
if( retTex->mProfile->isDynamic() )
{
usage = D3D11_USAGE_DYNAMIC;
cpuFlags |= D3D11_CPU_ACCESS_WRITE;
retTex->isManaged = false;
}
else if ( retTex->mProfile->isSystemMemory() )
{
usage |= D3D11_USAGE_STAGING;
cpuFlags |= D3D11_CPU_ACCESS_READ;
}
else
{
usage = D3D11_USAGE_DEFAULT;
retTex->isManaged = true;
}
if( retTex->mProfile->isRenderTarget() )
{
bindFlags |= D3D11_BIND_RENDER_TARGET;
//need to check to make sure this format supports render targets
U32 supportFlag = 0;
D3D11DEVICE->CheckFormatSupport(d3dTextureFormat, &supportFlag);
//if it doesn't support render targets then default to R8G8B8A8
if(!(supportFlag & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
d3dTextureFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
retTex->isManaged =false;
}
if( retTex->mProfile->isZTarget() )
{
bindFlags |= D3D11_BIND_DEPTH_STENCIL;
retTex->isManaged = false;
}
if( !forceMips && !retTex->mProfile->isSystemMemory() &&
numMipLevels == 0 &&
!(depth > 0) )
{
miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
bindFlags |= D3D11_BIND_RENDER_TARGET; // in order to automatically generate mips. Resource needs to be a rendertarget and shader resource
}
if( depth > 0 )
{
D3D11_TEXTURE3D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE3D_DESC));
desc.BindFlags = bindFlags;
desc.CPUAccessFlags = cpuFlags;
desc.Depth = depth;
desc.Width = width;
desc.Height = height;
desc.Format = d3dTextureFormat;
desc.Usage = (D3D11_USAGE)usage;
desc.MipLevels = numMipLevels;
HRESULT hr = D3D11DEVICE->CreateTexture3D(&desc, NULL, retTex->get3DTexPtr());
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11TextureManager::_createTexture - failed to create volume texture!");
}
retTex->mTextureSize.set(width, height, depth);
retTex->get3DTex()->GetDesc(&desc);
retTex->mMipLevels = numMipLevels;
retTex->mFormat = format;
}
else
{
UINT numQualityLevels = 0;
switch (antialiasLevel)
{
case 0:
case AA_MATCH_BACKBUFFER:
antialiasLevel = 1;
break;
default:
{
antialiasLevel = 0;
UINT numQualityLevels;
D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
AssertFatal(numQualityLevels, "Invalid AA level!");
break;
}
}
if(retTex->mProfile->isZTarget())
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.ArraySize = 1;
desc.BindFlags = bindFlags;
desc.CPUAccessFlags = cpuFlags;
//depth stencil must be a typeless format if it is bound on render target and shader resource simultaneously
// we'll send the real format for the creation of the views
desc.Format = DXGI_FORMAT_R24G8_TYPELESS;
desc.MipLevels = numMipLevels;
desc.SampleDesc.Count = antialiasLevel;
desc.SampleDesc.Quality = numQualityLevels;
desc.Height = height;
desc.Width = width;
desc.Usage = (D3D11_USAGE)usage;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, retTex->getSurfacePtr());
if(FAILED(hr))
{
AssertFatal(false, "Failed to create Zbuffer texture");
}
retTex->mFormat = format; // Assigning format like this should be fine.
}
else
{
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.ArraySize = 1;
desc.BindFlags = bindFlags;
desc.CPUAccessFlags = cpuFlags;
desc.Format = d3dTextureFormat;
desc.MipLevels = numMipLevels;
desc.SampleDesc.Count = antialiasLevel;
desc.SampleDesc.Quality = numQualityLevels;
desc.Height = height;
desc.Width = width;
desc.Usage = (D3D11_USAGE)usage;
desc.MiscFlags = miscFlags;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, retTex->get2DTexPtr());
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11TextureManager::_createTexture - failed to create texture!");
}
retTex->get2DTex()->GetDesc(&desc);
retTex->mMipLevels = desc.MipLevels;
}
// start creating the resource views...
// don't bother creating views for system memory/staging textures
// they are just used for copying
if (!retTex->mProfile->isSystemMemory())
{
createResourceView(height, width, depth, d3dTextureFormat, numMipLevels, bindFlags, retTex);
}
// Get the actual size of the texture...
D3D11_TEXTURE2D_DESC probeDesc;
ZeroMemory(&probeDesc, sizeof(D3D11_TEXTURE2D_DESC));
if( retTex->get2DTex() != NULL )
{
retTex->get2DTex()->GetDesc(&probeDesc);
}
else if( retTex->getSurface() != NULL )
{
retTex->getSurface()->GetDesc(&probeDesc);
}
retTex->mTextureSize.set(probeDesc.Width, probeDesc.Height, 0);
S32 fmt = 0;
if(!profile->isZTarget())
fmt = probeDesc.Format;
else
fmt = DXGI_FORMAT_D24_UNORM_S8_UINT; // we need to assign this manually.
GFXREVERSE_LOOKUP( GFXD3D11TextureFormat, GFXFormat, fmt );
retTex->mFormat = (GFXFormat)fmt;
}
}
//-----------------------------------------------------------------------------
// createTexture
//-----------------------------------------------------------------------------
GFXTextureObject *GFXD3D11TextureManager::_createTextureObject( U32 height,
U32 width,
U32 depth,
GFXFormat format,
GFXTextureProfile *profile,
U32 numMipLevels,
bool forceMips,
S32 antialiasLevel,
GFXTextureObject *inTex )
{
GFXD3D11TextureObject *retTex;
if ( inTex )
{
AssertFatal(static_cast<GFXD3D11TextureObject*>( inTex ), "GFXD3D11TextureManager::_createTexture() - Bad inTex type!");
retTex = static_cast<GFXD3D11TextureObject*>( inTex );
retTex->release();
}
else
{
retTex = new GFXD3D11TextureObject(GFX, profile);
retTex->registerResourceWithDevice(GFX);
}
_innerCreateTexture(retTex, height, width, depth, format, profile, numMipLevels, forceMips, antialiasLevel);
return retTex;
}
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *pDL)
{
PROFILE_SCOPE(GFXD3D11TextureManager_loadTexture);
GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture);
// Check with profiler to see if we can do automatic mipmap generation.
const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
// Helper bool
const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5;
// Settings for mipmap generation
U32 maxDownloadMip = pDL->getNumMipLevels();
U32 nbMipMapLevel = pDL->getNumMipLevels();
if( supportsAutoMips && !isCompressedTexFmt )
{
maxDownloadMip = 1;
nbMipMapLevel = aTexture->mMipLevels;
}
GFXD3D11Device* dev = D3D11;
bool isDynamic = texture->mProfile->isDynamic();
// Fill the texture...
for( U32 i = 0; i < maxDownloadMip; i++ )
{
U32 subResource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels);
if(!isDynamic)
{
U8* copyBuffer = NULL;
switch(texture->mFormat)
{
case GFXFormatR8G8B8:
{
PROFILE_SCOPE(Swizzle24_Upload);
AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i));
copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4);
dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * 4, pDL->getHeight() *4);
SAFE_DELETE_ARRAY(Bits);
break;
}
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
{
PROFILE_SCOPE(Swizzle32_Upload);
copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()];
dev->getDeviceSwizzle32()->ToBuffer(copyBuffer, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, copyBuffer, pDL->getWidth() * pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel());
break;
}
default:
{
// Just copy the bits in no swizzle or padding
PROFILE_SCOPE(SwizzleNull_Upload);
AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch");
dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subResource, NULL, pDL->getBits(i), pDL->getWidth() *pDL->getBytesPerPixel(), pDL->getHeight() *pDL->getBytesPerPixel());
}
}
SAFE_DELETE_ARRAY(copyBuffer);
}
else
{
D3D11_MAPPED_SUBRESOURCE mapping;
HRESULT res = dev->getDeviceContext()->Map(texture->get2DTex(), subResource, D3D11_MAP_WRITE, 0, &mapping);
AssertFatal(res, "tex2d map call failure");
switch( texture->mFormat )
{
case GFXFormatR8G8B8:
{
PROFILE_SCOPE(Swizzle24_Upload);
AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
bitmapConvertRGB_to_RGBX(&Bits, pDL->getWidth(i) * pDL->getHeight(i));
dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, Bits, pDL->getWidth(i) * pDL->getHeight(i) * 4);
SAFE_DELETE_ARRAY(Bits);
}
break;
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
{
PROFILE_SCOPE(Swizzle32_Upload);
dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
}
break;
default:
{
// Just copy the bits in no swizzle or padding
PROFILE_SCOPE(SwizzleNull_Upload);
AssertFatal( pDL->getFormat() == texture->mFormat, "Format mismatch");
dMemcpy(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
}
}
dev->getDeviceContext()->Unmap(texture->get2DTex(), subResource);
}
}
D3D11_TEXTURE2D_DESC desc;
// if the texture asked for mip generation. lets generate it.
texture->get2DTex()->GetDesc(&desc);
if (desc.MiscFlags &D3D11_RESOURCE_MISC_GENERATE_MIPS)
{
dev->getDeviceContext()->GenerateMips(texture->getSRView());
//texture->mMipLevels = desc.MipLevels;
}
return true;
}
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
{
PROFILE_SCOPE(GFXD3D11TextureManager_loadTextureRaw);
GFXD3D11TextureObject *texture = (GFXD3D11TextureObject *) inTex;
GFXD3D11Device* dev = static_cast<GFXD3D11Device *>(GFX);
// currently only for volume textures...
if(texture->getDepth() < 1) return false;
U8* Bits = NULL;
if(texture->mFormat == GFXFormatR8G8B8)
{
// convert 24 bit to 32 bit
Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
dMemcpy(Bits, raw, texture->getWidth() * texture->getHeight() * texture->getDepth() * 3);
bitmapConvertRGB_to_RGBX(&Bits, texture->getWidth() * texture->getHeight() * texture->getDepth());
}
U32 bytesPerPix = 1;
switch(texture->mFormat)
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
bytesPerPix = 4;
break;
}
D3D11_BOX box;
box.left = 0;
box.right = texture->getWidth();
box.front = 0;
box.back = texture->getDepth();
box.top = 0;
box.bottom = texture->getHeight();
if(texture->mFormat == GFXFormatR8G8B8) // converted format also for volume textures
dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, Bits, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
else
dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, raw, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
SAFE_DELETE_ARRAY(Bits);
return true;
}
bool GFXD3D11TextureManager::_refreshTexture(GFXTextureObject *texture)
{
U32 usedStrategies = 0;
GFXD3D11TextureObject *realTex = static_cast<GFXD3D11TextureObject *>(texture);
if(texture->mProfile->doStoreBitmap())
{
if(texture->mBitmap)
_loadTexture(texture, texture->mBitmap);
if(texture->mDDS)
_loadTexture(texture, texture->mDDS);
usedStrategies++;
}
if(texture->mProfile->isRenderTarget() || texture->mProfile->isDynamic() || texture->mProfile->isZTarget())
{
realTex->release();
_innerCreateTexture(realTex, texture->getHeight(), texture->getWidth(), texture->getDepth(), texture->mFormat, texture->mProfile, texture->mMipLevels, false, texture->mAntialiasLevel);
usedStrategies++;
}
AssertFatal(usedStrategies < 2, "GFXD3D11TextureManager::_refreshTexture - Inconsistent profile flags!");
return true;
}
bool GFXD3D11TextureManager::_freeTexture(GFXTextureObject *texture, bool zombify)
{
AssertFatal(dynamic_cast<GFXD3D11TextureObject *>(texture),"Not an actual d3d texture object!");
GFXD3D11TextureObject *tex = static_cast<GFXD3D11TextureObject *>( texture );
// If it's a managed texture and we're zombifying, don't blast it, D3D allows
// us to keep it.
if(zombify && tex->isManaged)
return true;
tex->release();
return true;
}
/// Load a texture from a proper DDSFile instance.
bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
{
PROFILE_SCOPE(GFXD3D11TextureManager_loadTextureDDS);
GFXD3D11TextureObject *texture = static_cast<GFXD3D11TextureObject*>(aTexture);
GFXD3D11Device* dev = static_cast<GFXD3D11Device *>(GFX);
// Fill the texture...
for( U32 i = 0; i < aTexture->mMipLevels; i++ )
{
PROFILE_SCOPE(GFXD3DTexMan_loadSurface);
AssertFatal( dds->mSurfaces.size() > 0, "Assumption failed. DDSFile has no surfaces." );
U32 subresource = D3D11CalcSubresource(i, 0, aTexture->mMipLevels);
dev->getDeviceContext()->UpdateSubresource(texture->get2DTex(), subresource, 0, dds->mSurfaces[0]->mMips[i], dds->getSurfacePitch(i), 0);
}
D3D11_TEXTURE2D_DESC desc;
// if the texture asked for mip generation. lets generate it.
texture->get2DTex()->GetDesc(&desc);
if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
dev->getDeviceContext()->GenerateMips(texture->getSRView());
return true;
}
void GFXD3D11TextureManager::createResourceView(U32 height, U32 width, U32 depth, DXGI_FORMAT format, U32 numMipLevels,U32 usageFlags, GFXTextureObject *inTex)
{
GFXD3D11TextureObject *tex = static_cast<GFXD3D11TextureObject*>(inTex);
ID3D11Resource* resource = NULL;
if(tex->get2DTex())
resource = tex->get2DTex();
else if(tex->getSurface())
resource = tex->getSurface();
else
resource = tex->get3DTex();
HRESULT hr;
//TODO: add MSAA support later.
if(usageFlags & D3D11_BIND_SHADER_RESOURCE)
{
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
if(usageFlags & D3D11_BIND_DEPTH_STENCIL)
desc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; // reads the depth
else
desc.Format = format;
if(depth > 0)
{
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
desc.Texture3D.MipLevels = -1;
desc.Texture3D.MostDetailedMip = 0;
}
else
{
desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipLevels = -1;
desc.Texture2D.MostDetailedMip = 0;
}
hr = D3D11DEVICE->CreateShaderResourceView(resource,&desc, tex->getSRViewPtr());
AssertFatal(SUCCEEDED(hr), "CreateShaderResourceView:: failed to create view!");
}
if(usageFlags & D3D11_BIND_RENDER_TARGET)
{
D3D11_RENDER_TARGET_VIEW_DESC desc;
desc.Format = format;
desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = 0;
hr = D3D11DEVICE->CreateRenderTargetView(resource, &desc, tex->getRTViewPtr());
AssertFatal(SUCCEEDED(hr), "CreateRenderTargetView:: failed to create view!");
}
if(usageFlags & D3D11_BIND_DEPTH_STENCIL)
{
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
desc.Format = format;
desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = 0;
desc.Flags = 0;
hr = D3D11DEVICE->CreateDepthStencilView(resource,&desc, tex->getDSViewPtr());
AssertFatal(SUCCEEDED(hr), "CreateDepthStencilView:: failed to create view!");
}
}

View file

@ -0,0 +1,62 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3DTEXTUREMANAGER_H_
#define _GFXD3DTEXTUREMANAGER_H_
#include "gfx/D3D11/gfxD3D11TextureObject.h"
#include "core/util/safeRelease.h"
class GFXD3D11TextureManager : public GFXTextureManager
{
friend class GFXD3D11TextureObject;
public:
GFXD3D11TextureManager();
virtual ~GFXD3D11TextureManager();
void createResourceView(U32 height, U32 width, U32 depth, DXGI_FORMAT format, U32 numMipLevels,U32 usageFlags, GFXTextureObject *inTex);
protected:
// GFXTextureManager
GFXTextureObject *_createTextureObject( U32 height,
U32 width,
U32 depth,
GFXFormat format,
GFXTextureProfile *profile,
U32 numMipLevels,
bool forceMips = false,
S32 antialiasLevel = 0,
GFXTextureObject *inTex = NULL );
bool _loadTexture(GFXTextureObject *texture, DDSFile *dds);
bool _loadTexture(GFXTextureObject *texture, GBitmap *bmp);
bool _loadTexture(GFXTextureObject *texture, void *raw);
bool _refreshTexture(GFXTextureObject *texture);
bool _freeTexture(GFXTextureObject *texture, bool zombify = false);
private:
U32 mCurTexSet[TEXTURE_STAGE_COUNT];
void _innerCreateTexture(GFXD3D11TextureObject *obj, U32 height, U32 width, U32 depth, GFXFormat format, GFXTextureProfile *profile, U32 numMipLevels, bool forceMips = false, S32 antialiasLevel = 0);
};
#endif

View file

@ -0,0 +1,280 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11TextureObject.h"
#include "platform/profiler.h"
#include "console/console.h"
#ifdef TORQUE_DEBUG
U32 GFXD3D11TextureObject::mTexCount = 0;
#endif
// GFXFormatR8G8B8 has now the same behaviour as GFXFormatR8G8B8X8.
// This is because 24 bit format are now deprecated by microsoft, for data alignment reason there's no changes beetween 24 and 32 bit formats.
// DirectX 10-11 both have 24 bit format no longer.
GFXD3D11TextureObject::GFXD3D11TextureObject( GFXDevice * d, GFXTextureProfile *profile) : GFXTextureObject( d, profile )
{
#ifdef D3D11_DEBUG_SPEW
mTexCount++;
Con::printf("+ texMake %d %x", mTexCount, this);
#endif
mD3DTexture = NULL;
mLocked = false;
mD3DSurface = NULL;
mLockedSubresource = 0;
mDSView = NULL;
mRTView = NULL;
mSRView = NULL;
}
GFXD3D11TextureObject::~GFXD3D11TextureObject()
{
kill();
#ifdef D3D11_DEBUG_SPEW
mTexCount--;
Con::printf("+ texkill %d %x", mTexCount, this);
#endif
}
GFXLockedRect *GFXD3D11TextureObject::lock(U32 mipLevel /*= 0*/, RectI *inRect /*= NULL*/)
{
AssertFatal( !mLocked, "GFXD3D11TextureObject::lock - The texture is already locked!" );
D3D11_MAPPED_SUBRESOURCE mapInfo;
if( mProfile->isRenderTarget() )
{
//AssertFatal( 0, "GFXD3D11TextureObject::lock - Need to handle mapping render targets" );
if( !mLockTex ||
mLockTex->getWidth() != getWidth() ||
mLockTex->getHeight() != getHeight() )
{
mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
}
PROFILE_START(GFXD3D11TextureObject_lockRT);
GFXD3D11Device* dev = D3D11;
GFXD3D11TextureObject* to = (GFXD3D11TextureObject*) &(*mLockTex);
dev->getDeviceContext()->CopyResource(to->get2DTex(), mD3DTexture);
mLockedSubresource = D3D11CalcSubresource(0, 0, 1);
HRESULT hr = dev->getDeviceContext()->Map(to->get2DTex(), mLockedSubresource, D3D11_MAP_READ, 0, &mapInfo);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11TextureObject:lock- failed to map render target resource!");
mLocked = true;
PROFILE_END();
}
else
{
RECT r;
if(inRect)
{
r.top = inRect->point.y;
r.left = inRect->point.x;
r.bottom = inRect->point.y + inRect->extent.y;
r.right = inRect->point.x + inRect->extent.x;
}
mLockedSubresource = D3D11CalcSubresource(mipLevel, 0, getMipLevels());
HRESULT hr = D3D11DEVICECONTEXT->Map(mD3DTexture, mLockedSubresource, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo);
if ( FAILED(hr) )
AssertFatal(false, "GFXD3D11TextureObject::lock - Failed to map subresource.");
mLocked = true;
}
mLockRect.pBits = static_cast<U8*>(mapInfo.pData);
mLockRect.Pitch = mapInfo.RowPitch;
return (GFXLockedRect*)&mLockRect;
}
void GFXD3D11TextureObject::unlock(U32 mipLevel)
{
AssertFatal( mLocked, "GFXD3D11TextureObject::unlock - Attempting to unlock a surface that has not been locked" );
if( mProfile->isRenderTarget() )
{
//AssertFatal( 0, "GFXD3D11TextureObject::unlock - Need to handle mapping render targets" );
GFXD3D11TextureObject* to = (GFXD3D11TextureObject*)&(*mLockTex);
D3D11->getDeviceContext()->Unmap(to->get2DTex(), mLockedSubresource);
mLockedSubresource = 0;
mLocked = false;
}
else
{
D3D11DEVICECONTEXT->Unmap(get2DTex(), mLockedSubresource);
mLockedSubresource = 0;
mLocked = false;
}
}
void GFXD3D11TextureObject::release()
{
SAFE_RELEASE(mSRView);
SAFE_RELEASE(mRTView);
SAFE_RELEASE(mDSView);
SAFE_RELEASE(mD3DTexture);
SAFE_RELEASE(mD3DSurface);
}
void GFXD3D11TextureObject::zombify()
{
// Managed textures are managed by D3D
AssertFatal(!mLocked, "GFXD3D11TextureObject::zombify - Cannot zombify a locked texture!");
if(isManaged)
return;
release();
}
void GFXD3D11TextureObject::resurrect()
{
// Managed textures are managed by D3D
if(isManaged)
return;
static_cast<GFXD3D11TextureManager*>(TEXMGR)->refreshTexture(this);
}
bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
{
if (!bmp)
return false;
// check format limitations
// at the moment we only support RGBA for the source (other 4 byte formats should
// be easy to add though)
AssertFatal(mFormat == GFXFormatR8G8B8A8, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8)
return false;
PROFILE_START(GFXD3D11TextureObject_copyToBmp);
AssertFatal(bmp->getWidth() == getWidth(), "doh");
AssertFatal(bmp->getHeight() == getHeight(), "doh");
U32 width = getWidth();
U32 height = getHeight();
bmp->setHasTransparency(mHasTransparency);
// set some constants
const U32 sourceBytesPerPixel = 4;
U32 destBytesPerPixel = 0;
if(bmp->getFormat() == GFXFormatR8G8B8A8)
destBytesPerPixel = 4;
else if(bmp->getFormat() == GFXFormatR8G8B8)
destBytesPerPixel = 3;
else
// unsupported
AssertFatal(false, "unsupported bitmap format");
// lock the texture
DXGI_MAPPED_RECT* lockRect = (DXGI_MAPPED_RECT*) lock();
// set pointers
U8* srcPtr = (U8*)lockRect->pBits;
U8* destPtr = bmp->getWritableBits();
// we will want to skip over any D3D cache data in the source texture
const S32 sourceCacheSize = lockRect->Pitch - width * sourceBytesPerPixel;
AssertFatal(sourceCacheSize >= 0, "copyToBmp: cache size is less than zero?");
PROFILE_START(GFXD3D11TextureObject_copyToBmp_pixCopy);
// copy data into bitmap
for (U32 row = 0; row < height; ++row)
{
for (U32 col = 0; col < width; ++col)
{
destPtr[0] = srcPtr[2]; // red
destPtr[1] = srcPtr[1]; // green
destPtr[2] = srcPtr[0]; // blue
if (destBytesPerPixel == 4)
destPtr[3] = srcPtr[3]; // alpha
// go to next pixel in src
srcPtr += sourceBytesPerPixel;
// go to next pixel in dest
destPtr += destBytesPerPixel;
}
// skip past the cache data for this row (if any)
srcPtr += sourceCacheSize;
}
PROFILE_END();
// assert if we stomped or underran memory
AssertFatal(U32(destPtr - bmp->getWritableBits()) == width * height * destBytesPerPixel, "copyToBmp: doh, memory error");
AssertFatal(U32(srcPtr - (U8*)lockRect->pBits) == height * lockRect->Pitch, "copyToBmp: doh, memory error");
// unlock
unlock();
PROFILE_END();
return true;
}
ID3D11ShaderResourceView* GFXD3D11TextureObject::getSRView()
{
return mSRView;
}
ID3D11RenderTargetView* GFXD3D11TextureObject::getRTView()
{
return mRTView;
}
ID3D11DepthStencilView* GFXD3D11TextureObject::getDSView()
{
return mDSView;
}
ID3D11ShaderResourceView** GFXD3D11TextureObject::getSRViewPtr()
{
return &mSRView;
}
ID3D11RenderTargetView** GFXD3D11TextureObject::getRTViewPtr()
{
return &mRTView;
}
ID3D11DepthStencilView** GFXD3D11TextureObject::getDSViewPtr()
{
return &mDSView;
}

View file

@ -0,0 +1,89 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D11TEXTUREOBJECT_H_
#define _GFXD3D11TEXTUREOBJECT_H_
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/gfxTextureHandle.h"
#include "gfx/gfxTextureManager.h"
class GFXD3D11TextureObject : public GFXTextureObject
{
protected:
static U32 mTexCount;
GFXTexHandle mLockTex;
DXGI_MAPPED_RECT mLockRect;
bool mLocked;
U32 mLockedSubresource;
ID3D11Resource *mD3DTexture;
// used for z buffers...
ID3D11Texture2D *mD3DSurface;
ID3D11ShaderResourceView* mSRView; // for shader resource input
ID3D11RenderTargetView* mRTView; // for render targets
ID3D11DepthStencilView* mDSView; //render target view for depth stencil
public:
GFXD3D11TextureObject( GFXDevice * d, GFXTextureProfile *profile);
~GFXD3D11TextureObject();
ID3D11Resource* getResource(){ return mD3DTexture; }
ID3D11Texture2D* get2DTex(){ return (ID3D11Texture2D*) mD3DTexture; }
ID3D11Texture2D** get2DTexPtr(){ return (ID3D11Texture2D**) &mD3DTexture; }
ID3D11Texture3D* get3DTex(){ return (ID3D11Texture3D*) mD3DTexture; }
ID3D11Texture3D** get3DTexPtr(){ return (ID3D11Texture3D**) &mD3DTexture; }
ID3D11ShaderResourceView* getSRView();
ID3D11RenderTargetView* getRTView();
ID3D11DepthStencilView* getDSView();
ID3D11ShaderResourceView** getSRViewPtr();
ID3D11RenderTargetView** getRTViewPtr();
ID3D11DepthStencilView** getDSViewPtr();
void release();
bool isManaged; //setting to true tells this texture not to be released from being zombify
virtual GFXLockedRect * lock(U32 mipLevel = 0, RectI *inRect = NULL);
virtual void unlock(U32 mipLevel = 0 );
virtual bool copyToBmp(GBitmap* bmp);
ID3D11Texture2D* getSurface() {return mD3DSurface;}
ID3D11Texture2D** getSurfacePtr() {return &mD3DSurface;}
// GFXResource
void zombify();
void resurrect();
#ifdef TORQUE_DEBUG
virtual void pureVirtualCrash() {};
#endif
};
#endif

View file

@ -0,0 +1,233 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/D3D11/gfxD3D11VertexBuffer.h"
#include "console/console.h"
GFXD3D11VertexBuffer::~GFXD3D11VertexBuffer()
{
if(getOwningDevice() != NULL)
{
if(mBufferType != GFXBufferTypeVolatile)
{
SAFE_RELEASE(vb);
}
}
}
void GFXD3D11VertexBuffer::lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr)
{
PROFILE_SCOPE(GFXD3D11VertexBuffer_lock);
AssertFatal(lockedVertexStart == 0 && lockedVertexEnd == 0, "Cannot lock a buffer more than once!");
D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD;
switch(mBufferType)
{
case GFXBufferTypeStatic:
case GFXBufferTypeDynamic:
flags = D3D11_MAP_WRITE_DISCARD;
break;
case GFXBufferTypeVolatile:
// Get or create the volatile buffer...
mVolatileBuffer = D3D11->findVBPool( &mVertexFormat, vertexEnd );
if( !mVolatileBuffer )
mVolatileBuffer = D3D11->createVBPool( &mVertexFormat, mVertexSize );
vb = mVolatileBuffer->vb;
// Get our range now...
AssertFatal(vertexStart == 0, "Cannot get a subrange on a volatile buffer.");
AssertFatal(vertexEnd <= MAX_DYNAMIC_VERTS, "Cannot get more than MAX_DYNAMIC_VERTS in a volatile buffer. Up the constant!");
AssertFatal(mVolatileBuffer->lockedVertexStart == 0 && mVolatileBuffer->lockedVertexEnd == 0, "Got more than one lock on the volatile pool.");
// We created the pool when we requested this volatile buffer, so assume it exists...
if( mVolatileBuffer->mNumVerts + vertexEnd > MAX_DYNAMIC_VERTS )
{
flags = D3D11_MAP_WRITE_DISCARD;
mVolatileStart = vertexStart = 0;
vertexEnd = vertexEnd;
}
else
{
flags = D3D11_MAP_WRITE_NO_OVERWRITE;
mVolatileStart = vertexStart = mVolatileBuffer->mNumVerts;
vertexEnd += mVolatileBuffer->mNumVerts;
}
mVolatileBuffer->mNumVerts = vertexEnd+1;
mVolatileBuffer->lockedVertexStart = vertexStart;
mVolatileBuffer->lockedVertexEnd = vertexEnd;
break;
}
lockedVertexStart = vertexStart;
lockedVertexEnd = vertexEnd;
// uncomment it for debugging purpose. called many times per frame... spammy!
//Con::printf("%x: Locking %s range (%d, %d)", this, (mBufferType == GFXBufferTypeVolatile ? "volatile" : "static"), lockedVertexStart, lockedVertexEnd);
U32 sizeToLock = (vertexEnd - vertexStart) * mVertexSize;
if(mBufferType == GFXBufferTypeStatic)
{
*vertexPtr = new U8[sizeToLock];
mLockedBuffer = *vertexPtr;
}
else
{
D3D11_MAPPED_SUBRESOURCE pVertexData;
ZeroMemory(&pVertexData, sizeof(D3D11_MAPPED_SUBRESOURCE));
HRESULT hr = D3D11DEVICECONTEXT->Map(vb, 0, flags, 0, &pVertexData);
if(FAILED(hr))
{
AssertFatal(false, "Unable to lock vertex buffer.");
}
*vertexPtr = (U8*)pVertexData.pData + (vertexStart * mVertexSize);
}
#ifdef TORQUE_DEBUG
// Allocate a debug buffer large enough for the lock
// plus space for over and under run guard strings.
const U32 guardSize = sizeof( _VBGuardString );
mDebugGuardBuffer = new U8[sizeToLock+(guardSize*2)];
// Setup the guard strings.
dMemcpy( mDebugGuardBuffer, _VBGuardString, guardSize );
dMemcpy( mDebugGuardBuffer + sizeToLock + guardSize, _VBGuardString, guardSize );
// Store the real lock pointer and return our debug pointer.
mLockedBuffer = *vertexPtr;
*vertexPtr = mDebugGuardBuffer + guardSize;
#endif // TORQUE_DEBUG
}
void GFXD3D11VertexBuffer::unlock()
{
PROFILE_SCOPE(GFXD3D11VertexBuffer_unlock);
#ifdef TORQUE_DEBUG
if ( mDebugGuardBuffer )
{
const U32 guardSize = sizeof( _VBGuardString );
const U32 sizeLocked = (lockedVertexEnd - lockedVertexStart) * mVertexSize;
// First check the guard areas for overwrites.
AssertFatal(dMemcmp( mDebugGuardBuffer, _VBGuardString, guardSize) == 0,
"GFXD3D11VertexBuffer::unlock - Caught lock memory underrun!" );
AssertFatal(dMemcmp( mDebugGuardBuffer + sizeLocked + guardSize, _VBGuardString, guardSize) == 0,
"GFXD3D11VertexBuffer::unlock - Caught lock memory overrun!" );
// Copy the debug content down to the real VB.
dMemcpy(mLockedBuffer, mDebugGuardBuffer + guardSize, sizeLocked);
// Cleanup.
delete [] mDebugGuardBuffer;
mDebugGuardBuffer = NULL;
//mLockedBuffer = NULL;
}
#endif // TORQUE_DEBUG
if(mBufferType == GFXBufferTypeStatic)
{
const U32 sizeLocked = (lockedVertexEnd - lockedVertexStart) * mVertexSize;
//set up the update region of the buffer
D3D11_BOX box;
box.back = 1;
box.front = 0;
box.top = 0;
box.bottom = 1;
box.left = lockedVertexStart * mVertexSize;
box.right = lockedVertexEnd * mVertexSize;
//update the real vb buffer
D3D11DEVICECONTEXT->UpdateSubresource(vb, 0, &box,mLockedBuffer,sizeLocked, 0);
//clean up the old buffer
delete[] mLockedBuffer;
mLockedBuffer = NULL;
}
else
{
D3D11DEVICECONTEXT->Unmap(vb,0);
}
mIsFirstLock = false;
//uncomment it for debugging purpose. called many times per frame... spammy!
//Con::printf("%x: Unlocking %s range (%d, %d)", this, (mBufferType == GFXBufferTypeVolatile ? "volatile" : "static"), lockedVertexStart, lockedVertexEnd);
lockedVertexEnd = lockedVertexStart = 0;
if(mVolatileBuffer.isValid())
{
mVolatileBuffer->lockedVertexStart = 0;
mVolatileBuffer->lockedVertexEnd = 0;
mVolatileBuffer = NULL;
}
}
void GFXD3D11VertexBuffer::zombify()
{
AssertFatal(lockedVertexStart == 0 && lockedVertexEnd == 0, "GFXD3D11VertexBuffer::zombify - Cannot zombify a locked buffer!");
// Static buffers are managed by D3D11 so we don't deal with them.
if(mBufferType == GFXBufferTypeDynamic)
{
SAFE_RELEASE(vb);
}
}
void GFXD3D11VertexBuffer::resurrect()
{
// Static buffers are managed by D3D11 so we don't deal with them.
if(mBufferType == GFXBufferTypeDynamic)
{
D3D11_BUFFER_DESC desc;
desc.ByteWidth = mVertexSize * mNumVerts;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
desc.StructureByteStride = 0;
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &vb);
if(FAILED(hr))
{
AssertFatal(false, "GFXD3D11VertexBuffer::resurrect - Failed to allocate VB");
}
}
}

View file

@ -0,0 +1,95 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2015 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GFXD3D_VERTEXBUFFER_H_
#define _GFXD3D_VERTEXBUFFER_H_
#include "gfx/D3D11/gfxD3D11Device.h"
#include "core/util/safeDelete.h"
class GFXD3D11VertexBuffer : public GFXVertexBuffer
{
public:
ID3D11Buffer *vb;
StrongRefPtr<GFXD3D11VertexBuffer> mVolatileBuffer;
void *mLockedBuffer;
#ifdef TORQUE_DEBUG
#define _VBGuardString "GFX_VERTEX_BUFFER_GUARD_STRING"
U8 *mDebugGuardBuffer;
#endif TORQUE_DEBUG
bool mIsFirstLock;
bool mClearAtFrameEnd;
GFXD3D11VertexBuffer();
GFXD3D11VertexBuffer( GFXDevice *device,
U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertexSize,
GFXBufferType bufferType );
virtual ~GFXD3D11VertexBuffer();
void lock(U32 vertexStart, U32 vertexEnd, void **vertexPtr);
void unlock();
void prepare() {}
// GFXResource interface
virtual void zombify();
virtual void resurrect();
};
//-----------------------------------------------------------------------------
// This is for debugging vertex buffers and trying to track down which vbs
// aren't getting free'd
inline GFXD3D11VertexBuffer::GFXD3D11VertexBuffer() : GFXVertexBuffer(0,0,0,0,(GFXBufferType)0)
{
vb = NULL;
mIsFirstLock = true;
lockedVertexEnd = lockedVertexStart = 0;
mClearAtFrameEnd = false;
#ifdef TORQUE_DEBUG
mDebugGuardBuffer = NULL;
mLockedBuffer = NULL;
#endif
}
inline GFXD3D11VertexBuffer::GFXD3D11VertexBuffer( GFXDevice *device,
U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertexSize,
GFXBufferType bufferType )
: GFXVertexBuffer( device, numVerts, vertexFormat, vertexSize, bufferType )
{
vb = NULL;
mIsFirstLock = true;
mClearAtFrameEnd = false;
lockedVertexEnd = lockedVertexStart = 0;
mLockedBuffer = NULL;
#ifdef TORQUE_DEBUG
mDebugGuardBuffer = NULL;
#endif
}
#endif // _GFXD3D_VERTEXBUFFER_H_

View file

@ -0,0 +1,98 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2016 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/D3D11/screenshotD3D11.h"
#include "gfx/D3D11/gfxD3D11Device.h"
//Note if MSAA is ever enabled this will need fixing
GBitmap* ScreenShotD3D11::_captureBackBuffer()
{
ID3D11Texture2D* backBuf = D3D11->getBackBufferTexture();
D3D11_TEXTURE2D_DESC desc;
backBuf->GetDesc(&desc);
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.Usage = D3D11_USAGE_STAGING;
//create temp texure
ID3D11Texture2D* pNewTexture = NULL;
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &pNewTexture);
if (FAILED(hr))
return NULL;
U32 width = desc.Width;
U32 height = desc.Height;
// pixel data
U8 *pData = new U8[width * height * 4];
D3D11DEVICECONTEXT->CopyResource(pNewTexture, backBuf);
D3D11_MAPPED_SUBRESOURCE Resource;
hr = D3D11DEVICECONTEXT->Map(pNewTexture, 0, D3D11_MAP_READ, 0, &Resource);
if (FAILED(hr))
{
//cleanup
SAFE_DELETE(pData);
SAFE_RELEASE(pNewTexture);
return NULL;
}
const U32 pitch = width << 2;
const U8* pSource = (U8*)Resource.pData;
U32 totalPitch = 0;
for (U32 i = 0; i < height; ++i)
{
dMemcpy(pData, pSource, width * 4);
pSource += Resource.RowPitch;
pData += pitch;
totalPitch += pitch;
}
D3D11DEVICECONTEXT->Unmap(pNewTexture, 0);
pData -= totalPitch;
GBitmap *gb = new GBitmap(width, height);
//Set GBitmap data and convert from bgr to rgb
ColorI c;
for (S32 i = 0; i<height; i++)
{
const U8 *a = pData + i * width * 4;
for (S32 j = 0; j<width; j++)
{
c.blue = *(a++);
c.green = *(a++);
c.red = *(a++);
a++; // Ignore alpha.
gb->setColor(j, i, c);
}
}
//cleanup
SAFE_DELETE(pData);
SAFE_RELEASE(pNewTexture);
return gb;
}

View file

@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2016 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SCREENSHOTD3D11_H_
#define _SCREENSHOTD3D11_H_
#include "gfx/screenshot.h"
//**************************************************************************
// D3D implementation of screenshot
//**************************************************************************
class ScreenShotD3D11 : public ScreenShot
{
protected:
GBitmap* _captureBackBuffer();
};
#endif // _SCREENSHOTD3D11_H_