Implement new gpu program interface in direct3d driver

This commit is contained in:
kaetemi 2013-09-07 22:00:07 +02:00
parent fca15bd084
commit f4d05d25c5
13 changed files with 256 additions and 110 deletions

View file

@ -26,11 +26,11 @@
#include "nel/misc/uv.h"
#include "nel/misc/hierarchical_timer.h"
#include "nel/3d/texture.h"
#include "nel/3d/shader.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/index_buffer.h"
#include "nel/3d/vertex_program.h"
#include "nel/3d/pixel_program.h"
#include "nel/3d/geometry_program.h"
#include "nel/3d/material.h"
#include "nel/misc/mutex.h"
#include "nel/3d/primitive_profile.h"
@ -152,9 +152,6 @@ protected:
TIBDrvInfoPtrList _IBDrvInfos;
TPolygonMode _PolygonMode;
TGPUPrgDrvInfoPtrList _GPUPrgDrvInfos;
// TPixelPrgDrvInfoPtrList _PixelPrgDrvInfos;
// TGeomPrgDrvInfoPtrList _GeomPrgDrvInfos;
// TShaderDrvInfoPtrList _ShaderDrvInfos;
uint _ResetCounter;
@ -1299,9 +1296,6 @@ protected:
friend class CTextureDrvShare;
friend class ITextureDrvInfos;
friend class IMaterialDrvInfos;
// friend class IVertexProgramDrvInfos;
// friend class IPixelProgramDrvInfos;
// friend class IShaderDrvInfos;
friend class IGPUProgramDrvInfos;
/// remove ptr from the lists in the driver.
@ -1310,9 +1304,6 @@ protected:
void removeTextureDrvInfoPtr(ItTexDrvInfoPtrMap texDrvInfoIt);
void removeTextureDrvSharePtr(ItTexDrvSharePtrList texDrvShareIt);
void removeMatDrvInfoPtr(ItMatDrvInfoPtrList shaderIt);
// void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt);
// void removeVtxPrgDrvInfoPtr(ItVtxPrgDrvInfoPtrList vtxPrgDrvInfoIt);
// void removePixelPrgDrvInfoPtr(ItPixelPrgDrvInfoPtrList pixelPrgDrvInfoIt);
void removeGPUPrgDrvInfoPtr(ItGPUPrgDrvInfoPtrList gpuPrgDrvInfoIt);
private:

View file

@ -22,7 +22,6 @@
#include "nel/misc/rgba.h"
#include "nel/misc/matrix.h"
#include "nel/3d/texture.h"
#include "nel/3d/shader.h"
#include <memory>

View file

@ -1,32 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_SHADER_H
#define NL_SHADER_H
#include "nel/misc/types_nl.h"
#include "nel/misc/smart_ptr.h"
#include <list>
namespace NL3D {
} // NL3D
#endif // NL_SHADER_H
/* End of shader.h */

View file

@ -153,8 +153,6 @@ SOURCE_GROUP(Driver FILES
../../include/nel/3d/scene.h
scene_group.cpp
../../include/nel/3d/scene_group.h
shader.cpp
../../include/nel/3d/shader.h
texture.cpp
../../include/nel/3d/texture.h
vertex_buffer.cpp

View file

@ -20,7 +20,6 @@
#include "nel/misc/types_nl.h"
#include "nel/3d/driver.h"
#include "nel/3d/shader.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/misc/algo.h"
@ -94,14 +93,6 @@ bool IDriver::release(void)
// NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted);
delete *itmat;
}
/*
// Release Shader drv.
ItShaderDrvInfoPtrList itshd;
while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() )
{
// NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted);
delete *itshd;
}*/
// Release VBs drv.
ItVBDrvInfoPtrList itvb;

View file

@ -1710,6 +1710,13 @@ bool CDriverD3D::release()
// Call IDriver::release() before, to destroy textures, shaders and VBs...
IDriver::release();
ItShaderDrvInfoPtrList itshd;
while( (itshd = _ShaderDrvInfos.begin()) != _ShaderDrvInfos.end() )
{
// NB: at IShader deletion, this->_MatDrvInfos is updated (entry deleted);
delete *itshd;
}
_SwapBufferCounter = 0;
if (_QuadIB)

View file

@ -35,7 +35,6 @@
#include "nel/3d/scissor.h"
#include "nel/3d/driver.h"
#include "nel/3d/material.h"
#include "nel/3d/shader.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/index_buffer.h"
#include "nel/3d/ptr_set.h"
@ -181,6 +180,75 @@ public:
};
using NLMISC::CRefCount;
class IDriver;
class CDriverD3D;
// List typedef.
class IShaderDrvInfos;
typedef std::list<IShaderDrvInfos*> TShaderDrvInfoPtrList;
typedef TShaderDrvInfoPtrList::iterator ItShaderDrvInfoPtrList;
/**
* Interface for shader driver infos.
*/
class IShaderDrvInfos : public CRefCount
{
private:
CDriverD3D *_Driver;
ItShaderDrvInfoPtrList _DriverIterator;
public:
IShaderDrvInfos(CDriverD3D *drv, ItShaderDrvInfoPtrList it) {_Driver= drv; _DriverIterator= it;}
// The virtual dtor is important.
virtual ~IShaderDrvInfos();
};
/**
* Shader resource for the driver. It is just a container for a ".fx" text file.
*/
/* *** IMPORTANT ********************
* *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL
* **********************************
*/
// --------------------------------------------------
class CShader
{
public:
CShader();
~CShader();
// Load a shader file
bool loadShaderFile (const char *filename);
// Set the shader text
void setText (const char *text);
// Get the shader text
const char *getText () const { return _Text.c_str(); }
// Set the shader name
void setName (const char *name);
// Get the shader name
const char *getName () const { return _Name.c_str(); }
public:
// Private. For Driver only.
bool _ShaderChanged;
NLMISC::CRefPtr<IShaderDrvInfos> _DrvInfo;
private:
// The shader
std::string _Text;
// The shader name
std::string _Name;
};
// ***************************************************************************
class CTextureDrvInfosD3D : public ITextureDrvInfos
{
@ -229,29 +297,48 @@ public:
};
// ***************************************************************************
class CVertexProgamDrvInfosD3D : public IVertexProgramDrvInfos
class CVertexProgamDrvInfosD3D : public IGPUProgramDrvInfos
{
public:
// The shader
IDirect3DVertexShader9 *Shader;
CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it);
CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it);
~CVertexProgamDrvInfosD3D();
virtual uint getParamIdx(char *name) const
{
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> ParamIndices;
};
// ***************************************************************************
class CPixelProgramDrvInfosD3D : public IPixelProgramDrvInfos
class CPixelProgramDrvInfosD3D : public IGPUProgramDrvInfos
{
public:
// The shader
IDirect3DPixelShader9 *Shader;
CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it);
CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it);
~CPixelProgramDrvInfosD3D();
virtual uint getParamIdx(char *name) const
{
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second;
return ~0;
};
std::map<std::string, uint> ParamIndices;
};
@ -346,7 +433,7 @@ public:
// Scalar handles
D3DXHANDLE ScalarFloatHandle[MaxShaderTexture];
CShaderDrvInfosD3D(IDriver *drv, ItShaderDrvInfoPtrList it);
CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it);
virtual ~CShaderDrvInfosD3D();
};
@ -1048,7 +1135,7 @@ public:
* ColorOp[n] = DISABLE;
* AlphaOp[n] = DISABLE;
*/
virtual bool activeShader(CShader *shd);
bool activeShader(CShader *shd);
// Bench
virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true);
@ -1922,7 +2009,7 @@ public:
{
H_AUTO_D3D(CDriverD3D_getPixelProgramD3D);
CPixelProgramDrvInfosD3D* d3dPixelProgram;
d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IPixelProgramDrvInfos*)(pixelProgram._DrvInfo);
d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(pixelProgram._DrvInfo);
return d3dPixelProgram;
}
@ -1931,7 +2018,7 @@ public:
{
H_AUTO_D3D(CDriverD3D_getVertexProgramD3D);
CVertexProgamDrvInfosD3D* d3dVertexProgram;
d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IVertexProgramDrvInfos*)(vertexProgram._DrvInfo);
d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IGPUProgramDrvInfos*)(vertexProgram._DrvInfo);
return d3dVertexProgram;
}
@ -2114,6 +2201,8 @@ private:
void findNearestFullscreenVideoMode();
TShaderDrvInfoPtrList _ShaderDrvInfos;
// Windows
std::string _WindowClass;
HWND _HWnd;
@ -2563,6 +2652,10 @@ public:
// Clip the wanted rectangle with window. return true if rect is not NULL.
bool clipRect(NLMISC::CRect &rect);
friend class IShaderDrvInfos;
void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt);
};
#define NL_D3DCOLOR_RGBA(rgba) (D3DCOLOR_ARGB(rgba.A,rgba.R,rgba.G,rgba.B))

View file

@ -37,7 +37,7 @@ namespace NL3D
// ***************************************************************************
CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it)
CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it)
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgamDrvInfosD3D)
Shader = NULL;
@ -81,18 +81,32 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program)
// Program setuped ?
if (program->_DrvInfo==NULL)
{
_PixelPrgDrvInfos.push_front (NULL);
ItPixelPrgDrvInfoPtrList itPix = _PixelPrgDrvInfos.begin();
*itPix = new CPixelProgramDrvInfosD3D(this, itPix);
// Find a supported pixel program profile
CGPUProgramSource *source = NULL;
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
{
if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile))
{
source = program->getProgramSource()->Sources[i];
}
}
if (!source)
{
nlwarning("No supported source profile for pixel program");
return false;
}
_GPUPrgDrvInfos.push_front (NULL);
ItGPUPrgDrvInfoPtrList itPix = _GPUPrgDrvInfos.begin();
CPixelProgramDrvInfosD3D *drvInfo;
*itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix);
// Create a driver info structure
program->_DrvInfo = *itPix;
const std::string &dest = program->getProgram();
LPD3DXBUFFER pShader;
LPD3DXBUFFER pErrorMsgs;
if (D3DXAssembleShader (dest.c_str(), dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
if (D3DXAssembleShader(source->SourcePtr, source->SourceLen, NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
{
if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK)
return false;
@ -103,13 +117,19 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program)
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source->DisplayName.c_str(), source->Features);
}
}
// Set the pixel program
if (program)
{
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IPixelProgramDrvInfos*)program->_DrvInfo);
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IGPUProgramDrvInfos*)program->_DrvInfo);
setPixelShader (info->Shader);
float z = 0;

View file

@ -17,6 +17,8 @@
#include "stddirect3d.h"
#include "driver_direct3d.h"
#include "nel/misc/path.h"
#include "nel/misc/file.h"
using namespace std;
using namespace NLMISC;
@ -24,6 +26,93 @@ using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
CShader::~CShader()
{
// Must kill the drv mirror of this shader.
_DrvInfo.kill();
}
// ***************************************************************************
CShader::CShader()
{
_ShaderChanged = true;
}
// ***************************************************************************
void CShader::setText (const char *text)
{
_Text = text;
_ShaderChanged = true;
}
// ***************************************************************************
void CShader::setName (const char *name)
{
_Name = name;
_ShaderChanged = true;
}
// ***************************************************************************
bool CShader::loadShaderFile (const char *filename)
{
_Text = "";
// Lookup
string _filename = NLMISC::CPath::lookup(filename, false, true, true);
if (!_filename.empty())
{
// File length
uint size = NLMISC::CFile::getFileSize (_filename);
_Text.reserve (size+1);
try
{
NLMISC::CIFile file;
if (file.open (_filename))
{
// Read it
while (!file.eof ())
{
char line[512];
file.getline (line, 512);
_Text += line;
}
// Set the shader name
_Name = NLMISC::CFile::getFilename (filename);
return true;
}
else
{
nlwarning ("Can't open the file %s for reading", _filename.c_str());
}
}
catch (const Exception &e)
{
nlwarning ("Error while reading %s : %s", _filename.c_str(), e.what());
}
}
return false;
}
// ***************************************************************************
IShaderDrvInfos::~IShaderDrvInfos()
{
_Driver->removeShaderDrvInfoPtr(_DriverIterator);
}
void CDriverD3D::removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt)
{
_ShaderDrvInfos.erase(shaderIt);
}
// mem allocator for state records
std::allocator<uint8> CStateRecord::Allocator;
@ -249,7 +338,7 @@ HRESULT CDriverD3D::SetVertexShaderConstantI(UINT StartRegister, CONST INT* pCon
// ***************************************************************************
CShaderDrvInfosD3D::CShaderDrvInfosD3D(IDriver *drv, ItShaderDrvInfoPtrList it) : IShaderDrvInfos(drv, it)
CShaderDrvInfosD3D::CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it) : IShaderDrvInfos(drv, it)
{
H_AUTO_D3D(CShaderDrvInfosD3D_CShaderDrvInfosD3D)
Validated = false;

View file

@ -26,7 +26,7 @@ namespace NL3D
// ***************************************************************************
CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it)
CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it)
{
H_AUTO_D3D(CVertexProgamDrvInfosD3D_CVertexProgamDrvInfosD3D)
Shader = NULL;
@ -274,9 +274,25 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program)
// Program setuped ?
if (program->_DrvInfo==NULL)
{
_VtxPrgDrvInfos.push_front (NULL);
ItVtxPrgDrvInfoPtrList itTex = _VtxPrgDrvInfos.begin();
*itTex = new CVertexProgamDrvInfosD3D(this, itTex);
// Find nelvp
CGPUProgramSource *source = NULL;
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
{
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
{
source = program->getProgramSource()->Sources[i];
}
}
if (!source)
{
nlwarning("Direct3D driver only supports 'nelvp' profile, vertex program cannot be used");
return false;
}
_GPUPrgDrvInfos.push_front (NULL);
ItGPUPrgDrvInfoPtrList itTex = _GPUPrgDrvInfos.begin();
CVertexProgamDrvInfosD3D *drvInfo;
*itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex);
// Create a driver info structure
program->_DrvInfo = *itTex;
@ -287,7 +303,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program)
CVPParser parser;
CVPParser::TProgram parsedProgram;
std::string errorOutput;
bool result = parser.parse(program->getProgram().c_str(), parsedProgram, errorOutput);
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
if (!result)
{
nlwarning("Unable to parse a vertex program :");
@ -345,13 +361,19 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program)
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source->DisplayName.c_str(), source->Features);
}
}
// Set the vertex program
if (program)
{
CVertexProgamDrvInfosD3D *info = static_cast<CVertexProgamDrvInfosD3D *>((IVertexProgramDrvInfos*)program->_DrvInfo);
CVertexProgamDrvInfosD3D *info = static_cast<CVertexProgamDrvInfosD3D *>((IGPUProgramDrvInfos*)program->_DrvInfo);
setVertexProgram (info->Shader, program);
/* D3DRS_FOGSTART and D3DRS_FOGEND must be set with [1, 0] else the fog doesn't work properly on VertexShader and non-VertexShader objects

View file

@ -49,7 +49,6 @@
#include "nel/3d/driver.h"
#include "nel/3d/material.h"
#include "nel/3d/shader.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/ptr_set.h"
#include "nel/3d/texture_cube.h"

View file

@ -18,7 +18,6 @@
#include "nel/3d/material.h"
#include "nel/3d/texture.h"
#include "nel/3d/shader.h"
#include "nel/3d/driver.h"
#include "nel/misc/stream.h"

View file

@ -1,30 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "std3d.h"
#include "nel/3d/shader.h"
#include "nel/3d/driver.h"
#include "nel/misc/path.h"
#include "nel/misc/file.h"
using namespace std;
using namespace NLMISC;
namespace NL3D
{
} // NL3D