Commit d779f6a9 by Jamie Madill Committed by Commit Bot

D3D11: Refactor draw call functions.

This allow for better code reuse for the Indirect draw calls. It also cleans up the InputLayoutCache to be only responsible for caching input layouts, and moves the logic for maintaining state into StateManager11. Bug: angleproject:2389 Change-Id: I84aae164bf1b94a394743cf58650adfdcfc2c17a Reviewed-on: https://chromium-review.googlesource.com/948796 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent a07b4213
...@@ -143,6 +143,13 @@ bool DrawCallParams::isDrawElements() const ...@@ -143,6 +143,13 @@ bool DrawCallParams::isDrawElements() const
return (mType != GL_NONE); return (mType != GL_NONE);
} }
bool DrawCallParams::isDrawIndirect() const
{
// This is a bit of a hack - it's quite possible for a direct call to have a zero count, but we
// assume these calls are filtered out before they make it to this code.
return (mIndexCount == 0 && mVertexCount == 0);
}
Error DrawCallParams::ensureIndexRangeResolved(const Context *context) const Error DrawCallParams::ensureIndexRangeResolved(const Context *context) const
{ {
if (mIndexRange.valid() || !isDrawElements()) if (mIndexRange.valid() || !isDrawElements())
......
...@@ -108,6 +108,7 @@ class DrawCallParams final : angle::NonCopyable ...@@ -108,6 +108,7 @@ class DrawCallParams final : angle::NonCopyable
Error ensureIndexRangeResolved(const Context *context) const; Error ensureIndexRangeResolved(const Context *context) const;
bool isDrawElements() const; bool isDrawElements() const;
bool isDrawIndirect() const;
// ensureIndexRangeResolved must be called first. // ensureIndexRangeResolved must be called first.
const IndexRange &getIndexRange() const; const IndexRange &getIndexRange() const;
......
...@@ -308,6 +308,13 @@ gl::Error GetIndexTranslationDestType(const gl::Context *context, ...@@ -308,6 +308,13 @@ gl::Error GetIndexTranslationDestType(const gl::Context *context,
// see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
if (usePrimitiveRestartWorkaround) if (usePrimitiveRestartWorkaround)
{ {
// Conservatively assume we need to translate the indices for draw indirect.
if (drawCallParams.isDrawIndirect())
{
*destTypeOut = GL_UNSIGNED_INT;
return gl::NoError();
}
ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context)); ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
const gl::IndexRange &indexRange = drawCallParams.getIndexRange(); const gl::IndexRange &indexRange = drawCallParams.getIndexRange();
if (indexRange.end == gl::GetPrimitiveRestartIndex(drawCallParams.type())) if (indexRange.end == gl::GetPrimitiveRestartIndex(drawCallParams.type()))
......
...@@ -149,7 +149,8 @@ class Context11 : public ContextImpl ...@@ -149,7 +149,8 @@ class Context11 : public ContextImpl
gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context, GLenum drawMode); gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context, GLenum drawMode);
private: private:
gl::Error prepareForDrawCall(const gl::Context *context, GLenum drawMode); gl::Error prepareForDrawCall(const gl::Context *context,
const gl::DrawCallParams &drawCallParams);
Renderer11 *mRenderer; Renderer11 *mRenderer;
}; };
......
...@@ -85,26 +85,15 @@ class InputLayoutCache : angle::NonCopyable ...@@ -85,26 +85,15 @@ class InputLayoutCache : angle::NonCopyable
void clear(); void clear();
gl::Error applyVertexBuffers(const gl::Context *context,
const std::vector<const TranslatedAttribute *> &currentAttributes,
GLenum mode,
GLint start,
bool isIndexedRendering);
gl::Error updateVertexOffsetsForPointSpritesEmulation(
Renderer11 *renderer,
const std::vector<const TranslatedAttribute *> &currentAttributes,
GLint startVertex,
GLsizei emulatedInstanceId);
// Useful for testing // Useful for testing
void setCacheSize(size_t newCacheSize); void setCacheSize(size_t newCacheSize);
gl::Error updateInputLayout(Renderer11 *renderer, gl::Error getInputLayout(Renderer11 *renderer,
const gl::State &state, const gl::State &state,
const std::vector<const TranslatedAttribute *> &currentAttributes, const std::vector<const TranslatedAttribute *> &currentAttributes,
const AttribIndexArray &sortedSemanticIndices, const AttribIndexArray &sortedSemanticIndices,
const gl::DrawCallParams &drawCallParams); const gl::DrawCallParams &drawCallParams,
const d3d11::InputLayout **inputLayoutOut);
private: private:
gl::Error createInputLayout(Renderer11 *renderer, gl::Error createInputLayout(Renderer11 *renderer,
...@@ -122,9 +111,6 @@ class InputLayoutCache : angle::NonCopyable ...@@ -122,9 +111,6 @@ class InputLayoutCache : angle::NonCopyable
using LayoutCache = angle::base::HashingMRUCache<PackedAttributeLayout, d3d11::InputLayout>; using LayoutCache = angle::base::HashingMRUCache<PackedAttributeLayout, d3d11::InputLayout>;
LayoutCache mLayoutCache; LayoutCache mLayoutCache;
d3d11::Buffer mPointSpriteVertexBuffer;
d3d11::Buffer mPointSpriteIndexBuffer;
}; };
} // namespace rx } // namespace rx
......
...@@ -380,24 +380,10 @@ class Renderer11 : public RendererD3D ...@@ -380,24 +380,10 @@ class Renderer11 : public RendererD3D
DeviceImpl *createEGLDevice() override; DeviceImpl *createEGLDevice() override;
gl::Error drawArrays(const gl::Context *context, gl::Error drawArrays(const gl::Context *context, const gl::DrawCallParams &params);
GLenum mode, gl::Error drawElements(const gl::Context *context, const gl::DrawCallParams &params);
GLint startVertex, gl::Error drawArraysIndirect(const gl::Context *context, const gl::DrawCallParams &params);
GLsizei count, gl::Error drawElementsIndirect(const gl::Context *context, const gl::DrawCallParams &params);
GLsizei instances);
gl::Error drawElements(const gl::Context *context,
GLenum mode,
GLsizei count,
GLenum type,
const void *indices,
GLsizei instances);
gl::Error drawArraysIndirect(const gl::Context *context, GLenum mode, const void *indirect);
gl::Error drawElementsIndirect(const gl::Context *context,
GLenum mode,
GLenum type,
const void *indirect);
// Necessary hack for default framebuffers in D3D. // Necessary hack for default framebuffers in D3D.
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
......
...@@ -201,17 +201,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -201,17 +201,9 @@ class StateManager11 final : angle::NonCopyable
void setInputLayout(const d3d11::InputLayout *inputLayout); void setInputLayout(const d3d11::InputLayout *inputLayout);
// TODO(jmadill): Migrate to d3d11::Buffer.
bool queueVertexBufferChange(size_t bufferIndex,
ID3D11Buffer *buffer,
UINT stride,
UINT offset);
bool queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly);
void applyVertexBufferChanges();
void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset); void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset);
gl::Error updateState(const gl::Context *context, GLenum drawMode); gl::Error updateState(const gl::Context *context, const gl::DrawCallParams &drawCallParams);
void setShaderResourceShared(gl::ShaderType shaderType, void setShaderResourceShared(gl::ShaderType shaderType,
UINT resourceSlot, UINT resourceSlot,
...@@ -342,6 +334,17 @@ class StateManager11 final : angle::NonCopyable ...@@ -342,6 +334,17 @@ class StateManager11 final : angle::NonCopyable
bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
bool setInputLayoutInternal(const d3d11::InputLayout *inputLayout);
gl::Error applyVertexBuffers(const gl::Context *context,
const gl::DrawCallParams &drawCallParams);
// TODO(jmadill): Migrate to d3d11::Buffer.
bool queueVertexBufferChange(size_t bufferIndex,
ID3D11Buffer *buffer,
UINT stride,
UINT offset);
void applyVertexBufferChanges();
enum DirtyBitType enum DirtyBitType
{ {
DIRTY_BIT_RENDER_TARGET, DIRTY_BIT_RENDER_TARGET,
...@@ -520,6 +523,9 @@ class StateManager11 final : angle::NonCopyable ...@@ -520,6 +523,9 @@ class StateManager11 final : angle::NonCopyable
ResourceSerial mCurrentComputeConstantBuffer; ResourceSerial mCurrentComputeConstantBuffer;
ResourceSerial mCurrentGeometryConstantBuffer; ResourceSerial mCurrentGeometryConstantBuffer;
d3d11::Buffer mPointSpriteVertexBuffer;
d3d11::Buffer mPointSpriteIndexBuffer;
template <typename T> template <typename T>
using VertexConstantBufferArray = using VertexConstantBufferArray =
std::array<T, gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS>; std::array<T, gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS>;
......
...@@ -50,6 +50,7 @@ VertexArray11::VertexArray11(const gl::VertexArrayState &data) ...@@ -50,6 +50,7 @@ VertexArray11::VertexArray11(const gl::VertexArrayState &data)
mLastElementType(GL_NONE), mLastElementType(GL_NONE),
mLastDrawElementsOffset(0), mLastDrawElementsOffset(0),
mCurrentElementArrayStorage(IndexStorageType::Invalid), mCurrentElementArrayStorage(IndexStorageType::Invalid),
mCachedIndexInfo{0},
mCachedIndexInfoValid(false) mCachedIndexInfoValid(false)
{ {
for (size_t attribIndex = 0; attribIndex < mCurrentArrayBuffers.size(); ++attribIndex) for (size_t attribIndex = 0; attribIndex < mCurrentArrayBuffers.size(); ++attribIndex)
......
...@@ -2358,46 +2358,6 @@ bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenu ...@@ -2358,46 +2358,6 @@ bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenu
return (!primitiveRestartFixedIndexEnabled && type == GL_UNSIGNED_SHORT); return (!primitiveRestartFixedIndexEnabled && type == GL_UNSIGNED_SHORT);
} }
bool IsStreamingIndexData(const gl::Context *context, GLenum srcType)
{
const auto &glState = context->getGLState();
gl::Buffer *glBuffer = glState.getVertexArray()->getElementArrayBuffer().get();
// Case 1: the indices are passed by pointer, which forces the streaming of index data
if (glBuffer == nullptr)
{
return true;
}
bool primitiveRestartWorkaround =
UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType);
BufferD3D *buffer = GetImplAs<BufferD3D>(glBuffer);
const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround)
? GL_UNSIGNED_INT
: GL_UNSIGNED_SHORT;
// Case 2a: the buffer can be used directly
if (buffer->supportsDirectBinding() && dstType == srcType)
{
return false;
}
// Case 2b: use a static translated copy or fall back to streaming
StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer();
if (staticBuffer == nullptr)
{
return true;
}
if ((staticBuffer->getBufferSize() == 0) || (staticBuffer->getIndexType() != dstType))
{
return true;
}
return false;
}
IndexStorageType ClassifyIndexStorage(const gl::State &glState, IndexStorageType ClassifyIndexStorage(const gl::State &glState,
const gl::Buffer *elementArrayBuffer, const gl::Buffer *elementArrayBuffer,
GLenum elementType, GLenum elementType,
......
...@@ -397,7 +397,6 @@ enum class StagingAccess ...@@ -397,7 +397,6 @@ enum class StagingAccess
bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer); bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type); bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type);
bool IsStreamingIndexData(const gl::Context *context, GLenum srcType);
enum class IndexStorageType enum class IndexStorageType
{ {
......
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