Commit 4c5c6bbb by Geoff Lang

Add support for drawing with transform feedback.

BUG=angle:495 Change-Id: Ib9c19130dfbc44a99998c5d6d8160bfc2b683eb9 Reviewed-on: https://chromium-review.googlesource.com/185037Tested-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent 1b3e4b80
...@@ -2491,14 +2491,14 @@ void Context::applyState(GLenum drawMode) ...@@ -2491,14 +2491,14 @@ void Context::applyState(GLenum drawMode)
} }
// Applies the shaders and shader constants to the Direct3D 9 device // Applies the shaders and shader constants to the Direct3D 9 device
void Context::applyShaders(ProgramBinary *programBinary) void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
{ {
const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes(); const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes();
VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues); VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues);
mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, inputLayout); mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, transformFeedbackActive, inputLayout);
programBinary->applyUniforms(); programBinary->applyUniforms();
} }
...@@ -2981,7 +2981,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan ...@@ -2981,7 +2981,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
bool transformFeedbackActive = applyTransformFeedbackBuffers(); bool transformFeedbackActive = applyTransformFeedbackBuffers();
applyShaders(programBinary); applyShaders(programBinary, transformFeedbackActive);
applyTextures(programBinary); applyTextures(programBinary);
if (!applyUniformBuffers()) if (!applyUniformBuffers())
...@@ -2996,7 +2996,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan ...@@ -2996,7 +2996,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
if (!skipDraw(mode)) if (!skipDraw(mode))
{ {
mRenderer->drawArrays(mode, count, instances); mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
if (transformFeedbackActive) if (transformFeedbackActive)
{ {
...@@ -3054,7 +3054,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid ...@@ -3054,7 +3054,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
// layer. // layer.
ASSERT(!transformFeedbackActive); ASSERT(!transformFeedbackActive);
applyShaders(programBinary); applyShaders(programBinary, transformFeedbackActive);
applyTextures(programBinary); applyTextures(programBinary);
if (!applyUniformBuffers()) if (!applyUniformBuffers())
......
...@@ -464,7 +464,7 @@ class Context ...@@ -464,7 +464,7 @@ class Context
bool applyRenderTarget(GLenum drawMode, bool ignoreViewport); bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode); void applyState(GLenum drawMode);
void applyShaders(ProgramBinary *programBinary); void applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
void applyTextures(ProgramBinary *programBinary); void applyTextures(ProgramBinary *programBinary);
void applyTextures(ProgramBinary *programBinary, SamplerType type); void applyTextures(ProgramBinary *programBinary, SamplerType type);
bool applyUniformBuffers(); bool applyUniformBuffers();
......
...@@ -127,7 +127,7 @@ class Renderer ...@@ -127,7 +127,7 @@ class Renderer
bool ignoreViewport) = 0; bool ignoreViewport) = 0;
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0; virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]) = 0; virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]) = 0;
virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0; virtual void applyUniforms(const gl::ProgramBinary &programBinary) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
...@@ -135,8 +135,9 @@ class Renderer ...@@ -135,8 +135,9 @@ class Renderer
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0; virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) = 0;
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0; virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0; virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
......
...@@ -99,6 +99,7 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc( ...@@ -99,6 +99,7 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(
mAppliedVertexShader = NULL; mAppliedVertexShader = NULL;
mAppliedGeometryShader = NULL; mAppliedGeometryShader = NULL;
mCurPointGeometryShader = NULL;
mAppliedPixelShader = NULL; mAppliedPixelShader = NULL;
} }
...@@ -1217,9 +1218,41 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff ...@@ -1217,9 +1218,41 @@ void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuff
} }
} }
void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances) void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive)
{ {
if (mode == GL_LINE_LOOP) if (mode == GL_POINTS && transformFeedbackActive)
{
// Since point sprites are generated with a geometry shader, too many vertices will
// be written if transform feedback is active. To work around this, draw only the points
// with the stream out shader and no pixel shader to feed the stream out buffers and then
// draw again with the point sprite geometry shader to rasterize the point sprites.
mDeviceContext->PSSetShader(NULL, NULL, 0);
if (instances > 0)
{
mDeviceContext->DrawInstanced(count, instances, 0, 0);
}
else
{
mDeviceContext->Draw(count, 0);
}
mDeviceContext->GSSetShader(mCurPointGeometryShader, NULL, 0);
mDeviceContext->PSSetShader(mAppliedPixelShader, NULL, 0);
if (instances > 0)
{
mDeviceContext->DrawInstanced(count, instances, 0, 0);
}
else
{
mDeviceContext->Draw(count, 0);
}
mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0);
}
else if (mode == GL_LINE_LOOP)
{ {
drawLineLoop(count, GL_NONE, NULL, 0, NULL); drawLineLoop(count, GL_NONE, NULL, 0, NULL);
} }
...@@ -1237,7 +1270,8 @@ void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances) ...@@ -1237,7 +1270,8 @@ void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
} }
} }
void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
{ {
if (mode == GL_LINE_LOOP) if (mode == GL_LINE_LOOP)
{ {
...@@ -1480,26 +1514,29 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic ...@@ -1480,26 +1514,29 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
} }
} }
void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]) void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[])
{ {
ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL); ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
ID3D11PixelShader *pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL);
ID3D11GeometryShader *geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
// Skip GS if we aren't drawing points ID3D11PixelShader *pixelShader = NULL;
if (!mCurRasterState.pointDrawMode) // Skip pixel shader if we're doing rasterizer discard.
if (!rasterizerDiscard)
{ {
geometryShader = NULL; pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL);
} }
// Skip pixel shader if we're doing rasterizer discard. ID3D11GeometryShader *geometryShader = NULL;
if (rasterizerDiscard) if (transformFeedbackActive)
{
geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL);
}
else if (mCurRasterState.pointDrawMode)
{ {
pixelShader = NULL; geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
} }
bool dirtyUniforms = false; bool dirtyUniforms = false;
...@@ -1518,6 +1555,15 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerD ...@@ -1518,6 +1555,15 @@ void Renderer11::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerD
dirtyUniforms = true; dirtyUniforms = true;
} }
if (geometryExe && mCurRasterState.pointDrawMode)
{
mCurPointGeometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
}
else
{
mCurPointGeometryShader = NULL;
}
if (pixelShader != mAppliedPixelShader) if (pixelShader != mAppliedPixelShader)
{ {
mDeviceContext->PSSetShader(pixelShader, NULL, 0); mDeviceContext->PSSetShader(pixelShader, NULL, 0);
...@@ -1723,6 +1769,7 @@ void Renderer11::markAllStateDirty() ...@@ -1723,6 +1769,7 @@ void Renderer11::markAllStateDirty()
mAppliedVertexShader = NULL; mAppliedVertexShader = NULL;
mAppliedGeometryShader = NULL; mAppliedGeometryShader = NULL;
mCurPointGeometryShader = NULL;
mAppliedPixelShader = NULL; mAppliedPixelShader = NULL;
for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
......
...@@ -76,15 +76,16 @@ class Renderer11 : public Renderer ...@@ -76,15 +76,16 @@ class Renderer11 : public Renderer
virtual bool applyPrimitiveType(GLenum mode, GLsizei count); virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]); virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]);
virtual void applyUniforms(const gl::ProgramBinary &programBinary); virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances); GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
...@@ -364,6 +365,7 @@ class Renderer11 : public Renderer ...@@ -364,6 +365,7 @@ class Renderer11 : public Renderer
// Currently applied shaders // Currently applied shaders
ID3D11VertexShader *mAppliedVertexShader; ID3D11VertexShader *mAppliedVertexShader;
ID3D11GeometryShader *mAppliedGeometryShader; ID3D11GeometryShader *mAppliedGeometryShader;
ID3D11GeometryShader *mCurPointGeometryShader;
ID3D11PixelShader *mAppliedPixelShader; ID3D11PixelShader *mAppliedPixelShader;
dx_VertexConstants mVertexConstants; dx_VertexConstants mVertexConstants;
......
...@@ -1452,8 +1452,10 @@ void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffe ...@@ -1452,8 +1452,10 @@ void Renderer9::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffe
UNREACHABLE(); UNREACHABLE();
} }
void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances) void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive)
{ {
ASSERT(!transformFeedbackActive);
startScene(); startScene();
if (mode == GL_LINE_LOOP) if (mode == GL_LINE_LOOP)
...@@ -1490,7 +1492,8 @@ void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances) ...@@ -1490,7 +1492,8 @@ void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
} }
} }
void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/)
{ {
startScene(); startScene();
...@@ -1730,8 +1733,9 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi ...@@ -1730,8 +1733,9 @@ void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indi
} }
} }
void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]) void Renderer9::applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[])
{ {
ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard); ASSERT(!rasterizerDiscard);
ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout);
......
...@@ -76,7 +76,7 @@ class Renderer9 : public Renderer ...@@ -76,7 +76,7 @@ class Renderer9 : public Renderer
bool ignoreViewport); bool ignoreViewport);
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, const gl::VertexFormat inputLayout[]); virtual void applyShaders(gl::ProgramBinary *programBinary, bool rasterizerDiscard, bool transformFeedbackActive, const gl::VertexFormat inputLayout[]);
virtual void applyUniforms(const gl::ProgramBinary &programBinary); virtual void applyUniforms(const gl::ProgramBinary &programBinary);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[], virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
...@@ -85,8 +85,9 @@ class Renderer9 : public Renderer ...@@ -85,8 +85,9 @@ class Renderer9 : public Renderer
virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]); virtual void applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
......
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