Implement gl_PointSize point sprite emulation using D3D11 geometry shaders.

TRAC #22412 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1786 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e0e8987b
...@@ -1712,7 +1712,17 @@ bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport) ...@@ -1712,7 +1712,17 @@ bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
void Context::applyState(GLenum drawMode) void Context::applyState(GLenum drawMode)
{ {
mRenderer->setRasterizerState(mState.rasterizer); // disable face culling for point sprite emulation (done as geometry shader quads)
if (getCurrentProgramBinary()->usesPointSpriteEmulation())
{
RasterizerState rasterizerStateCopy = mState.rasterizer;
rasterizerStateCopy.cullFace = false;
mRenderer->setRasterizerState(rasterizerStateCopy);
}
else
{
mRenderer->setRasterizerState(mState.rasterizer);
}
unsigned int mask = 0; unsigned int mask = 0;
if (mState.sampleCoverage) if (mState.sampleCoverage)
......
...@@ -53,6 +53,7 @@ class ProgramBinary : public RefCountObject ...@@ -53,6 +53,7 @@ class ProgramBinary : public RefCountObject
rx::ShaderExecutable *getPixelExecutable(); rx::ShaderExecutable *getPixelExecutable();
rx::ShaderExecutable *getVertexExecutable(); rx::ShaderExecutable *getVertexExecutable();
rx::ShaderExecutable *getGeometryExecutable();
GLuint getAttributeLocation(const char *name); GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex); int getSemanticIndex(int attributeIndex);
...@@ -61,6 +62,8 @@ class ProgramBinary : public RefCountObject ...@@ -61,6 +62,8 @@ class ProgramBinary : public RefCountObject
TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex); TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type); GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const; bool usesPointSize() const;
bool usesPointSpriteEmulation() const;
bool usesGeometryShader() const;
GLint getUniformLocation(std::string name); GLint getUniformLocation(std::string name);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
...@@ -117,10 +120,14 @@ class ProgramBinary : public RefCountObject ...@@ -117,10 +120,14 @@ class ProgramBinary : public RefCountObject
bool linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms); bool linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms);
bool defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog); bool defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog);
std::string generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
rx::Renderer *const mRenderer; rx::Renderer *const mRenderer;
rx::ShaderExecutable *mPixelExecutable; rx::ShaderExecutable *mPixelExecutable;
rx::ShaderExecutable *mVertexExecutable; rx::ShaderExecutable *mVertexExecutable;
rx::ShaderExecutable *mGeometryExecutable;
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS]; int mSemanticIndex[MAX_VERTEX_ATTRIBS];
......
...@@ -83,7 +83,8 @@ struct dx_PixelConstants ...@@ -83,7 +83,8 @@ struct dx_PixelConstants
enum ShaderType enum ShaderType
{ {
SHADER_VERTEX, SHADER_VERTEX,
SHADER_PIXEL SHADER_PIXEL,
SHADER_GEOMETRY
}; };
class Renderer class Renderer
......
...@@ -1044,6 +1044,7 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary) ...@@ -1044,6 +1044,7 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
{ {
ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
ID3D11VertexShader *vertexShader = NULL; ID3D11VertexShader *vertexShader = NULL;
if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader(); if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
...@@ -1051,8 +1052,21 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary) ...@@ -1051,8 +1052,21 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
ID3D11PixelShader *pixelShader = NULL; ID3D11PixelShader *pixelShader = NULL;
if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader(); if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
ID3D11GeometryShader *geometryShader = NULL;
if (geometryExe) geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
mDeviceContext->PSSetShader(pixelShader, NULL, 0); mDeviceContext->PSSetShader(pixelShader, NULL, 0);
mDeviceContext->VSSetShader(vertexShader, NULL, 0); mDeviceContext->VSSetShader(vertexShader, NULL, 0);
if (geometryShader)
{
mDeviceContext->GSSetShader(geometryShader, NULL, 0);
}
else
{
mDeviceContext->GSSetShader(NULL, NULL, 0);
}
programBinary->dirtyAllUniforms(); programBinary->dirtyAllUniforms();
mAppliedProgramBinarySerial = programBinarySerial; mAppliedProgramBinarySerial = programBinarySerial;
...@@ -1221,7 +1235,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra ...@@ -1221,7 +1235,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
delete[] mapVS; delete[] mapVS;
delete[] mapPS; delete[] mapPS;
...@@ -1269,6 +1283,9 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra ...@@ -1269,6 +1283,9 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0); mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants)); memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
} }
// needed for the point sprite geometry shader
mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
} }
void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
...@@ -1964,9 +1981,9 @@ int Renderer11::getMinorShaderModel() const ...@@ -1964,9 +1981,9 @@ int Renderer11::getMinorShaderModel() const
float Renderer11::getMaxPointSize() const float Renderer11::getMaxPointSize() const
{ {
// TODO // choose a reasonable maximum. we enforce this in the shader.
// UNIMPLEMENTED(); // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
return 1.0f; return 1024.0f;
} }
int Renderer11::getMaxTextureWidth() const int Renderer11::getMaxTextureWidth() const
...@@ -2406,6 +2423,18 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length ...@@ -2406,6 +2423,18 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
} }
} }
break; break;
case rx::SHADER_GEOMETRY:
{
ID3D11GeometryShader *gshader = NULL;
HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &gshader);
ASSERT(SUCCEEDED(result));
if (gshader)
{
executable = new ShaderExecutable11(function, length, gshader);
}
}
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -2426,6 +2455,9 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch ...@@ -2426,6 +2455,9 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
case rx::SHADER_PIXEL: case rx::SHADER_PIXEL:
profile = "ps_4_0"; profile = "ps_4_0";
break; break;
case rx::SHADER_GEOMETRY:
profile = "gs_4_0";
break;
default: default:
UNREACHABLE(); UNREACHABLE();
return NULL; return NULL;
......
...@@ -19,6 +19,7 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D ...@@ -19,6 +19,7 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
{ {
mPixelExecutable = executable; mPixelExecutable = executable;
mVertexExecutable = NULL; mVertexExecutable = NULL;
mGeometryExecutable = NULL;
mConstantBuffer = NULL; mConstantBuffer = NULL;
} }
...@@ -28,6 +29,17 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D ...@@ -28,6 +29,17 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
{ {
mVertexExecutable = executable; mVertexExecutable = executable;
mPixelExecutable = NULL; mPixelExecutable = NULL;
mGeometryExecutable = NULL;
mConstantBuffer = NULL;
}
ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable)
: ShaderExecutable(function, length)
{
mGeometryExecutable = executable;
mVertexExecutable = NULL;
mPixelExecutable = NULL;
mConstantBuffer = NULL; mConstantBuffer = NULL;
} }
...@@ -42,6 +54,10 @@ ShaderExecutable11::~ShaderExecutable11() ...@@ -42,6 +54,10 @@ ShaderExecutable11::~ShaderExecutable11()
{ {
mPixelExecutable->Release(); mPixelExecutable->Release();
} }
if (mGeometryExecutable)
{
mGeometryExecutable->Release();
}
if (mConstantBuffer) if (mConstantBuffer)
{ {
...@@ -65,6 +81,11 @@ ID3D11PixelShader *ShaderExecutable11::getPixelShader() const ...@@ -65,6 +81,11 @@ ID3D11PixelShader *ShaderExecutable11::getPixelShader() const
return mPixelExecutable; return mPixelExecutable;
} }
ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const
{
return mGeometryExecutable;
}
ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount) ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount)
{ {
if (!mConstantBuffer && registerCount > 0) if (!mConstantBuffer && registerCount > 0)
......
...@@ -22,6 +22,7 @@ class ShaderExecutable11 : public ShaderExecutable ...@@ -22,6 +22,7 @@ class ShaderExecutable11 : public ShaderExecutable
public: public:
ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable); ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable);
ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable); ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable);
ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable);
virtual ~ShaderExecutable11(); virtual ~ShaderExecutable11();
...@@ -29,6 +30,7 @@ class ShaderExecutable11 : public ShaderExecutable ...@@ -29,6 +30,7 @@ class ShaderExecutable11 : public ShaderExecutable
ID3D11PixelShader *getPixelShader() const; ID3D11PixelShader *getPixelShader() const;
ID3D11VertexShader *getVertexShader() const; ID3D11VertexShader *getVertexShader() const;
ID3D11GeometryShader *getGeometryShader() const;
ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount); ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount);
...@@ -37,6 +39,7 @@ class ShaderExecutable11 : public ShaderExecutable ...@@ -37,6 +39,7 @@ class ShaderExecutable11 : public ShaderExecutable
ID3D11PixelShader *mPixelExecutable; ID3D11PixelShader *mPixelExecutable;
ID3D11VertexShader *mVertexExecutable; ID3D11VertexShader *mVertexExecutable;
ID3D11GeometryShader *mGeometryExecutable;
ID3D11Buffer *mConstantBuffer; ID3D11Buffer *mConstantBuffer;
}; };
......
...@@ -507,6 +507,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) ...@@ -507,6 +507,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
deviceContext->VSSetShader(mPassThroughVS, NULL, 0); deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
deviceContext->PSSetShader(mPassThroughPS, NULL, 0); deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
deviceContext->GSSetShader(NULL, NULL, 0);
// Apply render targets // Apply render targets
deviceContext->OMSetRenderTargets(1, &mBackBufferRTView, NULL); deviceContext->OMSetRenderTargets(1, &mBackBufferRTView, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment