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
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
{
if (mIndexRange.valid() || !isDrawElements())
......
......@@ -108,6 +108,7 @@ class DrawCallParams final : angle::NonCopyable
Error ensureIndexRangeResolved(const Context *context) const;
bool isDrawElements() const;
bool isDrawIndirect() const;
// ensureIndexRangeResolved must be called first.
const IndexRange &getIndexRange() const;
......
......@@ -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
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));
const gl::IndexRange &indexRange = drawCallParams.getIndexRange();
if (indexRange.end == gl::GetPrimitiveRestartIndex(drawCallParams.type()))
......
......@@ -149,7 +149,8 @@ class Context11 : public ContextImpl
gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context, GLenum drawMode);
private:
gl::Error prepareForDrawCall(const gl::Context *context, GLenum drawMode);
gl::Error prepareForDrawCall(const gl::Context *context,
const gl::DrawCallParams &drawCallParams);
Renderer11 *mRenderer;
};
......
......@@ -85,26 +85,15 @@ class InputLayoutCache : angle::NonCopyable
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
void setCacheSize(size_t newCacheSize);
gl::Error updateInputLayout(Renderer11 *renderer,
const gl::State &state,
const std::vector<const TranslatedAttribute *> &currentAttributes,
const AttribIndexArray &sortedSemanticIndices,
const gl::DrawCallParams &drawCallParams);
gl::Error getInputLayout(Renderer11 *renderer,
const gl::State &state,
const std::vector<const TranslatedAttribute *> &currentAttributes,
const AttribIndexArray &sortedSemanticIndices,
const gl::DrawCallParams &drawCallParams,
const d3d11::InputLayout **inputLayoutOut);
private:
gl::Error createInputLayout(Renderer11 *renderer,
......@@ -122,9 +111,6 @@ class InputLayoutCache : angle::NonCopyable
using LayoutCache = angle::base::HashingMRUCache<PackedAttributeLayout, d3d11::InputLayout>;
LayoutCache mLayoutCache;
d3d11::Buffer mPointSpriteVertexBuffer;
d3d11::Buffer mPointSpriteIndexBuffer;
};
} // namespace rx
......
......@@ -380,24 +380,10 @@ class Renderer11 : public RendererD3D
DeviceImpl *createEGLDevice() override;
gl::Error drawArrays(const gl::Context *context,
GLenum mode,
GLint startVertex,
GLsizei count,
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);
gl::Error drawArrays(const gl::Context *context, const gl::DrawCallParams &params);
gl::Error drawElements(const gl::Context *context, const gl::DrawCallParams &params);
gl::Error drawArraysIndirect(const gl::Context *context, const gl::DrawCallParams &params);
gl::Error drawElementsIndirect(const gl::Context *context, const gl::DrawCallParams &params);
// Necessary hack for default framebuffers in D3D.
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
......
......@@ -201,17 +201,9 @@ class StateManager11 final : angle::NonCopyable
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);
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,
UINT resourceSlot,
......@@ -342,6 +334,17 @@ class StateManager11 final : angle::NonCopyable
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
{
DIRTY_BIT_RENDER_TARGET,
......@@ -520,6 +523,9 @@ class StateManager11 final : angle::NonCopyable
ResourceSerial mCurrentComputeConstantBuffer;
ResourceSerial mCurrentGeometryConstantBuffer;
d3d11::Buffer mPointSpriteVertexBuffer;
d3d11::Buffer mPointSpriteIndexBuffer;
template <typename T>
using VertexConstantBufferArray =
std::array<T, gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS>;
......
......@@ -50,6 +50,7 @@ VertexArray11::VertexArray11(const gl::VertexArrayState &data)
mLastElementType(GL_NONE),
mLastDrawElementsOffset(0),
mCurrentElementArrayStorage(IndexStorageType::Invalid),
mCachedIndexInfo{0},
mCachedIndexInfoValid(false)
{
for (size_t attribIndex = 0; attribIndex < mCurrentArrayBuffers.size(); ++attribIndex)
......
......@@ -2358,46 +2358,6 @@ bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenu
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,
const gl::Buffer *elementArrayBuffer,
GLenum elementType,
......
......@@ -397,7 +397,6 @@ enum class StagingAccess
bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type);
bool IsStreamingIndexData(const gl::Context *context, GLenum srcType);
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