DX and GL Geometry shaders added

Added the dx and gl geometry shader compile codes.
This commit is contained in:
marauder2k7 2024-03-06 13:51:50 +00:00
parent 808e2f4200
commit 4a6fbd5811
6 changed files with 312 additions and 239 deletions

View file

@ -105,6 +105,7 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mLastVertShader = NULL;
mLastPixShader = NULL;
mLastGeoShader = NULL;
mCanCurrentlyRender = false;
mTextureManager = NULL;
@ -202,7 +203,7 @@ GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, cons
features |= D3D11_FORMAT_SUPPORT_BLENDABLE;
if(mustfilter)
features |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
for(U32 i = 0; i < formats.size(); i++)
{
if(GFXD3D11TextureFormat[formats[i]] == DXGI_FORMAT_UNKNOWN)
@ -213,7 +214,7 @@ GFXFormat GFXD3D11Device::selectSupportedFormat(GFXTextureProfile *profile, cons
if(supportFlag & features)
return formats[i];
}
return GFXFormatR8G8B8A8;
}
@ -261,7 +262,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
{
GFXAdapter *toAdd = new GFXAdapter;
toAdd->mType = Direct3D11;
@ -286,7 +287,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
dStrncpy(toAdd->mName, Description.c_str(), GFXAdapter::MaxAdapterNameLen);
dStrncat(toAdd->mName, " (D3D11)", sizeof(toAdd->mName) - strlen(toAdd->mName) - 1);
IDXGIOutput* pOutput = NULL;
IDXGIOutput* pOutput = NULL;
HRESULT hr;
hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
@ -310,7 +311,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
if(FAILED(hr))
AssertFatal(false, "GFXD3D11Device::enumerateAdapters -> GetDisplayModeList call failure");
displayModes = new DXGI_MODE_DESC[numModes];
displayModes = new DXGI_MODE_DESC[numModes];
// Get the list
hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
@ -376,7 +377,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
SAFE_RELEASE(DXGIFactory);
}
void GFXD3D11Device::enumerateVideoModes()
void GFXD3D11Device::enumerateVideoModes()
{
mVideoModes.clear();
@ -389,9 +390,9 @@ void GFXD3D11Device::enumerateVideoModes()
if (FAILED(hr))
AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> CreateDXGIFactory1 call failure");
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
for(U32 adapterIndex = 0; DXGIFactory->EnumAdapters1(adapterIndex, &EnumAdapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex)
{
IDXGIOutput* pOutput = NULL;
IDXGIOutput* pOutput = NULL;
hr = EnumAdapter->EnumOutputs(adapterIndex, &pOutput);
@ -414,7 +415,7 @@ void GFXD3D11Device::enumerateVideoModes()
if(FAILED(hr))
AssertFatal(false, "GFXD3D11Device::enumerateVideoModes -> GetDisplayModeList call failure");
displayModes = new DXGI_MODE_DESC[numModes];
displayModes = new DXGI_MODE_DESC[numModes];
// Get the list
hr = pOutput->GetDisplayModeList(format, 0, &numModes, displayModes);
@ -519,14 +520,16 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
{
case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0";
mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0";
mGeometryShaderTarget = "gs_5_0";
mPixVersion = 5.0f;
mShaderModel = "50";
break;
case D3D_FEATURE_LEVEL_10_1:
mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1";
mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1";
mGeometryShaderTarget = "gs_4_1";
mPixVersion = 4.1f;
mShaderModel = "41";
break;
@ -546,7 +549,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
SAFE_RELEASE(testQuery);
Con::printf("Hardware occlusion query detected: %s", mOcclusionQuerySupported ? "Yes" : "No");
mCardProfiler = new GFXD3D11CardProfiler();
mCardProfiler->init();
@ -589,10 +592,10 @@ void GFXD3D11Device::_suppressDebugMessages()
}
}
bool GFXD3D11Device::beginSceneInternal()
bool GFXD3D11Device::beginSceneInternal()
{
mCanCurrentlyRender = true;
return mCanCurrentlyRender;
return mCanCurrentlyRender;
}
GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
@ -739,7 +742,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
_updateRenderTargets();
}
MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];
MatrixF tempMatrix = mProjectionMatrix * mViewMatrix * mWorldMatrix[mWorldStackSize];
mGenericShaderBuffer[type]->setSafe(mModelViewProjSC[type], tempMatrix);
setShader(mGenericShader[type]);
@ -764,7 +767,7 @@ void GFXD3D11Device::setStateBlockInternal(GFXStateBlock* block, bool force)
if (force)
d3dCurrent = NULL;
d3dBlock->activate(d3dCurrent);
d3dBlock->activate(d3dCurrent);
}
/// Called by base GFXDevice to actually set a const buffer
@ -863,7 +866,7 @@ void GFXD3D11Device::clearColorAttachment(const U32 attachment, const LinearColo
mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
}
void GFXD3D11Device::endSceneInternal()
void GFXD3D11Device::endSceneInternal()
{
mCanCurrentlyRender = false;
}
@ -875,7 +878,7 @@ void GFXD3D11Device::_updateRenderTargets()
if (mRTDeactivate)
{
mRTDeactivate->deactivate();
mRTDeactivate = NULL;
mRTDeactivate = NULL;
}
// NOTE: The render target changes are not really accurate
@ -887,7 +890,7 @@ void GFXD3D11Device::_updateRenderTargets()
mCurrentRT->activate();
mRTDirty = false;
}
}
if (mViewportDirty)
{
@ -906,7 +909,7 @@ void GFXD3D11Device::_updateRenderTargets()
}
}
void GFXD3D11Device::releaseDefaultPoolResources()
void GFXD3D11Device::releaseDefaultPoolResources()
{
// Release all the dynamic vertex buffer arrays
// Forcibly clean up the pools
@ -919,7 +922,7 @@ void GFXD3D11Device::releaseDefaultPoolResources()
// We gotta clear the current const buffer else the next
// activate may erroneously think the device is still holding
// this state and fail to set it.
// this state and fail to set it.
mCurrentConstBuffer = NULL;
// Set current VB to NULL and set state dirty
@ -943,7 +946,7 @@ void GFXD3D11Device::releaseDefaultPoolResources()
mPrimitiveBufferDirty = true;
// Zombify texture manager (for D3D this only modifies default pool textures)
if( mTextureManager )
if( mTextureManager )
mTextureManager->zombify();
// Set global dirty state so the IB/PB and VB get reset
@ -958,7 +961,7 @@ void GFXD3D11Device::releaseDefaultPoolResources()
}
}
void GFXD3D11Device::reacquireDefaultPoolResources()
void GFXD3D11Device::reacquireDefaultPoolResources()
{
// Now do the dynamic index buffers
if( mDynamicPB == NULL )
@ -974,7 +977,7 @@ void GFXD3D11Device::reacquireDefaultPoolResources()
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &mDynamicPB->ib);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate dynamic IB");
}
@ -1020,7 +1023,7 @@ GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vert
newBuff->mDevice = this;
// Requesting it will allocate it.
vertexFormat->getDecl();
vertexFormat->getDecl();
D3D11_BUFFER_DESC desc;
desc.ByteWidth = vertSize * GFX_MAX_DYNAMIC_VERTS;
@ -1032,7 +1035,7 @@ GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vert
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &newBuff->vb);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate dynamic VB");
}
@ -1042,9 +1045,9 @@ GFXD3D11VertexBuffer * GFXD3D11Device::createVBPool( const GFXVertexFormat *vert
//-----------------------------------------------------------------------------
void GFXD3D11Device::setClipRect( const RectI &inRect )
void GFXD3D11Device::setClipRect( const RectI &inRect )
{
// We transform the incoming rect by the view
// We transform the incoming rect by the view
// matrix first, so that it can be used to pan
// and scale the clip rect.
//
@ -1052,7 +1055,7 @@ void GFXD3D11Device::setClipRect( const RectI &inRect )
Point3F pos( inRect.point.x, inRect.point.y, 0.0f );
Point3F extent( inRect.extent.x, inRect.extent.y, 0.0f );
getViewMatrix().mulP( pos );
getViewMatrix().mulV( extent );
getViewMatrix().mulV( extent );
RectI rect( pos.x, pos.y, extent.x, extent.y );
// Clip the rect against the renderable size.
@ -1068,8 +1071,8 @@ void GFXD3D11Device::setClipRect( const RectI &inRect )
F32 b = F32( mClipRect.point.y + mClipRect.extent.y );
F32 t = F32( mClipRect.point.y );
// Set up projection matrix,
static Point4F pt;
// Set up projection matrix,
static Point4F pt;
pt.set(2.0f / (r - l), 0.0f, 0.0f, 0.0f);
mTempMatrix.setColumn(0, pt);
@ -1085,7 +1088,7 @@ void GFXD3D11Device::setClipRect( const RectI &inRect )
setProjectionMatrix( mTempMatrix );
// Set up world/view matrix
mTempMatrix.identity();
mTempMatrix.identity();
setWorldMatrix( mTempMatrix );
setViewport( mClipRect );
@ -1097,7 +1100,7 @@ void GFXD3D11Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
if ( stream == 0 )
{
// Set the volatile buffer which is used to
// Set the volatile buffer which is used to
// offset the start index when doing draw calls.
if ( d3dBuffer && d3dBuffer->mVolatileStart > 0 )
mVolatileVB = d3dBuffer;
@ -1106,7 +1109,7 @@ void GFXD3D11Device::setVertexStream( U32 stream, GFXVertexBuffer *buffer )
}
// NOTE: We do not use the stream offset here for stream 0
// as that feature is *supposedly* not as well supported as
// as that feature is *supposedly* not as well supported as
// using the start index in drawPrimitive.
//
// If we can verify that this is not the case then we should
@ -1125,7 +1128,7 @@ void GFXD3D11Device::setVertexStreamFrequency( U32 stream, U32 frequency )
mDrawInstancesCount = frequency; // instances count
}
void GFXD3D11Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer )
void GFXD3D11Device::_setPrimitiveBuffer( GFXPrimitiveBuffer *buffer )
{
mCurrentPB = static_cast<GFXD3D11PrimitiveBuffer *>( buffer );
@ -1160,7 +1163,7 @@ U32 GFXD3D11Device::primCountToIndexCount(GFXPrimitiveType primType, U32 primiti
}
void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount )
void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart, U32 primitiveCount )
{
// This is done to avoid the function call overhead if possible
if( mStateDirty )
@ -1172,12 +1175,12 @@ void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart,
vertexStart += mVolatileVB->mVolatileStart;
mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
if ( mDrawInstancesCount )
mD3DDeviceContext->DrawInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, vertexStart, 0);
else
mD3DDeviceContext->Draw(primCountToIndexCount(primType, primitiveCount), vertexStart);
mDeviceStatistics.mDrawCalls++;
if ( mVertexBufferFrequency[0] > 1 )
mDeviceStatistics.mPolyCount += primitiveCount * mVertexBufferFrequency[0];
@ -1185,12 +1188,12 @@ void GFXD3D11Device::drawPrimitive( GFXPrimitiveType primType, U32 vertexStart,
mDeviceStatistics.mPolyCount += primitiveCount;
}
void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount )
void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount )
{
// This is done to avoid the function call overhead if possible
if( mStateDirty )
@ -1204,11 +1207,11 @@ void GFXD3D11Device::drawIndexedPrimitive( GFXPrimitiveType primType,
startVertex += mVolatileVB->mVolatileStart;
mD3DDeviceContext->IASetPrimitiveTopology(GFXD3D11PrimType[primType]);
if ( mDrawInstancesCount )
mD3DDeviceContext->DrawIndexedInstanced(primCountToIndexCount(primType, primitiveCount), mDrawInstancesCount, mCurrentPB->mVolatileStart + startIndex, startVertex, 0);
else
mD3DDeviceContext->DrawIndexed(primCountToIndexCount(primType,primitiveCount), mCurrentPB->mVolatileStart + startIndex, startVertex);
mD3DDeviceContext->DrawIndexed(primCountToIndexCount(primType,primitiveCount), mCurrentPB->mVolatileStart + startIndex, startVertex);
mDeviceStatistics.mDrawCalls++;
if ( mVertexBufferFrequency[0] > 1 )
@ -1245,7 +1248,13 @@ void GFXD3D11Device::setShader(GFXShader *shader, bool force)
{
mD3DDeviceContext->VSSetShader( d3dShader->mVertShader, NULL, 0);
mLastVertShader = d3dShader->mVertShader;
}
}
if (d3dShader->mGeoShader != mLastGeoShader || force)
{
mD3DDeviceContext->GSSetShader(d3dShader->mGeoShader, NULL, 0);
mLastGeoShader = d3dShader->mGeoShader;
}
}
else
{
@ -1308,7 +1317,7 @@ GFXPrimitiveBuffer * GFXD3D11Device::allocPrimitiveBuffer(U32 numIndices, U32 nu
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->ib);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate an index buffer.");
}
@ -1329,12 +1338,12 @@ GFXVertexBuffer * GFXD3D11Device::allocVertexBuffer(U32 numVerts, const GFXVerte
{
PROFILE_SCOPE( GFXD3D11Device_allocVertexBuffer );
GFXD3D11VertexBuffer *res = new GFXD3D11VertexBuffer( this,
numVerts,
vertexFormat,
vertSize,
GFXD3D11VertexBuffer *res = new GFXD3D11VertexBuffer( this,
numVerts,
vertexFormat,
vertSize,
bufferType );
// Determine usage flags
D3D11_USAGE usage = D3D11_USAGE_DEFAULT;
@ -1387,7 +1396,7 @@ GFXVertexBuffer * GFXD3D11Device::allocVertexBuffer(U32 numVerts, const GFXVerte
HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &res->vb);
if(FAILED(hr))
if(FAILED(hr))
{
AssertFatal(false, "Failed to allocate VB");
}
@ -1540,16 +1549,16 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
return decl;
U32 elemCount = vertexFormat->getElementCount();
ID3DBlob* code = NULL;
// We have to generate a temporary shader here for now since the input layout creation
// expects a shader to be already compiled to verify the vertex layout structure. The problem
// is that most of the time the regular shaders are compiled AFTER allocVertexDecl is called.
if(!decl)
{
//TODO: Perhaps save/cache the ID3DBlob for later use on identical vertex formats,save creating/compiling the temp shader everytime
String shaderData = _createTempShaderInternal(vertexFormat);
String shaderData = _createTempShaderInternal(vertexFormat);
#ifdef TORQUE_DEBUG
U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
@ -1569,11 +1578,11 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
SAFE_RELEASE(errorBlob);
}
AssertFatal(code, "D3D11Device::allocVertexDecl - compiled vert shader code missing!");
// Setup the declaration struct.
U32 stream;
D3D11_INPUT_ELEMENT_DESC *vd = new D3D11_INPUT_ELEMENT_DESC[ elemCount];
@ -1599,7 +1608,7 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
vd[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
vd[i].InstanceDataStepRate = 0;
}
// We force the usage index of 0 for everything but
// We force the usage index of 0 for everything but
// texture coords for now... this may change later.
vd[i].SemanticIndex = 0;
@ -1634,7 +1643,7 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
decl = new D3D11VertexDecl();
HRESULT hr = mD3DDevice->CreateInputLayout(vd, elemCount,code->GetBufferPointer(), code->GetBufferSize(), &decl->decl);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Device::allocVertexDecl - Failed to create vertex input layout!");
@ -1654,7 +1663,7 @@ void GFXD3D11Device::setVertexDecl( const GFXVertexDecl *decl )
ID3D11InputLayout *dx11Decl = NULL;
if (decl)
dx11Decl = static_cast<const D3D11VertexDecl*>(decl)->decl;
mD3DDeviceContext->IASetInputLayout(dx11Decl);
}
@ -1709,7 +1718,7 @@ GFXFence *GFXD3D11Device::createFence()
}
// CodeReview: At some point I would like a specialized implementation of
// the method used by the general fence, only without the overhead incurred
// the method used by the general fence, only without the overhead incurred
// by using the GFX constructs. Primarily the lock() method on texture handles
// will do a data copy, and this method doesn't require a copy, just a lock
// [5/10/2007 Pat]
@ -1719,12 +1728,12 @@ GFXFence *GFXD3D11Device::createFence()
}
GFXOcclusionQuery* GFXD3D11Device::createOcclusionQuery()
{
{
GFXOcclusionQuery *query;
if (mOcclusionQuerySupported)
query = new GFXD3D11OcclusionQuery( this );
else
return NULL;
return NULL;
query->registerResourceWithDevice(this);
return query;
@ -1794,7 +1803,7 @@ const char* GFXD3D11Device::interpretDebugResult(long result)
//generics
case E_UNEXPECTED:
error = "E_UNEXPECTED";
break;
break;
case E_NOTIMPL:
error = "E_NOTIMPL";
break;

View file

@ -121,6 +121,7 @@ protected:
ID3D11VertexShader *mLastVertShader;
ID3D11PixelShader *mLastPixShader;
ID3D11GeometryShader *mLastGeoShader;
S32 mCreateFenceType;
@ -140,6 +141,7 @@ protected:
// Shader Model targers
String mVertexShaderTarget;
String mPixelShaderTarget;
String mGeometryShaderTarget;
// String for use with shader macros in the form of shader model version * 10
String mShaderModel;
bool mDebugLayers;
@ -148,7 +150,7 @@ protected:
bool mOcclusionQuerySupported;
U32 mDrawInstancesCount;
U32 mDrawInstancesCount;
/// To manage creating and re-creating of these when device is aquired
void reacquireDefaultPoolResources();
@ -181,11 +183,11 @@ protected:
// Index buffer management
// {
virtual void _setPrimitiveBuffer( GFXPrimitiveBuffer *buffer );
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
virtual void drawIndexedPrimitive( GFXPrimitiveType primType,
U32 startVertex,
U32 minIndex,
U32 numVerts,
U32 startIndex,
U32 primitiveCount );
// }
@ -197,7 +199,7 @@ protected:
String _createTempShaderInternal(const GFXVertexFormat *vertexFormat);
// Supress any debug layer messages we don't want to see
void _suppressDebugMessages();
public:
static GFXDevice *createInstance( U32 adapterIndex );
@ -229,7 +231,7 @@ public:
virtual GFXTextureArray* createTextureArray();
virtual F32 getPixelShaderVersion() const { return mPixVersion; }
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;}
virtual void setPixelShaderVersion( F32 version ){ mPixVersion = version;}
virtual void setShader(GFXShader *shader, bool force = false);
virtual U32 getNumSamplers() const { return 16; }
@ -252,10 +254,10 @@ public:
virtual void setClipRect( const RectI &rect );
virtual const RectI& getClipRect() const { return mClipRect; }
// }
// }
/// @name Render Targets
/// @{
virtual void _updateRenderTargets();
@ -263,14 +265,14 @@ public:
// Vertex/Index buffer management
// {
virtual GFXVertexBuffer* allocVertexBuffer( U32 numVerts,
virtual GFXVertexBuffer* allocVertexBuffer( U32 numVerts,
const GFXVertexFormat *vertexFormat,
U32 vertSize,
GFXBufferType bufferType,
void* data = NULL);
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
U32 numPrimitives,
virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices,
U32 numPrimitives,
GFXBufferType bufferType,
void* data = NULL);
@ -307,7 +309,7 @@ public:
GFXFence *createFence();
GFXOcclusionQuery* createOcclusionQuery();
GFXOcclusionQuery* createOcclusionQuery();
// Default multisample parameters
DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
@ -317,6 +319,7 @@ public:
// Shader Model targers
const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
const String &getGeometryShaderTarget() const { return mGeometryShaderTarget; }
const String &getShaderModel() const { return mShaderModel; }
// grab the sampler map

View file

@ -215,7 +215,7 @@ void GFXD3D11ShaderConstBuffer::setMatrix(const GFXShaderConstDesc& constDesc, c
break;
}
// Loop through and copy
// Loop through and copy
bool ret = false;
U8* currDestPointer = buf + constDesc.offset;
const U8* currSourcePointer = static_cast<const U8*>(data);
@ -418,7 +418,7 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF&
if (matrixType == GFXSCT_Float4x4)
dMemcpy(mInstPtr + constDesc.offset, mat, sizeof(mat));
// TODO: Support 3x3 and 2x2 matricies?
// TODO: Support 3x3 and 2x2 matricies?
return;
}
@ -569,6 +569,16 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
D3D11DEVICECONTEXT->PSSetConstantBuffers(bufStartSlot, numBufs, psBuffers);
}
if (mShader->mGeoShader && bufRanges[2].isValid())
{
const U32 bufStartSlot = bufRanges[2].mBufMin;
const U32 numBufs = bufRanges[2].mBufMax - bufRanges[2].mBufMin + 1;
ID3D11Buffer** psBuffers = mBoundBuffers[2] + bufStartSlot;
D3D11DEVICECONTEXT->GSSetConstantBuffers(bufStartSlot, numBufs, psBuffers);
}
mWasLost = false;
}
@ -608,6 +618,7 @@ GFXD3D11Shader::GFXD3D11Shader()
AssertFatal(D3D11DEVICE, "Invalid device for shader.");
mVertShader = NULL;
mPixShader = NULL;
mGeoShader = NULL;
if( smD3DInclude == NULL )
smD3DInclude = new gfxD3D11Include;
@ -628,6 +639,7 @@ GFXD3D11Shader::~GFXD3D11Shader()
// release shaders
SAFE_RELEASE(mVertShader);
SAFE_RELEASE(mPixShader);
SAFE_RELEASE(mGeoShader);
//maybe add SAFE_RELEASE(mVertexCode) ?
}
@ -637,6 +649,7 @@ bool GFXD3D11Shader::_init()
SAFE_RELEASE(mVertShader);
SAFE_RELEASE(mPixShader);
SAFE_RELEASE(mGeoShader);
// Create the macro array including the system wide macros.
const U32 macroCount = smGlobalMacros.size() + mMacros.size() + 2;
@ -668,6 +681,12 @@ bool GFXD3D11Shader::_init()
if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, GFXShaderStage::PIXEL_SHADER, d3dMacros))
return false;
if (!mGeometryFile.isEmpty())
{
if (!_compileShader(mGeometryFile, GFXShaderStage::GEOMETRY_SHADER, d3dMacros))
return false;
}
// Mark all existing handles as invalid.
// Those that are found when parsing the descriptions will then be marked valid again.
for (auto& pair : mHandles) {
@ -676,7 +695,7 @@ bool GFXD3D11Shader::_init()
_buildShaderConstantHandles();
// Notify any existing buffers that the buffer
// Notify any existing buffers that the buffer
// layouts have changed and they need to update.
Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
for ( ; biter != mActiveBuffers.end(); biter++ )
@ -685,7 +704,7 @@ bool GFXD3D11Shader::_init()
return true;
}
bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
GFXShaderStage shaderStage,
const D3D_SHADER_MACRO *defines)
{
@ -711,9 +730,9 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
#endif
// Is it an HLSL shader?
if(filePath.getExtension().equal("hlsl", String::NoCase))
if(filePath.getExtension().equal("hlsl", String::NoCase))
{
// Set this so that the D3DInclude::Open will have this
// Set this so that the D3DInclude::Open will have this
// information for relative paths.
smD3DInclude->setPath(filePath.getRootAndPath());
@ -754,6 +773,7 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
target = D3D11->getPixelShaderTarget();
break;
case GEOMETRY_SHADER:
target = D3D11->getGeometryShaderTarget();
break;
case DOMAIN_SHADER:
break;
@ -802,6 +822,7 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
res = D3D11DEVICE->CreatePixelShader(code->GetBufferPointer(), code->GetBufferSize(), NULL, &mPixShader);
break;
case GEOMETRY_SHADER:
res = D3D11DEVICE->CreateGeometryShader(code->GetBufferPointer(), code->GetBufferSize(), NULL, &mGeoShader);
break;
case DOMAIN_SHADER:
break;
@ -812,7 +833,7 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
default:
break;
}
if (FAILED(res))
{
AssertFatal(false, "D3D11Shader::_compilershader- failed to create shader");
@ -848,6 +869,8 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
mPixShader->SetPrivateData(WKPDID_D3DDebugObjectName, shader.size(), shader.c_str());
break;
case GEOMETRY_SHADER:
shader = mGeometryFile.getFileName();
mGeoShader->SetPrivateData(WKPDID_D3DDebugObjectName, shader.size(), shader.c_str());
break;
case DOMAIN_SHADER:
break;
@ -859,8 +882,8 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
break;
}
#endif
SAFE_RELEASE(code);
SAFE_RELEASE(code);
SAFE_RELEASE(reflectionTable);
SAFE_RELEASE(errorBuff);
@ -885,7 +908,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection* refTable,
GFXShaderConstDesc desc;
ID3D11ShaderReflectionConstantBuffer* constantBuffer = refTable->GetConstantBufferByIndex(i);
D3D11_SHADER_BUFFER_DESC constantBufferDesc;
if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
{
desc.name = String(constantBufferDesc.Name);
@ -954,11 +977,11 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection* refTable,
#ifdef D3D11_DEBUG_SPEW
Con::printf("Variable Name %s:, offset: %d, size: %d, constantDesc.Elements: %d", varDesc.name.c_str(), varDesc.StartOffset, varDesc.Size, varDesc.arraySize);
#endif
#endif
mShaderConsts.push_back(varDesc);
}
}
}
else
{
@ -1073,7 +1096,7 @@ GFXShaderConstType GFXD3D11Shader::convertConstType(const D3D11_SHADER_TYPE_DESC
break;
}
}
}
void GFXD3D11Shader::_buildShaderConstantHandles()
@ -1144,7 +1167,7 @@ void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
for ( U32 i=0; i < mInstancingFormat->getElementCount(); i++ )
{
const GFXVertexElement &element = mInstancingFormat->getElement( i );
String constName = String::ToString( "$%s", element.getSemantic().c_str() );
GFXD3D11ShaderConstHandle *handle;
@ -1169,15 +1192,15 @@ void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
desc.arraySize = 1;
if ( j != mHandles.end() )
handle = j->value;
handle = j->value;
else
{
handle = new GFXD3D11ShaderConstHandle(this, desc);
mHandles[ constName ] = handle;
mHandles[ constName ] = handle;
}
handle->mShader = this;
handle->setValid( true );
handle->setValid( true );
handle->mInstancingConstant = true;
// If this is a matrix we will have 2 or 3 more of these
@ -1213,19 +1236,19 @@ GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
/// Returns a shader constant handle for name, if the variable doesn't exist NULL is returned.
GFXShaderConstHandle* GFXD3D11Shader::getShaderConstHandle(const String& name)
{
HandleMap::Iterator i = mHandles.find(name);
HandleMap::Iterator i = mHandles.find(name);
if ( i != mHandles.end() )
{
return i->value;
}
else
{
}
else
{
GFXD3D11ShaderConstHandle *handle = new GFXD3D11ShaderConstHandle(this);
handle->setValid( false );
mHandles[name] = handle;
return handle;
}
return handle;
}
}
GFXShaderConstHandle* GFXD3D11Shader::findShaderConstHandle(const String& name)
@ -1245,7 +1268,7 @@ const Vector<GFXShaderConstDesc>& GFXD3D11Shader::getShaderConstDesc() const
}
U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
{
{
const U32 mRowSizeF = 16;
const U32 mRowSizeI = 16;
@ -1253,7 +1276,7 @@ U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
{
case GFXSCT_Float :
case GFXSCT_Float2 :
case GFXSCT_Float3 :
case GFXSCT_Float3 :
case GFXSCT_Float4 :
return mRowSizeF;
break;
@ -1261,7 +1284,7 @@ U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
case GFXSCT_Float2x2 :
return mRowSizeF * 2;
break;
case GFXSCT_Float3x3 :
case GFXSCT_Float3x3 :
return mRowSizeF * 3;
break;
case GFXSCT_Float4x3:
@ -1269,11 +1292,11 @@ U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
break;
case GFXSCT_Float4x4 :
return mRowSizeF * 4;
break;
break;
//// Scalar
case GFXSCT_Int :
case GFXSCT_Int2 :
case GFXSCT_Int3 :
case GFXSCT_Int3 :
case GFXSCT_Int4 :
return mRowSizeI;
break;

View file

@ -80,7 +80,7 @@ public:
S32 getSamplerRegister() const { return (!isSampler() || !mValid) ? -1 : mSampler; }
// Returns true if this is a handle to a sampler register.
bool isSampler() const
bool isSampler() const
{
return (getType() >= GFXSCT_Sampler);
}
@ -157,7 +157,7 @@ public:
protected:
friend class GFXD3D11Shader;
/// We keep a weak reference to the shader
/// We keep a weak reference to the shader
/// because it will often be deleted.
WeakRefPtr<GFXD3D11Shader> mShader;
BufferMap mBufferMap;
@ -183,12 +183,12 @@ public:
typedef Map<String, GFXShaderConstDesc> BufferMap;
GFXD3D11Shader();
virtual ~GFXD3D11Shader();
virtual ~GFXD3D11Shader();
// GFXShader
virtual GFXShaderConstBufferRef allocConstBuffer();
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
@ -202,6 +202,7 @@ protected:
ID3D11VertexShader *mVertShader;
ID3D11PixelShader *mPixShader;
ID3D11GeometryShader *mGeoShader;
static gfxD3DIncludeRef smD3DInclude;
@ -213,13 +214,13 @@ protected:
Vector<GFXShaderConstDesc> mSamplerDescriptions;
// These two functions are used when compiling shaders from hlsl
virtual bool _compileShader( const Torque::Path &filePath,
virtual bool _compileShader( const Torque::Path &filePath,
GFXShaderStage shaderStage,
const D3D_SHADER_MACRO *defines);
void _getShaderConstants( ID3D11ShaderReflection* refTable,
GFXShaderStage shaderStage);
// This is used in both cases
virtual void _buildShaderConstantHandles();
void _buildInstancingShaderConstantHandles();

View file

@ -39,12 +39,12 @@ class GFXGLShaderConstHandle : public GFXShaderConstHandle
{
friend class GFXGLShader;
public:
public:
GFXGLShaderConstHandle( GFXGLShader *shader );
GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum );
virtual ~GFXGLShaderConstHandle();
void reinit( const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum );
const String& getName() const { return mDesc.name; }
@ -52,7 +52,7 @@ public:
U32 getArraySize() const { return mDesc.arraySize; }
U32 getSize() const;
void setValid( bool valid ) { mValid = valid; }
void setValid( bool valid ) { mValid = valid; }
/// @warning This will always return the value assigned when the shader was
/// initialized. If the value is later changed this method won't reflect that.
S32 getSamplerRegister() const { return mSamplerNum; }
@ -62,7 +62,7 @@ public:
U32 mOffset;
U32 mSize;
GLuint mLocation;
S32 mSamplerNum;
S32 mSamplerNum;
bool mInstancingConstant;
};
@ -75,7 +75,7 @@ GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader )
static U32 shaderConstTypeSize(GFXShaderConstType type)
{
switch(type)
switch(type)
{
case GFXSCT_Float:
case GFXSCT_Int:
@ -107,7 +107,7 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
}
}
GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum )
GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum )
: mShader(shader), mInstancingConstant(false)
{
reinit(desc, loc, samplerNum);
@ -120,7 +120,7 @@ void GFXGLShaderConstHandle::reinit( const GFXShaderConstDesc& desc, GLuint loc,
mSamplerNum = samplerNum;
mOffset = 0;
mInstancingConstant = false;
U32 elemSize = shaderConstTypeSize(mDesc.constType);
AssertFatal(elemSize, "GFXGLShaderConst::GFXGLShaderConst - elemSize is 0");
mSize = mDesc.arraySize * elemSize;
@ -169,7 +169,7 @@ void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const Con
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
U8 *buf = mBuffer + _glHandle->mOffset;
if(_glHandle->mInstancingConstant)
if(_glHandle->mInstancingConstant)
buf = mInstPtr + _glHandle->mOffset;
dMemcpy(buf, &param, sizeof(ConstType));
@ -204,7 +204,7 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColor
{
internalSet(handle, fv);
}
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 fv)
{
internalSet(handle, fv);
@ -258,7 +258,7 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArra
internalSet(handle, fv);
}
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv)
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv)
{
internalSet(handle, fv);
}
@ -292,7 +292,7 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
AssertFatal(!_glHandle->mInstancingConstant || matType == GFXSCT_Float4x4, "GFXGLShaderConstBuffer::set - Only support GFXSCT_Float4x4 for instancing");
switch(matType)
{
case GFXSCT_Float2x2:
@ -316,15 +316,15 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, (sizeof(F32) * 12));// matrix with end row chopped off
break;
case GFXSCT_Float4x4:
{
{
if(_glHandle->mInstancingConstant)
{
MatrixF transposed;
MatrixF transposed;
mat.transposeTo(transposed);
dMemcpy( mInstPtr + _glHandle->mOffset, (const F32*)transposed, sizeof(MatrixF) );
return;
}
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, sizeof(MatrixF));
break;
}
@ -340,7 +340,7 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* ma
AssertFatal(handle->isValid(), "GFXGLShaderConstBuffer::set - Handle is not valid!" );
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays");
switch (matrixType) {
@ -385,6 +385,7 @@ void GFXGLShaderConstBuffer::onShaderReload( GFXGLShader *shader )
GFXGLShader::GFXGLShader(GFXGLDevice* device) :
mVertexShader(0),
mPixelShader(0),
mGeometryShader(0),
mProgram(0),
mDevice(device),
mConstBufferSize(0),
@ -397,7 +398,7 @@ GFXGLShader::~GFXGLShader()
clearShaders();
for(HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); i++)
delete i->value;
delete[] mConstBuffer;
}
@ -406,10 +407,12 @@ void GFXGLShader::clearShaders()
glDeleteProgram(mProgram);
glDeleteShader(mVertexShader);
glDeleteShader(mPixelShader);
glDeleteShader(mGeometryShader);
mProgram = 0;
mVertexShader = 0;
mPixelShader = 0;
mGeometryShader = 0;
}
bool GFXGLShader::_init()
@ -422,44 +425,57 @@ bool GFXGLShader::_init()
clearShaders();
mProgram = glCreateProgram();
// Set the macros and add the global ones.
Vector<GFXShaderMacro> macros;
macros.merge( mMacros );
macros.merge( smGlobalMacros );
macros.increment();
macros.last().name = "TORQUE_SM";
macros.last().value = 40;
macros.increment();
macros.last().name = "TORQUE_VERTEX_SHADER";
macros.last().value = "";
// Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
bool compiledVertexShader = true;
bool compiledPixelShader = true;
// Compile the vertex and pixel shaders if specified.
if(!mVertexFile.isEmpty())
compiledVertexShader = initShader(mVertexFile, true, macros);
bool compiledGeometryShader = true;
// Compile the vertex and pixel shaders if specified.
if (!mVertexFile.isEmpty())
{
compiledVertexShader = initShader(mVertexFile, GFXShaderStage::VERTEX_SHADER, macros);
if (!compiledVertexShader)
return false;
}
if (!mPixelFile.isEmpty())
{
macros.last().name = "TORQUE_PIXEL_SHADER";
compiledPixelShader = initShader(mPixelFile, GFXShaderStage::PIXEL_SHADER, macros);
if (!compiledPixelShader)
return false;
}
if (!mGeometryFile.isEmpty())
{
macros.last().name = "TORQUE_GEOMETRY_SHADER";
compiledGeometryShader = initShader(mPixelFile, GFXShaderStage::GEOMETRY_SHADER, macros);
if (!compiledGeometryShader)
return false;
}
macros.last().name = "TORQUE_PIXEL_SHADER";
if(!mPixelFile.isEmpty())
compiledPixelShader = initShader(mPixelFile, false, macros);
// If either shader was present and failed to compile, bail.
if(!compiledVertexShader || !compiledPixelShader)
return false;
// Link it!
glLinkProgram( mProgram );
GLint activeAttribs = 0;
glGetProgramiv(mProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs );
GLint maxLength;
glGetProgramiv(mProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
FrameTemp<GLchar> tempData(maxLength+1);
*tempData.address() = '\0';
// Check atributes
@ -467,11 +483,11 @@ bool GFXGLShader::_init()
{
GLint size;
GLenum type;
glGetActiveAttrib(mProgram, i, maxLength + 1, NULL, &size, &type, tempData.address());
StringTableEntry argName = StringTable->insert(tempData.address());
CHECK_AARG(Torque::GL_VertexAttrib_Position, vPosition);
CHECK_AARG(Torque::GL_VertexAttrib_Normal, vNormal);
CHECK_AARG(Torque::GL_VertexAttrib_Color, vColor);
@ -502,13 +518,13 @@ bool GFXGLShader::_init()
glBindFragDataLocation(mProgram, i, buffer);
}
// Link it again!
glLinkProgram( mProgram );
GLint linkStatus;
glGetProgramiv( mProgram, GL_LINK_STATUS, &linkStatus );
// Dump the info log to the console
U32 logLength = 0;
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
@ -517,7 +533,7 @@ bool GFXGLShader::_init()
FrameAllocatorMarker fam;
char* log = (char*)fam.alloc( logLength );
glGetProgramInfoLog( mProgram, logLength, NULL, log );
if ( linkStatus == GL_FALSE )
{
if ( smLogErrors )
@ -539,16 +555,16 @@ bool GFXGLShader::_init()
if ( linkStatus == GL_FALSE )
return false;
initConstantDescs();
initConstantDescs();
initHandles();
// Notify Buffers we might have changed in size.
// If this was our first init then we won't have any activeBuffers
// Notify Buffers we might have changed in size.
// If this was our first init then we won't have any activeBuffers
// to worry about unnecessarily calling.
Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
for ( ; biter != mActiveBuffers.end(); biter++ )
for ( ; biter != mActiveBuffers.end(); biter++ )
((GFXGLShaderConstBuffer*)(*biter))->onShaderReload( this );
return true;
}
@ -565,23 +581,23 @@ void GFXGLShader::initConstantDescs()
maxNameLength++;
FrameTemp<GLchar> uniformName(maxNameLength);
for(U32 i = 0; i < numUniforms; i++)
{
GLint size;
GLenum type;
glGetActiveUniform(mProgram, i, maxNameLength, NULL, &size, &type, uniformName);
GFXShaderConstDesc desc;
desc.name = String((char*)uniformName);
// Remove array brackets from the name
desc.name = desc.name.substr(0, desc.name.find('['));
// Insert $ to match D3D behavior of having a $ prepended to parameters to main.
desc.name.insert(0, '$');
desc.arraySize = size;
switch(type)
{
case GL_FLOAT:
@ -641,24 +657,24 @@ void GFXGLShader::initConstantDescs()
// If we don't recognize the constant don't add its description.
continue;
}
mConstants.push_back(desc);
}
}
void GFXGLShader::initHandles()
{
{
// Mark all existing handles as invalid.
// Those that are found when parsing the descriptions will then be marked valid again.
for ( HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter )
(iter->value)->setValid( false );
for ( HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter )
(iter->value)->setValid( false );
mValidHandles.clear();
// Loop through all ConstantDescriptions,
// Loop through all ConstantDescriptions,
// if they aren't in the HandleMap add them, if they are reinitialize them.
for ( U32 i = 0; i < mConstants.size(); i++ )
{
GFXShaderConstDesc &desc = mConstants[i];
GFXShaderConstDesc &desc = mConstants[i];
// Index element 1 of the name to skip the '$' we inserted earier.
GLint loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]);
@ -678,11 +694,11 @@ void GFXGLShader::initHandles()
}
if ( handle != mHandles.end() )
{
handle->value->reinit( desc, loc, sampler );
}
else
handle->value->reinit( desc, loc, sampler );
}
else
{
mHandles[desc.name] = new GFXGLShaderConstHandle( this, desc, loc, sampler );
mHandles[desc.name] = new GFXGLShaderConstHandle( this, desc, loc, sampler );
}
}
@ -703,10 +719,10 @@ void GFXGLShader::initHandles()
mConstBufferSize += handle->getSize();
}
}
mConstBuffer = new U8[mConstBufferSize];
dMemset(mConstBuffer, 0, mConstBufferSize);
// Set our program so uniforms are assigned properly.
mDevice->setShader(this, false);
@ -736,15 +752,15 @@ void GFXGLShader::initHandles()
for ( U32 i=0; i < mInstancingFormat->getElementCount(); i++ )
{
const GFXVertexElement &element = mInstancingFormat->getElement( i );
String constName = String::ToString( "$%s", element.getSemantic().c_str() );
HandleMap::Iterator handle = mHandles.find(constName);
HandleMap::Iterator handle = mHandles.find(constName);
if ( handle != mHandles.end() )
{
{
AssertFatal(0, "");
}
else
}
else
{
GFXShaderConstDesc desc;
desc.name = constName;
@ -759,7 +775,7 @@ void GFXGLShader::initHandles()
desc.constType = GFXSCT_Float;
break;
}
GFXGLShaderConstHandle *h = new GFXGLShaderConstHandle( this, desc, -1, -1 );
h->mInstancingConstant = true;
h->mOffset = offset;
@ -801,7 +817,7 @@ GFXShaderConstHandle* GFXGLShader::getShaderConstHandle(const String& name)
GFXGLShaderConstHandle* handle = new GFXGLShaderConstHandle( this );
handle->setValid(false);
mHandles[ name ] = handle;
return handle;
}
}
@ -826,11 +842,11 @@ void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
if(handle->mInstancingConstant)
continue;
// Don't set if the value has not be changed.
if(dMemcmp(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize()) == 0)
continue;
// Copy new value into our const buffer and set in GL.
dMemcpy(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize());
@ -872,7 +888,7 @@ void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
break;
case GFXSCT_Float4x3:
// NOTE: To save a transpose here we could store the matrix transposed (i.e. column major) in the constant buffer.
// See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix.
// See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix.
glUniformMatrix4x3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
break;
case GFXSCT_Float4x4:
@ -919,7 +935,7 @@ char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
//dStrncpy( buffer, linePragma.c_str(), linePragmaLen );
s->read(shaderLen, buffer);
buffer[shaderLen] = 0;
char* p = dStrstr(buffer, "#include");
while(p)
{
@ -944,12 +960,12 @@ char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
// First try it as a local file.
Torque::Path includePath = Torque::Path::Join(path.getPath(), '/', includeFile);
includePath = Torque::Path::CompressPath(includePath);
FileStream includeStream;
if ( !includeStream.open( includePath, Torque::FS::File::Read ) )
{
// Try again assuming the path is absolute
// Try again assuming the path is absolute
// and/or relative.
includePath = String( includeFile );
includePath = Torque::Path::CompressPath(includePath);
@ -958,7 +974,7 @@ char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
AssertISV(false, avar("failed to open include '%s'.", includePath.getFullPath().c_str()));
if ( smLogErrors )
Con::errorf( "GFXGLShader::_handleIncludes - Failed to open include '%s'.",
Con::errorf( "GFXGLShader::_handleIncludes - Failed to open include '%s'.",
includePath.getFullPath().c_str() );
// Fail... don't return the buffer.
@ -968,17 +984,17 @@ char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
}
char* includedText = _handleIncludes(includePath, &includeStream);
// If a sub-include fails... cleanup and return.
if ( !includedText )
{
dFree(buffer);
return NULL;
}
// TODO: Disabled till this is fixed correctly.
//
// Count the number of lines in the file
// Count the number of lines in the file
// before the include.
/*
U32 includeLine = 0;
@ -1002,7 +1018,7 @@ char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
// Add a new line pragma to restore the proper
// file and line number after the include.
//sItx += String::ToString( "\r\n#line %d \r\n", includeLine );
dFree(includedText);
manip.insert(q-buffer, sItx);
char* manipBuf = dStrdup(manip.c_str());
@ -1012,18 +1028,18 @@ char* GFXGLShader::_handleIncludes( const Torque::Path& path, FileStream *s )
}
p = dStrstr(p, "#include");
}
return buffer;
}
bool GFXGLShader::_loadShaderFromStream( GLuint shader,
const Torque::Path &path,
FileStream *s,
bool GFXGLShader::_loadShaderFromStream( GLuint shader,
const Torque::Path &path,
FileStream *s,
const Vector<GFXShaderMacro> &macros )
{
Vector<char*> buffers;
Vector<U32> lengths;
// The GLSL version declaration must go first!
const char *versionDecl = "#version 330\n";
buffers.push_back( dStrdup( versionDecl ) );
@ -1052,16 +1068,16 @@ bool GFXGLShader::_loadShaderFromStream( GLuint shader,
buffers.push_back( dStrdup( define.c_str() ) );
lengths.push_back( define.length() );
}
// Now finally add the shader source.
U32 shaderLen = s->getStreamSize();
char *buffer = _handleIncludes(path, s);
if ( !buffer )
return false;
buffers.push_back(buffer);
lengths.push_back(shaderLen);
glShaderSource(shader, buffers.size(), (const GLchar**)const_cast<const char**>(buffers.address()), NULL);
#if defined(TORQUE_DEBUG) && defined(TORQUE_DEBUG_GFX)
@ -1084,19 +1100,40 @@ bool GFXGLShader::_loadShaderFromStream( GLuint shader,
return true;
}
bool GFXGLShader::initShader( const Torque::Path &file,
bool isVertex,
bool GFXGLShader::initShader( const Torque::Path &file,
GFXShaderStage stage,
const Vector<GFXShaderMacro> &macros )
{
PROFILE_SCOPE(GFXGLShader_CompileShader);
GLuint activeShader = glCreateShader(isVertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER);
if(isVertex)
GLuint activeShader;
switch (stage)
{
case VERTEX_SHADER:
activeShader = glCreateShader(GL_VERTEX_SHADER);
mVertexShader = activeShader;
else
break;
case PIXEL_SHADER:
activeShader = glCreateShader(GL_FRAGMENT_SHADER);
mPixelShader = activeShader;
break;
case GEOMETRY_SHADER:
activeShader = glCreateShader(GL_GEOMETRY_SHADER);
mGeometryShader = activeShader;
break;
case DOMAIN_SHADER:
break;
case HULL_SHADER:
break;
case COMPUTE_SHADER:
break;
default:
break;
}
glAttachShader(mProgram, activeShader);
// Ok it's not in the shader gen manager, so ask Torque for it
FileStream stream;
if ( !stream.open( file, Torque::FS::File::Read ) )
@ -1104,12 +1141,12 @@ bool GFXGLShader::initShader( const Torque::Path &file,
AssertISV(false, avar("GFXGLShader::initShader - failed to open shader '%s'.", file.getFullPath().c_str()));
if ( smLogErrors )
Con::errorf( "GFXGLShader::initShader - Failed to open shader file '%s'.",
Con::errorf( "GFXGLShader::initShader - Failed to open shader file '%s'.",
file.getFullPath().c_str() );
return false;
}
if (!_loadShaderFromStream(activeShader, file, &stream, macros))
{
if (smLogErrors)
@ -1122,7 +1159,7 @@ bool GFXGLShader::initShader( const Torque::Path &file,
// Dump the info log to the console
U32 logLength = 0;
glGetShaderiv(activeShader, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
if ( logLength )
{
FrameAllocatorMarker fam;
@ -1164,6 +1201,6 @@ const String GFXGLShader::describeSelf() const
ret = String::ToString(" Program: %i", mProgram);
ret += String::ToString(" Vertex Path: %s", mVertexFile.getFullPath().c_str());
ret += String::ToString(" Pixel Path: %s", mPixelFile.getFullPath().c_str());
return ret;
}

View file

@ -50,43 +50,43 @@ public:
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
/// Returns the alignment value for constType
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
virtual GFXShaderConstBufferRef allocConstBuffer();
/// @}
/// @name GFXResource interface
/// @{
virtual void zombify();
virtual void resurrect() { reload(); }
virtual const String describeSelf() const;
/// @}
/// @}
/// Activates this shader in the GL context.
void useProgram();
protected:
friend class GFXGLShaderConstBuffer;
friend class GFXGLShaderConstHandle;
virtual bool _init();
bool initShader( const Torque::Path &file,
bool isVertex,
virtual bool _init();
bool initShader( const Torque::Path &file,
GFXShaderStage stage,
const Vector<GFXShaderMacro> &macros );
void clearShaders();
void initConstantDescs();
void initHandles();
void setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer);
static char* _handleIncludes( const Torque::Path &path, FileStream *s );
static bool _loadShaderFromStream( GLuint shader,
const Torque::Path& path,
FileStream* s,
static bool _loadShaderFromStream( GLuint shader,
const Torque::Path& path,
FileStream* s,
const Vector<GFXShaderMacro>& macros );
/// @name Internal GL handles
@ -95,7 +95,7 @@ protected:
GLuint mPixelShader;
GLuint mProgram;
/// @}
Vector<GFXShaderConstDesc> mConstants;
U32 mConstBufferSize;
U8* mConstBuffer;
@ -109,7 +109,7 @@ class GFXGLShaderConstBuffer : public GFXShaderConstBuffer
public:
GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants);
~GFXGLShaderConstBuffer();
/// Called by GFXGLDevice to activate this buffer.
void activate();
@ -123,7 +123,7 @@ public:
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 LinearColorF& fv);
virtual void set(GFXShaderConstHandle* handle, const LinearColorF& 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);
@ -131,13 +131,13 @@ public:
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<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);
virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
// GFXResource
virtual const String describeSelf() const;
@ -149,12 +149,12 @@ private:
friend class GFXGLShader;
U8* mBuffer;
WeakRefPtr<GFXGLShader> mShader;
template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
template<typename ConstType>
void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
};
#endif // _GFXGLSHADER_H_
#endif // _GFXGLSHADER_H_