Commit efb45eda by Brandon Schade Committed by Commit Bot

Vulkan: Accelerate Texture PBO updates

If the format of the image and the PBO match, use a vkCmdCopyBufferToImage transfer operation. Test: angle_end2end_tests --gtest_filter=*PBOCompressedSubImage* angle_end2end_tests --gtest_filter=*PBOWithMultipleDraws* dEQP-GLES3.functional.texture.specification.tex*image*d_pbo* Bug: angleproject:3777 Change-Id: I3f271024a635be113202a16f8893a199c194172d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1906203Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
parent f9c3eaf4
...@@ -150,7 +150,8 @@ angle::Result TextureVk::setSubImage(const gl::Context *context, ...@@ -150,7 +150,8 @@ angle::Result TextureVk::setSubImage(const gl::Context *context,
const vk::Format &vkFormat = const vk::Format &vkFormat =
contextVk->getRenderer()->getFormat(levelDesc.format.info->sizedInternalFormat); contextVk->getRenderer()->getFormat(levelDesc.format.info->sizedInternalFormat);
return setSubImageImpl(context, index, area, formatInfo, type, unpack, pixels, vkFormat); return setSubImageImpl(context, index, area, formatInfo, type, unpack, unpackBuffer, pixels,
vkFormat);
} }
angle::Result TextureVk::setCompressedImage(const gl::Context *context, angle::Result TextureVk::setCompressedImage(const gl::Context *context,
...@@ -180,9 +181,11 @@ angle::Result TextureVk::setCompressedSubImage(const gl::Context *context, ...@@ -180,9 +181,11 @@ angle::Result TextureVk::setCompressedSubImage(const gl::Context *context,
const gl::ImageDesc &levelDesc = mState.getImageDesc(index); const gl::ImageDesc &levelDesc = mState.getImageDesc(index);
const vk::Format &vkFormat = const vk::Format &vkFormat =
contextVk->getRenderer()->getFormat(levelDesc.format.info->sizedInternalFormat); contextVk->getRenderer()->getFormat(levelDesc.format.info->sizedInternalFormat);
const gl::State &glState = contextVk->getState();
gl::Buffer *unpackBuffer = glState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
return setSubImageImpl(context, index, area, formatInfo, GL_UNSIGNED_BYTE, unpack, pixels, return setSubImageImpl(context, index, area, formatInfo, GL_UNSIGNED_BYTE, unpack, unpackBuffer,
vkFormat); pixels, vkFormat);
} }
angle::Result TextureVk::setImageImpl(const gl::Context *context, angle::Result TextureVk::setImageImpl(const gl::Context *context,
...@@ -205,9 +208,11 @@ angle::Result TextureVk::setImageImpl(const gl::Context *context, ...@@ -205,9 +208,11 @@ angle::Result TextureVk::setImageImpl(const gl::Context *context,
{ {
return angle::Result::Continue; return angle::Result::Continue;
} }
const gl::State &glState = contextVk->getState();
gl::Buffer *unpackBuffer = glState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
return setSubImageImpl(context, index, gl::Box(0, 0, 0, size.width, size.height, size.depth), return setSubImageImpl(context, index, gl::Box(0, 0, 0, size.width, size.height, size.depth),
formatInfo, type, unpack, pixels, vkFormat); formatInfo, type, unpack, unpackBuffer, pixels, vkFormat);
} }
angle::Result TextureVk::setSubImageImpl(const gl::Context *context, angle::Result TextureVk::setSubImageImpl(const gl::Context *context,
...@@ -216,29 +221,65 @@ angle::Result TextureVk::setSubImageImpl(const gl::Context *context, ...@@ -216,29 +221,65 @@ angle::Result TextureVk::setSubImageImpl(const gl::Context *context,
const gl::InternalFormat &formatInfo, const gl::InternalFormat &formatInfo,
GLenum type, GLenum type,
const gl::PixelUnpackState &unpack, const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels, const uint8_t *pixels,
const vk::Format &vkFormat) const vk::Format &vkFormat)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
const gl::State &glState = contextVk->getState();
gl::Buffer *unpackBuffer = glState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
if (unpackBuffer) if (unpackBuffer)
{ {
BufferVk *unpackBufferVk = vk::GetImpl(unpackBuffer); BufferVk *unpackBufferVk = vk::GetImpl(unpackBuffer);
vk::BufferHelper &bufferHelper = unpackBufferVk->getBuffer();
uintptr_t offset = reinterpret_cast<uintptr_t>(pixels);
GLuint inputRowPitch = 0;
GLuint inputDepthPitch = 0;
GLuint inputSkipBytes = 0;
ANGLE_TRY(mImage->CalculateBufferInfo(
contextVk, gl::Extents(area.width, area.height, area.depth), formatInfo, unpack, type,
index.usesTex3D(), &inputRowPitch, &inputDepthPitch, &inputSkipBytes));
size_t offsetBytes = static_cast<size_t>(offset + inputSkipBytes);
if (isFastUnpackPossible(vkFormat, offsetBytes))
{
GLuint pixelSize = formatInfo.pixelBytes;
GLuint blockWidth = formatInfo.compressedBlockWidth;
GLuint blockHeight = formatInfo.compressedBlockHeight;
if (!formatInfo.compressed)
{
pixelSize = formatInfo.computePixelBytes(type);
blockWidth = 1;
blockHeight = 1;
}
ASSERT(pixelSize != 0 && inputRowPitch != 0 && blockWidth != 0 && blockHeight != 0);
GLuint rowLengthPixels = inputRowPitch / pixelSize * blockWidth;
GLuint imageHeightPixels = inputDepthPitch / inputRowPitch * blockHeight;
ANGLE_TRY(copyBufferDataToImage(contextVk, &bufferHelper, index, rowLengthPixels,
imageHeightPixels, area, offsetBytes));
}
else
{
void *mapPtr = nullptr; void *mapPtr = nullptr;
ANGLE_TRY(unpackBufferVk->mapImpl(contextVk, &mapPtr)); ANGLE_TRY(unpackBufferVk->mapImpl(contextVk, &mapPtr));
const uint8_t *source = const uint8_t *source =
static_cast<const uint8_t *>(mapPtr) + reinterpret_cast<ptrdiff_t>(pixels); static_cast<const uint8_t *>(mapPtr) + reinterpret_cast<ptrdiff_t>(pixels);
ANGLE_TRY(mImage->stageSubresourceUpdate( ANGLE_TRY(mImage->stageSubresourceUpdateImpl(
contextVk, getNativeImageIndex(index), gl::Extents(area.width, area.height, area.depth), contextVk, getNativeImageIndex(index),
gl::Offset(area.x, area.y, area.z), formatInfo, unpack, type, source, vkFormat)); gl::Extents(area.width, area.height, area.depth),
gl::Offset(area.x, area.y, area.z), formatInfo, unpack, type, source, vkFormat,
inputRowPitch, inputDepthPitch, inputSkipBytes));
unpackBufferVk->unmapImpl(contextVk); unpackBufferVk->unmapImpl(contextVk);
onStagingBufferChange(); onStagingBufferChange();
} }
}
else if (pixels) else if (pixels)
{ {
ANGLE_TRY(mImage->stageSubresourceUpdate( ANGLE_TRY(mImage->stageSubresourceUpdate(
...@@ -983,6 +1024,62 @@ angle::Result TextureVk::copyImageDataToBufferAndGetData(ContextVk *contextVk, ...@@ -983,6 +1024,62 @@ angle::Result TextureVk::copyImageDataToBufferAndGetData(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result TextureVk::copyBufferDataToImage(ContextVk *contextVk,
vk::BufferHelper *srcBuffer,
const gl::ImageIndex index,
uint32_t rowLength,
uint32_t imageHeight,
const gl::Box &sourceArea,
size_t offset)
{
ANGLE_TRACE_EVENT0("gpu.angle", "TextureVk::copyBufferDataToImage");
// Vulkan Spec requires the bufferOffset to be a multiple of 4 for vkCmdCopyBufferToImage.
ASSERT((offset & (kBufferOffsetMultiple - 1)) == 0);
GLuint layerCount = 0;
GLuint layerIndex = 0;
GetRenderTargetLayerCountAndIndex(mImage, index, &layerCount, &layerIndex);
// Make sure the source is initialized and its images are flushed.
ANGLE_TRY(ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels));
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst, commandBuffer);
// Source's layout change should happen before the copy
// Also updates the serial of the srcBuffer
srcBuffer->addReadDependency(contextVk, mImage);
VkBufferImageCopy region = {};
region.bufferOffset = offset;
region.bufferRowLength = rowLength;
region.bufferImageHeight = imageHeight;
region.imageExtent.width = sourceArea.width;
region.imageExtent.height = sourceArea.height;
region.imageExtent.depth = sourceArea.depth;
region.imageOffset.x = sourceArea.x;
region.imageOffset.y = sourceArea.y;
region.imageOffset.z = sourceArea.z;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.baseArrayLayer = layerIndex;
region.imageSubresource.layerCount = 1;
region.imageSubresource.mipLevel = static_cast<uint32_t>(index.getLevelIndex());
if (index.getType() == gl::TextureType::_2DArray)
{
region.imageExtent.depth = 1;
region.imageSubresource.layerCount = sourceArea.depth;
}
commandBuffer->copyBufferToImage(srcBuffer->getBuffer().getHandle(), mImage->getImage(),
mImage->getCurrentLayout(), 1, &region);
return angle::Result::Continue;
}
angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context) angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context)
{ {
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
......
...@@ -27,6 +27,9 @@ enum class ImageMipLevels ...@@ -27,6 +27,9 @@ enum class ImageMipLevels
InvalidEnum = 2, InvalidEnum = 2,
}; };
// vkCmdCopyBufferToImage buffer offset multiple
constexpr VkDeviceSize kBufferOffsetMultiple = 4;
class TextureVk : public TextureImpl class TextureVk : public TextureImpl
{ {
public: public:
...@@ -148,6 +151,22 @@ class TextureVk : public TextureImpl ...@@ -148,6 +151,22 @@ class TextureVk : public TextureImpl
angle::Result initializeContents(const gl::Context *context, angle::Result initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override; const gl::ImageIndex &imageIndex) override;
ANGLE_INLINE bool isFastUnpackPossible(const vk::Format &vkFormat, size_t offset)
{
// Conditions to determine if fast unpacking is possible
// 1. Image must be well defined to unpack directly to it
// TODO(http://anglebug.com/3777) Create and stage a temp image instead
// 2. Can't perform a fast copy for emulated formats
// 3. vkCmdCopyBufferToImage requires byte offset to be a multiple of 4
if (mImage->valid() && (vkFormat.intendedFormatID == vkFormat.actualImageFormatID) &&
((offset & (kBufferOffsetMultiple - 1)) == 0))
{
return true;
}
return false;
}
const vk::ImageHelper &getImage() const const vk::ImageHelper &getImage() const
{ {
ASSERT(mImage && mImage->valid()); ASSERT(mImage && mImage->valid());
...@@ -247,6 +266,7 @@ class TextureVk : public TextureImpl ...@@ -247,6 +266,7 @@ class TextureVk : public TextureImpl
const gl::InternalFormat &formatInfo, const gl::InternalFormat &formatInfo,
GLenum type, GLenum type,
const gl::PixelUnpackState &unpack, const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels, const uint8_t *pixels,
const vk::Format &vkFormat); const vk::Format &vkFormat);
...@@ -256,6 +276,14 @@ class TextureVk : public TextureImpl ...@@ -256,6 +276,14 @@ class TextureVk : public TextureImpl
const gl::Rectangle &sourceArea, const gl::Rectangle &sourceArea,
uint8_t **outDataPtr); uint8_t **outDataPtr);
angle::Result copyBufferDataToImage(ContextVk *contextVk,
vk::BufferHelper *srcBuffer,
const gl::ImageIndex index,
uint32_t rowLength,
uint32_t imageHeight,
const gl::Box &sourceArea,
size_t offset);
angle::Result generateMipmapsWithCPU(const gl::Context *context); angle::Result generateMipmapsWithCPU(const gl::Context *context);
angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk, angle::Result generateMipmapLevelsWithCPU(ContextVk *contextVk,
......
...@@ -2208,7 +2208,7 @@ void ImageHelper::removeStagedUpdates(ContextVk *contextVk, const gl::ImageIndex ...@@ -2208,7 +2208,7 @@ void ImageHelper::removeStagedUpdates(ContextVk *contextVk, const gl::ImageIndex
} }
} }
angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk, angle::Result ImageHelper::stageSubresourceUpdateImpl(ContextVk *contextVk,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const gl::Extents &glExtents, const gl::Extents &glExtents,
const gl::Offset &offset, const gl::Offset &offset,
...@@ -2216,23 +2216,11 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk, ...@@ -2216,23 +2216,11 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
const gl::PixelUnpackState &unpack, const gl::PixelUnpackState &unpack,
GLenum type, GLenum type,
const uint8_t *pixels, const uint8_t *pixels,
const Format &vkFormat) const Format &vkFormat,
const GLuint inputRowPitch,
const GLuint inputDepthPitch,
const GLuint inputSkipBytes)
{ {
GLuint inputRowPitch = 0;
ANGLE_VK_CHECK_MATH(contextVk,
formatInfo.computeRowPitch(type, glExtents.width, unpack.alignment,
unpack.rowLength, &inputRowPitch));
GLuint inputDepthPitch = 0;
ANGLE_VK_CHECK_MATH(
contextVk, formatInfo.computeDepthPitch(glExtents.height, unpack.imageHeight, inputRowPitch,
&inputDepthPitch));
GLuint inputSkipBytes = 0;
ANGLE_VK_CHECK_MATH(contextVk,
formatInfo.computeSkipBytes(type, inputRowPitch, inputDepthPitch, unpack,
index.usesTex3D(), &inputSkipBytes));
const angle::Format &storageFormat = vkFormat.actualImageFormat(); const angle::Format &storageFormat = vkFormat.actualImageFormat();
size_t outputRowPitch; size_t outputRowPitch;
...@@ -2429,6 +2417,54 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk, ...@@ -2429,6 +2417,54 @@ angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result ImageHelper::CalculateBufferInfo(ContextVk *contextVk,
const gl::Extents &glExtents,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
bool is3D,
GLuint *inputRowPitch,
GLuint *inputDepthPitch,
GLuint *inputSkipBytes)
{
ANGLE_VK_CHECK_MATH(contextVk,
formatInfo.computeRowPitch(type, glExtents.width, unpack.alignment,
unpack.rowLength, inputRowPitch));
ANGLE_VK_CHECK_MATH(contextVk,
formatInfo.computeDepthPitch(glExtents.height, unpack.imageHeight,
*inputRowPitch, inputDepthPitch));
ANGLE_VK_CHECK_MATH(
contextVk, formatInfo.computeSkipBytes(type, *inputRowPitch, *inputDepthPitch, unpack, is3D,
inputSkipBytes));
return angle::Result::Continue;
}
angle::Result ImageHelper::stageSubresourceUpdate(ContextVk *contextVk,
const gl::ImageIndex &index,
const gl::Extents &glExtents,
const gl::Offset &offset,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels,
const Format &vkFormat)
{
GLuint inputRowPitch = 0;
GLuint inputDepthPitch = 0;
GLuint inputSkipBytes = 0;
ANGLE_TRY(CalculateBufferInfo(contextVk, glExtents, formatInfo, unpack, type, index.usesTex3D(),
&inputRowPitch, &inputDepthPitch, &inputSkipBytes));
ANGLE_TRY(stageSubresourceUpdateImpl(contextVk, index, glExtents, offset, formatInfo, unpack,
type, pixels, vkFormat, inputRowPitch, inputDepthPitch,
inputSkipBytes));
return angle::Result::Continue;
}
angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk, angle::Result ImageHelper::stageSubresourceUpdateAndGetData(ContextVk *contextVk,
size_t allocationSize, size_t allocationSize,
const gl::ImageIndex &imageIndex, const gl::ImageIndex &imageIndex,
......
...@@ -785,6 +785,19 @@ class ImageHelper final : public CommandGraphResource ...@@ -785,6 +785,19 @@ class ImageHelper final : public CommandGraphResource
// Data staging // Data staging
void removeStagedUpdates(ContextVk *contextVk, const gl::ImageIndex &index); void removeStagedUpdates(ContextVk *contextVk, const gl::ImageIndex &index);
angle::Result stageSubresourceUpdateImpl(ContextVk *contextVk,
const gl::ImageIndex &index,
const gl::Extents &glExtents,
const gl::Offset &offset,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
const uint8_t *pixels,
const Format &vkFormat,
const GLuint inputRowPitch,
const GLuint inputDepthPitch,
const GLuint inputSkipBytes);
angle::Result stageSubresourceUpdate(ContextVk *contextVk, angle::Result stageSubresourceUpdate(ContextVk *contextVk,
const gl::ImageIndex &index, const gl::ImageIndex &index,
const gl::Extents &glExtents, const gl::Extents &glExtents,
...@@ -924,6 +937,16 @@ class ImageHelper final : public CommandGraphResource ...@@ -924,6 +937,16 @@ class ImageHelper final : public CommandGraphResource
void *pixels, void *pixels,
DynamicBuffer *stagingBuffer); DynamicBuffer *stagingBuffer);
angle::Result CalculateBufferInfo(ContextVk *contextVk,
const gl::Extents &glExtents,
const gl::InternalFormat &formatInfo,
const gl::PixelUnpackState &unpack,
GLenum type,
bool is3D,
GLuint *inputRowPitch,
GLuint *inputDepthPitch,
GLuint *inputSkipBytes);
private: private:
void forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask, void forceChangeLayoutAndQueue(VkImageAspectFlags aspectMask,
ImageLayout newLayout, ImageLayout newLayout,
......
...@@ -109,6 +109,69 @@ class TextureUploadFullMipBenchmark : public TextureUploadBenchmarkBase ...@@ -109,6 +109,69 @@ class TextureUploadFullMipBenchmark : public TextureUploadBenchmarkBase
void drawBenchmark() override; void drawBenchmark() override;
}; };
class PBOSubImageBenchmark : public TextureUploadBenchmarkBase
{
public:
PBOSubImageBenchmark() : TextureUploadBenchmarkBase("PBO") {}
void initializeBenchmark() override
{
TextureUploadBenchmarkBase::initializeBenchmark();
const auto &params = GetParam();
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, params.baseSize, params.baseSize);
glGenBuffers(1, &mPBO);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
glBufferData(GL_PIXEL_UNPACK_BUFFER, params.baseSize * params.baseSize * 4,
mTextureData.data(), GL_STREAM_DRAW);
}
void destroyBenchmark()
{
TextureUploadBenchmarkBase::destroyBenchmark();
glDeleteBuffers(1, &mPBO);
}
void drawBenchmark() override;
private:
GLuint mPBO;
};
class PBOCompressedSubImageBenchmark : public TextureUploadBenchmarkBase
{
public:
PBOCompressedSubImageBenchmark() : TextureUploadBenchmarkBase("PBOCompressed") {}
void initializeBenchmark() override
{
TextureUploadBenchmarkBase::initializeBenchmark();
const auto &params = GetParam();
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB8_ETC2, params.baseSize,
params.baseSize);
glGenBuffers(1, &mPBO);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
glBufferData(GL_PIXEL_UNPACK_BUFFER, params.subImageSize * params.subImageSize / 2,
mTextureData.data(), GL_STREAM_DRAW);
}
void destroyBenchmark()
{
TextureUploadBenchmarkBase::destroyBenchmark();
glDeleteBuffers(1, &mPBO);
}
void drawBenchmark() override;
private:
GLuint mPBO;
};
TextureUploadBenchmarkBase::TextureUploadBenchmarkBase(const char *benchmarkName) TextureUploadBenchmarkBase::TextureUploadBenchmarkBase(const char *benchmarkName)
: ANGLERenderTest(benchmarkName, GetParam()) : ANGLERenderTest(benchmarkName, GetParam())
{ {
...@@ -228,6 +291,46 @@ void TextureUploadFullMipBenchmark::drawBenchmark() ...@@ -228,6 +291,46 @@ void TextureUploadFullMipBenchmark::drawBenchmark()
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
void PBOSubImageBenchmark::drawBenchmark()
{
const auto &params = GetParam();
startGpuTimer();
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
{
glTexSubImage2D(GL_TEXTURE_2D, 0, rand() % (params.baseSize - params.subImageSize),
rand() % (params.baseSize - params.subImageSize), params.subImageSize,
params.subImageSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// Perform a draw just so the texture data is flushed. With the position attributes not
// set, a constant default value is used, resulting in a very cheap draw.
glDrawArrays(GL_TRIANGLES, 0, 3);
}
stopGpuTimer();
ASSERT_GL_NO_ERROR();
}
void PBOCompressedSubImageBenchmark::drawBenchmark()
{
const auto &params = GetParam();
startGpuTimer();
for (unsigned int iteration = 0; iteration < params.iterationsPerStep; ++iteration)
{
glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, params.subImageSize, params.subImageSize,
GL_COMPRESSED_RGB8_ETC2,
params.subImageSize * params.subImageSize / 2, 0);
// Perform a draw just so the texture data is flushed. With the position attributes not
// set, a constant default value is used, resulting in a very cheap draw.
glDrawArrays(GL_TRIANGLES, 0, 3);
}
stopGpuTimer();
ASSERT_GL_NO_ERROR();
}
TextureUploadParams D3D11Params(bool webglCompat) TextureUploadParams D3D11Params(bool webglCompat)
{ {
TextureUploadParams params; TextureUploadParams params;
...@@ -252,6 +355,30 @@ TextureUploadParams VulkanParams(bool webglCompat) ...@@ -252,6 +355,30 @@ TextureUploadParams VulkanParams(bool webglCompat)
return params; return params;
} }
TextureUploadParams VulkanPBOParams(GLsizei baseSize, GLsizei subImageSize)
{
TextureUploadParams params;
params.eglParameters = egl_platform::VULKAN();
params.webgl = false;
params.trackGpuTime = false;
params.baseSize = baseSize;
params.subImageSize = subImageSize;
return params;
}
TextureUploadParams ES3OpenGLPBOParams(GLsizei baseSize, GLsizei subImageSize)
{
TextureUploadParams params;
params.eglParameters = egl_platform::OPENGL();
params.majorVersion = 3;
params.minorVersion = 0;
params.webgl = false;
params.trackGpuTime = false;
params.baseSize = baseSize;
params.subImageSize = subImageSize;
return params;
}
} // anonymous namespace } // anonymous namespace
TEST_P(TextureUploadSubImageBenchmark, Run) TEST_P(TextureUploadSubImageBenchmark, Run)
...@@ -264,6 +391,16 @@ TEST_P(TextureUploadFullMipBenchmark, Run) ...@@ -264,6 +391,16 @@ TEST_P(TextureUploadFullMipBenchmark, Run)
run(); run();
} }
TEST_P(PBOSubImageBenchmark, Run)
{
run();
}
TEST_P(PBOCompressedSubImageBenchmark, Run)
{
run();
}
using namespace params; using namespace params;
ANGLE_INSTANTIATE_TEST(TextureUploadSubImageBenchmark, ANGLE_INSTANTIATE_TEST(TextureUploadSubImageBenchmark,
...@@ -283,3 +420,11 @@ ANGLE_INSTANTIATE_TEST(TextureUploadFullMipBenchmark, ...@@ -283,3 +420,11 @@ ANGLE_INSTANTIATE_TEST(TextureUploadFullMipBenchmark,
VulkanParams(false), VulkanParams(false),
NullDevice(VulkanParams(false)), NullDevice(VulkanParams(false)),
VulkanParams(true)); VulkanParams(true));
ANGLE_INSTANTIATE_TEST(PBOSubImageBenchmark,
ES3OpenGLPBOParams(1024, 128),
VulkanPBOParams(1024, 128));
ANGLE_INSTANTIATE_TEST(PBOCompressedSubImageBenchmark,
ES3OpenGLPBOParams(128, 128),
VulkanPBOParams(128, 128));
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