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)
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
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;
if (mState.sampleCoverage)
......
......@@ -53,6 +53,7 @@ class ProgramBinary : public RefCountObject
rx::ShaderExecutable *getPixelExecutable();
rx::ShaderExecutable *getVertexExecutable();
rx::ShaderExecutable *getGeometryExecutable();
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
......@@ -61,6 +62,8 @@ class ProgramBinary : public RefCountObject
TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
bool usesPointSpriteEmulation() const;
bool usesGeometryShader() const;
GLint getUniformLocation(std::string name);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
......@@ -117,10 +120,14 @@ class ProgramBinary : public RefCountObject
bool linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms);
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::ShaderExecutable *mPixelExecutable;
rx::ShaderExecutable *mVertexExecutable;
rx::ShaderExecutable *mGeometryExecutable;
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
......
......@@ -83,7 +83,8 @@ struct dx_PixelConstants
enum ShaderType
{
SHADER_VERTEX,
SHADER_PIXEL
SHADER_PIXEL,
SHADER_GEOMETRY
};
class Renderer
......
......@@ -1044,6 +1044,7 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
{
ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
ID3D11VertexShader *vertexShader = NULL;
if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
......@@ -1051,8 +1052,21 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
ID3D11PixelShader *pixelShader = NULL;
if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
ID3D11GeometryShader *geometryShader = NULL;
if (geometryExe) geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
mDeviceContext->PSSetShader(pixelShader, NULL, 0);
mDeviceContext->VSSetShader(vertexShader, NULL, 0);
if (geometryShader)
{
mDeviceContext->GSSetShader(geometryShader, NULL, 0);
}
else
{
mDeviceContext->GSSetShader(NULL, NULL, 0);
}
programBinary->dirtyAllUniforms();
mAppliedProgramBinarySerial = programBinarySerial;
......@@ -1221,7 +1235,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
delete[] mapVS;
delete[] mapPS;
......@@ -1269,6 +1283,9 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
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)
......@@ -1964,9 +1981,9 @@ int Renderer11::getMinorShaderModel() const
float Renderer11::getMaxPointSize() const
{
// TODO
// UNIMPLEMENTED();
return 1.0f;
// choose a reasonable maximum. we enforce this in the shader.
// (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
return 1024.0f;
}
int Renderer11::getMaxTextureWidth() const
......@@ -2406,6 +2423,18 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
}
}
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:
UNREACHABLE();
break;
......@@ -2426,6 +2455,9 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
case rx::SHADER_PIXEL:
profile = "ps_4_0";
break;
case rx::SHADER_GEOMETRY:
profile = "gs_4_0";
break;
default:
UNREACHABLE();
return NULL;
......
......@@ -19,6 +19,7 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
{
mPixelExecutable = executable;
mVertexExecutable = NULL;
mGeometryExecutable = NULL;
mConstantBuffer = NULL;
}
......@@ -28,6 +29,17 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
{
mVertexExecutable = executable;
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;
}
......@@ -42,6 +54,10 @@ ShaderExecutable11::~ShaderExecutable11()
{
mPixelExecutable->Release();
}
if (mGeometryExecutable)
{
mGeometryExecutable->Release();
}
if (mConstantBuffer)
{
......@@ -65,6 +81,11 @@ ID3D11PixelShader *ShaderExecutable11::getPixelShader() const
return mPixelExecutable;
}
ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const
{
return mGeometryExecutable;
}
ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount)
{
if (!mConstantBuffer && registerCount > 0)
......
......@@ -22,6 +22,7 @@ class ShaderExecutable11 : public ShaderExecutable
public:
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, ID3D11GeometryShader *executable);
virtual ~ShaderExecutable11();
......@@ -29,6 +30,7 @@ class ShaderExecutable11 : public ShaderExecutable
ID3D11PixelShader *getPixelShader() const;
ID3D11VertexShader *getVertexShader() const;
ID3D11GeometryShader *getGeometryShader() const;
ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount);
......@@ -37,6 +39,7 @@ class ShaderExecutable11 : public ShaderExecutable
ID3D11PixelShader *mPixelExecutable;
ID3D11VertexShader *mVertexExecutable;
ID3D11GeometryShader *mGeometryExecutable;
ID3D11Buffer *mConstantBuffer;
};
......
......@@ -507,6 +507,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
deviceContext->GSSetShader(NULL, NULL, 0);
// Apply render targets
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