Commit d8fa9215 by Jamie Madill

D3D: Refactor VertexBuffer::getSpaceRequired.

By making this a virtual call to BufferFactoryD3D (aka RendererD3D), we can also stop having side-effects in the BufferD3D class of creating a static buffer storage when we only want to know the space required for some vertex elements. This refactoring will aid implementation of VertexArray11 dirty bits. BUG=angleproject:1327 Change-Id: I0e34c6e9f5da35edebc179d578ad9392dc0166db Reviewed-on: https://chromium-review.googlesource.com/329741Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 7ec6549d
...@@ -88,6 +88,10 @@ class BufferFactoryD3D ...@@ -88,6 +88,10 @@ class BufferFactoryD3D
// TODO(jmadill): add VertexFormatCaps // TODO(jmadill): add VertexFormatCaps
virtual VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const = 0; virtual VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const = 0;
virtual GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const = 0; virtual GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const = 0;
virtual gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(
const gl::VertexAttribute &attrib,
GLsizei count,
GLsizei instances) const = 0;
}; };
class RendererD3D : public Renderer, public BufferFactoryD3D class RendererD3D : public Renderer, public BufferFactoryD3D
......
...@@ -98,15 +98,14 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute ...@@ -98,15 +98,14 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute
unsigned int *outStreamOffset, unsigned int *outStreamOffset,
const uint8_t *sourceData) const uint8_t *sourceData)
{ {
gl::Error error(GL_NO_ERROR); auto errorOrSpaceRequired = mFactory->getVertexSpaceRequired(attrib, count, instances);
if (errorOrSpaceRequired.isError())
unsigned int spaceRequired;
error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired);
if (error.isError())
{ {
return error; return errorOrSpaceRequired.getError();
} }
unsigned int spaceRequired = errorOrSpaceRequired.getResult();
// Align to 16-byte boundary // Align to 16-byte boundary
unsigned int alignedSpaceRequired = roundUp(spaceRequired, 16u); unsigned int alignedSpaceRequired = roundUp(spaceRequired, 16u);
...@@ -117,7 +116,7 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute ...@@ -117,7 +116,7 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute
return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow."); return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow.");
} }
error = reserveSpace(mReservedSpace); gl::Error error = reserveSpace(mReservedSpace);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -142,15 +141,14 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute ...@@ -142,15 +141,14 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute
gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances)
{ {
gl::Error error(GL_NO_ERROR); auto errorOrRequiredSpace = mFactory->getVertexSpaceRequired(attrib, count, instances);
if (errorOrRequiredSpace.isError())
unsigned int requiredSpace;
error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace);
if (error.isError())
{ {
return error; return errorOrRequiredSpace.getError();
} }
unsigned int requiredSpace = errorOrRequiredSpace.getResult();
// Align to 16-byte boundary // Align to 16-byte boundary
unsigned int alignedRequiredSpace = roundUp(requiredSpace, 16u); unsigned int alignedRequiredSpace = roundUp(requiredSpace, 16u);
......
...@@ -44,8 +44,6 @@ class VertexBuffer : angle::NonCopyable ...@@ -44,8 +44,6 @@ class VertexBuffer : angle::NonCopyable
GLsizei instances, GLsizei instances,
unsigned int offset, unsigned int offset,
const uint8_t *sourceData) = 0; const uint8_t *sourceData) = 0;
virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
unsigned int *outSpaceRequired) const = 0;
virtual unsigned int getBufferSize() const = 0; virtual unsigned int getBufferSize() const = 0;
virtual gl::Error setBufferSize(unsigned int size) = 0; virtual gl::Error setBufferSize(unsigned int size) = 0;
......
...@@ -68,37 +68,36 @@ bool DirectStoragePossible(const gl::VertexAttribute &attrib) ...@@ -68,37 +68,36 @@ bool DirectStoragePossible(const gl::VertexAttribute &attrib)
return false; return false;
} }
StaticVertexBufferInterface *staticBuffer =
bufferD3D->getStaticVertexBuffer(attrib, D3D_BUFFER_CREATE_IF_NECESSARY);
// Dynamic buffers can not be stored directly.
if (!staticBuffer)
{
return false;
}
// Alignment restrictions: In D3D, vertex data must be aligned to the format stride, or to a // Alignment restrictions: In D3D, vertex data must be aligned to the format stride, or to a
// 4-byte boundary, whichever is smaller. (Undocumented, and experimentally confirmed) // 4-byte boundary, whichever is smaller. (Undocumented, and experimentally confirmed)
size_t alignment = 4; size_t alignment = 4;
bool requiresConversion = false;
if (attrib.type != GL_FLOAT) if (attrib.type != GL_FLOAT)
{ {
gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib); gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
unsigned int outputElementSize;
staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
alignment = std::min<size_t>(outputElementSize, 4);
// TODO(jmadill): add VertexFormatCaps // TODO(jmadill): add VertexFormatCaps
BufferFactoryD3D *factory = bufferD3D->getFactory(); BufferFactoryD3D *factory = bufferD3D->getFactory();
requiresConversion =
(factory->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_CPU) != 0;
}
bool isAligned = (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) && auto errorOrElementSize = factory->getVertexSpaceRequired(attrib, 1, 0);
(static_cast<size_t>(attrib.offset) % alignment == 0); if (errorOrElementSize.isError())
{
ERR("Unlogged error in DirectStoragePossible.");
return false;
}
alignment = std::min<size_t>(errorOrElementSize.getResult(), 4);
return !requiresConversion && isAligned; // CPU-converted vertex data must be converted (naturally).
if ((factory->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_CPU) != 0)
{
return false;
}
}
// Final alignment check - unaligned data must be converted.
return (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) &&
(static_cast<size_t>(attrib.offset) % alignment == 0);
} }
} // anonymous namespace } // anonymous namespace
...@@ -380,16 +379,21 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -380,16 +379,21 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
} }
unsigned int streamOffset = 0; unsigned int streamOffset = 0;
unsigned int outputElementSize = 0;
if (staticBuffer) auto errorOrOutputElementSize = mFactory->getVertexSpaceRequired(attrib, 1, 0);
if (errorOrOutputElementSize.isError())
{ {
gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); return errorOrOutputElementSize.getError();
if (error.isError()) }
{
return error; translated->storage = nullptr;
} translated->stride = errorOrOutputElementSize.getResult();
translated->serial = vertexBuffer->getSerial();
gl::Error error(GL_NO_ERROR);
if (staticBuffer)
{
if (!staticBuffer->lookupAttribute(attrib, &streamOffset)) if (!staticBuffer->lookupAttribute(attrib, &streamOffset))
{ {
// Convert the entire buffer // Convert the entire buffer
...@@ -414,9 +418,9 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -414,9 +418,9 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
unsigned int firstElementOffset = unsigned int firstElementOffset =
(static_cast<unsigned int>(attrib.offset) / (static_cast<unsigned int>(attrib.offset) /
static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) * static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) *
outputElementSize; translated->stride;
ASSERT(attrib.divisor == 0 || firstVertexIndex == 0); ASSERT(attrib.divisor == 0 || firstVertexIndex == 0);
unsigned int startOffset = firstVertexIndex * outputElementSize; unsigned int startOffset = firstVertexIndex * translated->stride;
if (streamOffset + firstElementOffset + startOffset < streamOffset) if (streamOffset + firstElementOffset + startOffset < streamOffset)
{ {
return gl::Error(GL_OUT_OF_MEMORY); return gl::Error(GL_OUT_OF_MEMORY);
...@@ -427,11 +431,6 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -427,11 +431,6 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
else else
{ {
size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
if (error.isError())
{
return error;
}
error = mStreamingBuffer->storeVertexAttributes( error = mStreamingBuffer->storeVertexAttributes(
attrib, translated->currentValueType, firstVertexIndex, attrib, translated->currentValueType, firstVertexIndex,
...@@ -442,9 +441,6 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, ...@@ -442,9 +441,6 @@ gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
} }
} }
translated->storage = nullptr;
translated->serial = vertexBuffer->getSerial();
translated->stride = outputElementSize;
translated->offset = streamOffset; translated->offset = streamOffset;
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
......
...@@ -4185,6 +4185,42 @@ GLenum Renderer11::getVertexComponentType(gl::VertexFormatType vertexFormatType) ...@@ -4185,6 +4185,42 @@ GLenum Renderer11::getVertexComponentType(gl::VertexFormatType vertexFormatType)
return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).nativeFormat).componentType; return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).nativeFormat).componentType;
} }
gl::ErrorOrResult<unsigned int> Renderer11::getVertexSpaceRequired(
const gl::VertexAttribute &attrib,
GLsizei count,
GLsizei instances) const
{
if (!attrib.enabled)
{
return 16u;
}
unsigned int elementCount = 0;
if (instances == 0 || attrib.divisor == 0)
{
elementCount = count;
}
else
{
// Round up to divisor, if possible
elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
gl::VertexFormatType formatType = gl::GetVertexFormatType(attrib);
const D3D_FEATURE_LEVEL featureLevel = mRenderer11DeviceCaps.featureLevel;
const d3d11::VertexFormat &vertexFormatInfo =
d3d11::GetVertexFormatInfo(formatType, featureLevel);
const d3d11::DXGIFormatSize &dxgiFormatInfo =
d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat);
unsigned int elementSize = dxgiFormatInfo.pixelBytes;
if (elementSize > std::numeric_limits<unsigned int>::max() / elementCount)
{
return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
}
return elementSize * elementCount;
}
void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps,
gl::Extensions *outExtensions, gl::Limitations *outLimitations) const gl::Extensions *outExtensions, gl::Limitations *outLimitations) const
{ {
......
...@@ -266,6 +266,9 @@ class Renderer11 : public RendererD3D ...@@ -266,6 +266,9 @@ class Renderer11 : public RendererD3D
bool getLUID(LUID *adapterLuid) const override; bool getLUID(LUID *adapterLuid) const override;
VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override;
GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override;
gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(const gl::VertexAttribute &attrib,
GLsizei count,
GLsizei instances) const override;
gl::Error readFromAttachment(const gl::FramebufferAttachment &srcAttachment, gl::Error readFromAttachment(const gl::FramebufferAttachment &srcAttachment,
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
......
...@@ -144,52 +144,6 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri ...@@ -144,52 +144,6 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
GLsizei instances, unsigned int *outSpaceRequired) const
{
unsigned int elementCount = 0;
if (attrib.enabled)
{
if (instances == 0 || attrib.divisor == 0)
{
elementCount = count;
}
else
{
// Round up to divisor, if possible
elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
gl::VertexFormatType formatType = gl::GetVertexFormatType(attrib);
const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(formatType, featureLevel);
const d3d11::DXGIFormatSize &dxgiFormatInfo =
d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat);
unsigned int elementSize = dxgiFormatInfo.pixelBytes;
if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
{
if (outSpaceRequired)
{
*outSpaceRequired = elementSize * elementCount;
}
return gl::Error(GL_NO_ERROR);
}
else
{
return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
}
}
else
{
const unsigned int elementSize = 4;
if (outSpaceRequired)
{
*outSpaceRequired = elementSize * 4;
}
return gl::Error(GL_NO_ERROR);
}
}
unsigned int VertexBuffer11::getBufferSize() const unsigned int VertexBuffer11::getBufferSize() const
{ {
return mBufferSize; return mBufferSize;
...@@ -233,4 +187,4 @@ ID3D11Buffer *VertexBuffer11::getBuffer() const ...@@ -233,4 +187,4 @@ ID3D11Buffer *VertexBuffer11::getBuffer() const
return mBuffer; return mBuffer;
} }
} } // namespace rx
...@@ -21,9 +21,9 @@ class VertexBuffer11 : public VertexBuffer ...@@ -21,9 +21,9 @@ class VertexBuffer11 : public VertexBuffer
{ {
public: public:
explicit VertexBuffer11(Renderer11 *const renderer); explicit VertexBuffer11(Renderer11 *const renderer);
virtual ~VertexBuffer11(); ~VertexBuffer11() override;
virtual gl::Error initialize(unsigned int size, bool dynamicUsage); gl::Error initialize(unsigned int size, bool dynamicUsage) override;
gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
GLenum currentValueType, GLenum currentValueType,
...@@ -33,14 +33,11 @@ class VertexBuffer11 : public VertexBuffer ...@@ -33,14 +33,11 @@ class VertexBuffer11 : public VertexBuffer
unsigned int offset, unsigned int offset,
const uint8_t *sourceData) override; const uint8_t *sourceData) override;
virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int getBufferSize() const override;
unsigned int *outSpaceRequired) const; gl::Error setBufferSize(unsigned int size) override;
gl::Error discard() override;
virtual unsigned int getBufferSize() const; void hintUnmapResource() override;
virtual gl::Error setBufferSize(unsigned int size);
virtual gl::Error discard();
virtual void hintUnmapResource();
ID3D11Buffer *getBuffer() const; ID3D11Buffer *getBuffer() const;
...@@ -56,6 +53,6 @@ class VertexBuffer11 : public VertexBuffer ...@@ -56,6 +53,6 @@ class VertexBuffer11 : public VertexBuffer
uint8_t *mMappedResourceData; uint8_t *mMappedResourceData;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
...@@ -2752,6 +2752,38 @@ GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) ...@@ -2752,6 +2752,38 @@ GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType)
return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType; return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType;
} }
gl::ErrorOrResult<unsigned int> Renderer9::getVertexSpaceRequired(const gl::VertexAttribute &attrib,
GLsizei count,
GLsizei instances) const
{
gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT);
const d3d9::VertexFormat &d3d9VertexInfo =
d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType);
if (!attrib.enabled)
{
return 16u;
}
unsigned int elementCount = 0;
if (instances == 0 || attrib.divisor == 0)
{
elementCount = static_cast<unsigned int>(count);
}
else
{
// Round up to divisor, if possible
elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
if (d3d9VertexInfo.outputElementSize > std::numeric_limits<unsigned int>::max() / elementCount)
{
return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
}
return static_cast<unsigned int>(d3d9VertexInfo.outputElementSize) * elementCount;
}
void Renderer9::generateCaps(gl::Caps *outCaps, void Renderer9::generateCaps(gl::Caps *outCaps,
gl::TextureCapsMap *outTextureCaps, gl::TextureCapsMap *outTextureCaps,
gl::Extensions *outExtensions, gl::Extensions *outExtensions,
......
...@@ -252,6 +252,9 @@ class Renderer9 : public RendererD3D ...@@ -252,6 +252,9 @@ class Renderer9 : public RendererD3D
bool getLUID(LUID *adapterLuid) const override; bool getLUID(LUID *adapterLuid) const override;
VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override;
GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override;
gl::ErrorOrResult<unsigned int> getVertexSpaceRequired(const gl::VertexAttribute &attrib,
GLsizei count,
GLsizei instances) const override;
gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
......
...@@ -74,15 +74,16 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib ...@@ -74,15 +74,16 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib
DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
uint8_t *mapPtr = NULL; uint8_t *mapPtr = nullptr;
unsigned int mapSize; auto errorOrMapSize = mRenderer->getVertexSpaceRequired(attrib, count, instances);
gl::Error error = spaceRequired(attrib, count, instances, &mapSize); if (errorOrMapSize.isError())
if (error.isError())
{ {
return error; return errorOrMapSize.getError();
} }
unsigned int mapSize = errorOrMapSize.getResult();
HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void**>(&mapPtr), lockFlags); HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void**>(&mapPtr), lockFlags);
if (FAILED(result)) if (FAILED(result))
{ {
...@@ -115,12 +116,6 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib ...@@ -115,12 +116,6 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances,
unsigned int *outSpaceRequired) const
{
return spaceRequired(attrib, count, instances, outSpaceRequired);
}
unsigned int VertexBuffer9::getBufferSize() const unsigned int VertexBuffer9::getBufferSize() const
{ {
return mBufferSize; return mBufferSize;
...@@ -167,49 +162,4 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const ...@@ -167,49 +162,4 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
{ {
return mVertexBuffer; return mVertexBuffer;
} }
} // namespace rx
gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
unsigned int *outSpaceRequired) const
{
gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT);
const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType);
if (attrib.enabled)
{
unsigned int elementCount = 0;
if (instances == 0 || attrib.divisor == 0)
{
elementCount = static_cast<unsigned int>(count);
}
else
{
// Round up to divisor, if possible
elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), attrib.divisor);
}
if (d3d9VertexInfo.outputElementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
{
if (outSpaceRequired)
{
*outSpaceRequired =
static_cast<unsigned int>(d3d9VertexInfo.outputElementSize) * elementCount;
}
return gl::Error(GL_NO_ERROR);
}
else
{
return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow.");
}
}
else
{
const unsigned int elementSize = 4;
if (outSpaceRequired)
{
*outSpaceRequired = elementSize * 4;
}
return gl::Error(GL_NO_ERROR);
}
}
}
...@@ -19,9 +19,9 @@ class VertexBuffer9 : public VertexBuffer ...@@ -19,9 +19,9 @@ class VertexBuffer9 : public VertexBuffer
{ {
public: public:
explicit VertexBuffer9(Renderer9 *renderer); explicit VertexBuffer9(Renderer9 *renderer);
virtual ~VertexBuffer9(); ~VertexBuffer9() override;
virtual gl::Error initialize(unsigned int size, bool dynamicUsage); gl::Error initialize(unsigned int size, bool dynamicUsage) override;
gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib,
GLenum currentValueType, GLenum currentValueType,
...@@ -31,11 +31,9 @@ class VertexBuffer9 : public VertexBuffer ...@@ -31,11 +31,9 @@ class VertexBuffer9 : public VertexBuffer
unsigned int offset, unsigned int offset,
const uint8_t *sourceData) override; const uint8_t *sourceData) override;
virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; unsigned int getBufferSize() const override;
gl::Error setBufferSize(unsigned int size) override;
virtual unsigned int getBufferSize() const; gl::Error discard() override;
virtual gl::Error setBufferSize(unsigned int size);
virtual gl::Error discard();
IDirect3DVertexBuffer9 *getBuffer() const; IDirect3DVertexBuffer9 *getBuffer() const;
...@@ -45,9 +43,6 @@ class VertexBuffer9 : public VertexBuffer ...@@ -45,9 +43,6 @@ class VertexBuffer9 : public VertexBuffer
IDirect3DVertexBuffer9 *mVertexBuffer; IDirect3DVertexBuffer9 *mVertexBuffer;
unsigned int mBufferSize; unsigned int mBufferSize;
bool mDynamicUsage; bool mDynamicUsage;
gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances,
unsigned int *outSpaceRequired) const;
}; };
} }
......
...@@ -56,6 +56,10 @@ class MockBufferFactoryD3D : public rx::BufferFactoryD3D ...@@ -56,6 +56,10 @@ class MockBufferFactoryD3D : public rx::BufferFactoryD3D
MOCK_METHOD0(createVertexBuffer, rx::VertexBuffer*()); MOCK_METHOD0(createVertexBuffer, rx::VertexBuffer*());
MOCK_CONST_METHOD1(getVertexConversionType, rx::VertexConversionType(gl::VertexFormatType)); MOCK_CONST_METHOD1(getVertexConversionType, rx::VertexConversionType(gl::VertexFormatType));
MOCK_CONST_METHOD1(getVertexComponentType, GLenum(gl::VertexFormatType)); MOCK_CONST_METHOD1(getVertexComponentType, GLenum(gl::VertexFormatType));
MOCK_CONST_METHOD3(getVertexSpaceRequired,
gl::ErrorOrResult<unsigned int>(const gl::VertexAttribute &,
GLsizei,
GLsizei));
// Dependency injection // Dependency injection
rx::IndexBuffer* createIndexBuffer() override rx::IndexBuffer* createIndexBuffer() override
......
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