Commit a63cc59f by Jamie Madill Committed by Commit Bot

Vulkan: Don't store vertex attrib format and stride.

We only use these values in vertex conversion. We can instead pass more info to the convertGPU/CPU functions. In client attribute streaming we can query the format table a second time. This is a bit slower. But the runtime of attribute streaming would usually be dominated by the conversion function time. So it shouldn't regress any real work perf. This saves on a bit of storage and memory overhead in the vertex sync functions in VertexArrayVk. Bug: angleproject:3014 Change-Id: I401eeff024664aa0efeea710503c0f619e6d4f22 Reviewed-on: https://chromium-review.googlesource.com/c/1406889 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent c3abb7f1
...@@ -100,8 +100,6 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s ...@@ -100,8 +100,6 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s
mCurrentArrayBufferHandles{}, mCurrentArrayBufferHandles{},
mCurrentArrayBufferOffsets{}, mCurrentArrayBufferOffsets{},
mCurrentArrayBuffers{}, mCurrentArrayBuffers{},
mCurrentArrayBufferFormats{},
mCurrentArrayBufferStrides{},
mCurrentArrayBufferConversion{{ mCurrentArrayBufferConversion{{
INIT, INIT,
INIT, INIT,
...@@ -210,12 +208,13 @@ angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk, ...@@ -210,12 +208,13 @@ angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk, angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex) size_t attribIndex,
const vk::Format &vertexFormat)
{ {
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
const angle::Format &srcFormat = mCurrentArrayBufferFormats[attribIndex]->angleFormat(); const angle::Format &srcFormat = vertexFormat.angleFormat();
const angle::Format &destFormat = mCurrentArrayBufferFormats[attribIndex]->bufferFormat(); const angle::Format &destFormat = vertexFormat.bufferFormat();
ASSERT(binding.getStride() % (srcFormat.pixelBytes / srcFormat.channelCount()) == 0); ASSERT(binding.getStride() % (srcFormat.pixelBytes / srcFormat.channelCount()) == 0);
...@@ -228,8 +227,7 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk, ...@@ -228,8 +227,7 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <= ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
kMaxVertexFormatAlignment);
// Allocate buffer for results // Allocate buffer for results
mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer); mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
...@@ -260,13 +258,14 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk, ...@@ -260,13 +258,14 @@ angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk, angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex) size_t attribIndex,
const vk::Format &vertexFormat)
{ {
// Needed before reading buffer or we could get stale data. // Needed before reading buffer or we could get stale data.
ANGLE_TRY(contextVk->getRenderer()->finish(contextVk)); ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes; unsigned srcFormatSize = vertexFormat.angleFormat().pixelBytes;
unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex]; unsigned dstFormatSize = vertexFormat.bufferFormat().pixelBytes;
mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer()); mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
...@@ -280,12 +279,10 @@ angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk, ...@@ -280,12 +279,10 @@ angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src)); ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src); const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
srcBytes += binding.getOffset(); srcBytes += binding.getOffset();
ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <= ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
kMaxVertexFormatAlignment);
ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes, ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
numVertices * dstFormatSize, 0, numVertices, binding.getStride(), numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction, vertexFormat.vertexLoadFunction, &mCurrentArrayBuffers[attribIndex],
&mCurrentArrayBuffers[attribIndex],
&mCurrentArrayBufferOffsets[attribIndex])); &mCurrentArrayBufferOffsets[attribIndex]));
ANGLE_TRY(srcBuffer->unmapImpl(contextVk)); ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
...@@ -394,17 +391,6 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context, ...@@ -394,17 +391,6 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
ANGLE_INLINE void VertexArrayVk::setPackedInputInfo(ContextVk *contextVk,
size_t attribIndex,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding)
{
ASSERT(attrib.enabled);
contextVk->onVertexAttributeChange(
attribIndex, mCurrentArrayBufferStrides[attribIndex], binding.getDivisor(),
mCurrentArrayBufferFormats[attribIndex]->vkBufferFormat, attrib.relativeOffset);
}
ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex) ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex)
{ {
contextVk->onVertexAttributeChange(attribIndex, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0); contextVk->onVertexAttributeChange(attribIndex, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0);
...@@ -420,32 +406,30 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -420,32 +406,30 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
if (attrib.enabled) if (attrib.enabled)
{ {
gl::Buffer *bufferGL = binding.getBuffer().get(); gl::Buffer *bufferGL = binding.getBuffer().get();
mCurrentArrayBufferFormats[attribIndex] = &renderer->getFormat(GetVertexFormatID(attrib)); const vk::Format &vertexFormat = renderer->getFormat(GetVertexFormatID(attrib));
GLuint stride;
if (bufferGL) if (bufferGL)
{ {
BufferVk *bufferVk = vk::GetImpl(bufferGL); BufferVk *bufferVk = vk::GetImpl(bufferGL);
const angle::Format &angleFormat = const angle::Format &angleFormat = vertexFormat.angleFormat();
mCurrentArrayBufferFormats[attribIndex]->angleFormat(); bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion || if (vertexFormat.vertexLoadRequiresConversion || !bindingIsAligned)
!bindingIsAligned)
{ {
mCurrentArrayBufferStrides[attribIndex] = stride = vertexFormat.bufferFormat().pixelBytes;
mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
if (bindingIsAligned) if (bindingIsAligned)
{ {
ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex)); ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex,
vertexFormat));
anyVertexBufferConvertedOnGpu = true; anyVertexBufferConvertedOnGpu = true;
} }
else else
{ {
// TODO(syoussefi): Implement unaligned vertex buffer conversions in compute. ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex,
// http://anglebug.com/3009 vertexFormat));
ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex));
} }
} }
else else
...@@ -456,7 +440,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -456,7 +440,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBufferHandles[attribIndex] = mCurrentArrayBufferHandles[attribIndex] =
mTheNullBuffer.getBuffer().getHandle(); mTheNullBuffer.getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = 0; mCurrentArrayBufferOffsets[attribIndex] = 0;
mCurrentArrayBufferStrides[attribIndex] = 0; stride = 0;
} }
else else
{ {
...@@ -464,7 +448,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -464,7 +448,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBufferHandles[attribIndex] = mCurrentArrayBufferHandles[attribIndex] =
bufferVk->getBuffer().getBuffer().getHandle(); bufferVk->getBuffer().getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset(); mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
mCurrentArrayBufferStrides[attribIndex] = binding.getStride(); stride = binding.getStride();
} }
ensureConversionReleased(renderer, attribIndex); ensureConversionReleased(renderer, attribIndex);
...@@ -475,12 +459,12 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -475,12 +459,12 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBuffers[attribIndex] = nullptr; mCurrentArrayBuffers[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle(); mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = 0; mCurrentArrayBufferOffsets[attribIndex] = 0;
mCurrentArrayBufferStrides[attribIndex] = stride = vertexFormat.bufferFormat().pixelBytes;
mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
ensureConversionReleased(renderer, attribIndex); ensureConversionReleased(renderer, attribIndex);
} }
setPackedInputInfo(contextVk, attribIndex, attrib, binding); contextVk->onVertexAttributeChange(attribIndex, stride, binding.getDivisor(),
vertexFormat.vkBufferFormat, attrib.relativeOffset);
} }
else else
{ {
...@@ -490,9 +474,6 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk, ...@@ -490,9 +474,6 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBuffers[attribIndex] = nullptr; mCurrentArrayBuffers[attribIndex] = nullptr;
mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle(); mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
mCurrentArrayBufferOffsets[attribIndex] = 0; mCurrentArrayBufferOffsets[attribIndex] = 0;
mCurrentArrayBufferStrides[attribIndex] = 0;
mCurrentArrayBufferFormats[attribIndex] =
&renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
setDefaultPackedInput(contextVk, attribIndex); setDefaultPackedInput(contextVk, attribIndex);
ensureConversionReleased(renderer, attribIndex); ensureConversionReleased(renderer, attribIndex);
...@@ -522,7 +503,8 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context, ...@@ -522,7 +503,8 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid, ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
indices, 0, &startVertex, &vertexCount)); indices, 0, &startVertex, &vertexCount));
mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer()); RendererVk *renderer = contextVk->getRenderer();
mDynamicVertexData.releaseRetainedBuffers(renderer);
const auto &attribs = mState.getVertexAttributes(); const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings(); const auto &bindings = mState.getVertexBindings();
...@@ -535,14 +517,15 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context, ...@@ -535,14 +517,15 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
const gl::VertexBinding &binding = bindings[attrib.bindingIndex]; const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr); ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
const size_t bytesToAllocate = const vk::Format &vertexFormat = renderer->getFormat(GetVertexFormatID(attrib));
(startVertex + vertexCount) * mCurrentArrayBufferStrides[attribIndex]; GLuint stride = vertexFormat.bufferFormat().pixelBytes;
const size_t bytesToAllocate = (startVertex + vertexCount) * stride;
const uint8_t *src = const uint8_t *src =
static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride(); static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
size_t destOffset = startVertex * mCurrentArrayBufferStrides[attribIndex]; size_t destOffset = startVertex * stride;
ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <= ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
kMaxVertexFormatAlignment);
// Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy. // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
// We allocate space for startVertex + vertexCount so indexing will work. If we // We allocate space for startVertex + vertexCount so indexing will work. If we
...@@ -551,7 +534,7 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context, ...@@ -551,7 +534,7 @@ angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
// offset, thus avoiding wasted memory. // offset, thus avoiding wasted memory.
ANGLE_TRY(StreamVertexData( ANGLE_TRY(StreamVertexData(
contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount, contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
binding.getStride(), mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction, binding.getStride(), vertexFormat.vertexLoadFunction,
&mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex])); &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
mCurrentArrayBufferHandles[attribIndex] = mCurrentArrayBufferHandles[attribIndex] =
mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle(); mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
...@@ -711,9 +694,6 @@ void VertexArrayVk::updateDefaultAttrib(ContextVk *contextVk, ...@@ -711,9 +694,6 @@ void VertexArrayVk::updateDefaultAttrib(ContextVk *contextVk,
mCurrentArrayBufferHandles[attribIndex] = bufferHandle; mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
mCurrentArrayBufferOffsets[attribIndex] = offset; mCurrentArrayBufferOffsets[attribIndex] = offset;
mCurrentArrayBuffers[attribIndex] = nullptr; mCurrentArrayBuffers[attribIndex] = nullptr;
mCurrentArrayBufferStrides[attribIndex] = 0;
mCurrentArrayBufferFormats[attribIndex] =
&contextVk->getRenderer()->getFormat(angle::FormatID::R32G32B32A32_FIXED);
setDefaultPackedInput(contextVk, attribIndex); setDefaultPackedInput(contextVk, attribIndex);
} }
......
...@@ -86,10 +86,6 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -86,10 +86,6 @@ class VertexArrayVk : public VertexArrayImpl
const void *indices); const void *indices);
private: private:
void setPackedInputInfo(ContextVk *contextVk,
size_t attribIndex,
const gl::VertexAttribute &attrib,
const gl::VertexBinding &binding);
void setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex); void setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex);
angle::Result streamIndexData(ContextVk *contextVk, angle::Result streamIndexData(ContextVk *contextVk,
...@@ -100,11 +96,13 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -100,11 +96,13 @@ class VertexArrayVk : public VertexArrayImpl
angle::Result convertVertexBufferGpu(ContextVk *contextVk, angle::Result convertVertexBufferGpu(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex); size_t attribIndex,
const vk::Format &vertexFormat);
angle::Result convertVertexBufferCpu(ContextVk *contextVk, angle::Result convertVertexBufferCpu(ContextVk *contextVk,
BufferVk *srcBuffer, BufferVk *srcBuffer,
const gl::VertexBinding &binding, const gl::VertexBinding &binding,
size_t attribIndex); size_t attribIndex,
const vk::Format &vertexFormat);
void ensureConversionReleased(RendererVk *renderer, size_t attribIndex); void ensureConversionReleased(RendererVk *renderer, size_t attribIndex);
angle::Result syncDirtyAttrib(ContextVk *contextVk, angle::Result syncDirtyAttrib(ContextVk *contextVk,
...@@ -115,8 +113,6 @@ class VertexArrayVk : public VertexArrayImpl ...@@ -115,8 +113,6 @@ class VertexArrayVk : public VertexArrayImpl
gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles; gl::AttribArray<VkBuffer> mCurrentArrayBufferHandles;
gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets; gl::AttribArray<VkDeviceSize> mCurrentArrayBufferOffsets;
gl::AttribArray<vk::BufferHelper *> mCurrentArrayBuffers; gl::AttribArray<vk::BufferHelper *> mCurrentArrayBuffers;
gl::AttribArray<const vk::Format *> mCurrentArrayBufferFormats;
gl::AttribArray<GLuint> mCurrentArrayBufferStrides;
gl::AttribArray<vk::DynamicBuffer> mCurrentArrayBufferConversion; gl::AttribArray<vk::DynamicBuffer> mCurrentArrayBufferConversion;
gl::AttribArray<bool> mCurrentArrayBufferConversionCanRelease; gl::AttribArray<bool> mCurrentArrayBufferConversionCanRelease;
VkDeviceSize mCurrentElementArrayBufferOffset; VkDeviceSize mCurrentElementArrayBufferOffset;
......
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