Add testing-only backend render target support to GrVkGpu.

Update unit tests to use backend render targets on non-GL contexts

Add named DM configs for rendering to Vulkan backend render targets and textures.

Make src data ptr param to createTestingOnlyBackendTexture be const.

Change-Id: I17f5375ed9bb08422006698956469d3151c4954c
Reviewed-on: https://skia-review.googlesource.com/113276
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2018-03-13 09:32:39 -04:00 committed by Skia Commit-Bot
parent 65247e595d
commit 52e943a469
12 changed files with 173 additions and 105 deletions

View File

@ -452,14 +452,13 @@ public:
/** Creates a texture directly in the backend API without wrapping it in a GrTexture. This is /** Creates a texture directly in the backend API without wrapping it in a GrTexture. This is
only to be used for testing (particularly for testing the methods that import an externally only to be used for testing (particularly for testing the methods that import an externally
created texture into Skia. Must be matched with a call to deleteTestingOnlyTexture(). */ created texture into Skia. Must be matched with a call to deleteTestingOnlyTexture(). */
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, SkColorType, GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h, SkColorType,
bool isRenderTarget, GrMipMapped); bool isRenderTarget, GrMipMapped);
/** Older version based on GrPixelConfig. Currently the preferred one above devolves to this. */ /** Older version based on GrPixelConfig. Currently the preferred one above devolves to this. */
virtual GrBackendTexture createTestingOnlyBackendTexture( virtual GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
void* pixels, int w, int h, GrPixelConfig config,
GrPixelConfig config, bool isRenderTarget,
bool isRenderTarget, GrMipMapped mipMapped) = 0;
GrMipMapped mipMapped) = 0;
/** Check a handle represents an actual texture in the backend API that has not been freed. */ /** Check a handle represents an actual texture in the backend API that has not been freed. */
virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0; virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0;
/** /**

View File

@ -4345,7 +4345,7 @@ void GrGLGpu::xferBarrier(GrRenderTarget* rt, GrXferBarrierType type) {
} }
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(const void* pixels, int w, int h,
GrPixelConfig config, bool /*isRT*/, GrPixelConfig config, bool /*isRT*/,
GrMipMapped mipMapped) { GrMipMapped mipMapped) {
if (!this->caps()->isConfigTexturable(config)) { if (!this->caps()->isConfigTexturable(config)) {
@ -4395,7 +4395,7 @@ GrBackendTexture GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, i
if (!pixels) { if (!pixels) {
// Fill in the texture with all zeros so we don't have random garbage // Fill in the texture with all zeros so we don't have random garbage
pixels = defaultStorage.get(); pixels = defaultStorage.get();
memset(pixels, 0, baseLayerSize); memset(defaultStorage.get(), 0, baseLayerSize);
} }
int width = w; int width = w;

View File

@ -145,9 +145,8 @@ public:
int width, int width,
int height) override; int height) override;
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
GrPixelConfig config, GrPixelConfig config, bool isRenderTarget,
bool isRenderTarget,
GrMipMapped mipMapped) override; GrMipMapped mipMapped) override;
bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override; void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;

View File

@ -181,7 +181,7 @@ GrStencilAttachment* GrMockGpu::createStencilAttachmentForRenderTarget(const GrR
} }
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture GrMockGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, GrBackendTexture GrMockGpu::createTestingOnlyBackendTexture(const void* pixels, int w, int h,
GrPixelConfig config, bool isRT, GrPixelConfig config, bool isRT,
GrMipMapped mipMapped) { GrMipMapped mipMapped) {
GrMockTextureInfo info; GrMockTextureInfo info;

View File

@ -114,8 +114,9 @@ private:
void clearStencil(GrRenderTarget*, int clearValue) override {} void clearStencil(GrRenderTarget*, int clearValue) override {}
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrPixelConfig, GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
bool isRT, GrMipMapped) override; GrPixelConfig, bool isRT,
GrMipMapped) override;
bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override; void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;

View File

@ -138,7 +138,7 @@ private:
void clearStencil(GrRenderTarget* target, int clearValue) override {} void clearStencil(GrRenderTarget* target, int clearValue) override {}
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
GrPixelConfig config, bool isRT, GrPixelConfig config, bool isRT,
GrMipMapped) override { GrMipMapped) override {
return GrBackendTexture(); return GrBackendTexture();

View File

@ -1131,8 +1131,8 @@ GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc, size_t bufferOffset, bool copy_testing_data(GrVkGpu* gpu, const void* srcData, const GrVkAlloc& alloc,
size_t srcRowBytes, size_t dstRowBytes, int h) { size_t bufferOffset, size_t srcRowBytes, size_t dstRowBytes, int h) {
// For Noncoherent buffers we want to make sure the range that we map, both offset and size, // For Noncoherent buffers we want to make sure the range that we map, both offset and size,
// are aligned to the nonCoherentAtomSize limit. We may have to move the initial offset back to // are aligned to the nonCoherentAtomSize limit. We may have to move the initial offset back to
// meet the alignment requirements. So we track how far we move back and then adjust the mapped // meet the alignment requirements. So we track how far we move back and then adjust the mapped
@ -1184,33 +1184,39 @@ bool copy_testing_data(GrVkGpu* gpu, void* srcData, const GrVkAlloc& alloc, size
} }
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w, int h, bool GrVkGpu::createTestingOnlyVkImage(GrPixelConfig config, int w, int h, bool texturable,
GrPixelConfig config, bool renderable, GrMipMapped mipMapped, const void* srcData,
bool isRenderTarget, GrVkImageInfo* info) {
GrMipMapped mipMapped) { SkASSERT(texturable || renderable);
if (!texturable) {
SkASSERT(GrMipMapped::kNo == mipMapped);
SkASSERT(!srcData);
}
VkFormat pixelFormat; VkFormat pixelFormat;
if (!GrPixelConfigToVkFormat(config, &pixelFormat)) { if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
return GrBackendTexture(); // invalid return false;
} }
if (!fVkCaps->isConfigTexturable(config)) { if (texturable && !fVkCaps->isConfigTexturable(config)) {
return GrBackendTexture(); // invalid return false;
} }
if (isRenderTarget && !fVkCaps->isConfigRenderable(config)) { if (renderable && !fVkCaps->isConfigRenderable(config)) {
return GrBackendTexture(); // invalid return false;
} }
// Currently we don't support uploading pixel data when mipped. // Currently we don't support uploading pixel data when mipped.
if (srcData && GrMipMapped::kYes == mipMapped) { if (srcData && GrMipMapped::kYes == mipMapped) {
return GrBackendTexture(); // invalid return false;
} }
VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT; VkImageUsageFlags usageFlags = 0;
usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
if (isRenderTarget) { if (texturable) {
usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
}
if (renderable) {
usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
} }
@ -1221,7 +1227,7 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
// Create Image // Create Image
VkSampleCountFlagBits vkSamples; VkSampleCountFlagBits vkSamples;
if (!GrSampleCountToVkSampleCount(1, &vkSamples)) { if (!GrSampleCountToVkSampleCount(1, &vkSamples)) {
return GrBackendTexture(); // invalid return false;
} }
// Figure out the number of mip levels. // Figure out the number of mip levels.
@ -1248,11 +1254,12 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
initialLayout // initialLayout initialLayout // initialLayout
}; };
GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateImage(this->device(), &imageCreateInfo, nullptr, &image)); GR_VK_CALL_ERRCHECK(this->vkInterface(),
CreateImage(this->device(), &imageCreateInfo, nullptr, &image));
if (!GrVkMemory::AllocAndBindImageMemory(this, image, false, &alloc)) { if (!GrVkMemory::AllocAndBindImageMemory(this, image, false, &alloc)) {
VK_CALL(DestroyImage(this->device(), image, nullptr)); VK_CALL(DestroyImage(this->device(), image, nullptr));
return GrBackendTexture(); // invalid return false;
} }
// We need to declare these early so that we can delete them at the end outside of the if block. // We need to declare these early so that we can delete them at the end outside of the if block.
@ -1273,7 +1280,7 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
if (err) { if (err) {
GrVkMemory::FreeImageMemory(this, false, alloc); GrVkMemory::FreeImageMemory(this, false, alloc);
VK_CALL(DestroyImage(fDevice, image, nullptr)); VK_CALL(DestroyImage(fDevice, image, nullptr));
return GrBackendTexture(); // invalid return false;
} }
VkCommandBufferBeginInfo cmdBufferBeginInfo; VkCommandBufferBeginInfo cmdBufferBeginInfo;
@ -1328,7 +1335,7 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
VK_CALL(DestroyImage(fDevice, image, nullptr)); VK_CALL(DestroyImage(fDevice, image, nullptr));
VK_CALL(EndCommandBuffer(cmdBuffer)); VK_CALL(EndCommandBuffer(cmdBuffer));
VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
return GrBackendTexture(); // invalid return false;
} }
if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type, true, if (!GrVkMemory::AllocAndBindBufferMemory(this, buffer, GrVkBuffer::kCopyRead_Type, true,
@ -1338,7 +1345,7 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
VK_CALL(EndCommandBuffer(cmdBuffer)); VK_CALL(EndCommandBuffer(cmdBuffer));
VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
return GrBackendTexture(); // invalid return false;
} }
currentWidth = w; currentWidth = w;
@ -1355,7 +1362,7 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
VK_CALL(DestroyBuffer(fDevice, buffer, nullptr)); VK_CALL(DestroyBuffer(fDevice, buffer, nullptr));
VK_CALL(EndCommandBuffer(cmdBuffer)); VK_CALL(EndCommandBuffer(cmdBuffer));
VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
return GrBackendTexture(); // invalid return false;
} }
currentWidth = SkTMax(1, currentWidth / 2); currentWidth = SkTMax(1, currentWidth / 2);
currentHeight = SkTMax(1, currentHeight / 2); currentHeight = SkTMax(1, currentHeight / 2);
@ -1401,27 +1408,29 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, regions.count(), VK_CALL(CmdCopyBufferToImage(cmdBuffer, buffer, image, initialLayout, regions.count(),
regions.begin())); regions.begin()));
// Change Image layout to shader read since if we use this texture as a borrowed textures within if (texturable) {
// Ganesh we require that its layout be set to that // Change Image layout to shader read since if we use this texture as a borrowed textures
memset(&barrier, 0, sizeof(VkImageMemoryBarrier)); // within Ganesh we require that its layout be set to that
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
barrier.pNext = nullptr; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout); barrier.pNext = nullptr;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; barrier.srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(initialLayout);
barrier.oldLayout = initialLayout; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.oldLayout = initialLayout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0 , 1}; barrier.image = image;
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, mipLevels, 0, 1};
VK_CALL(CmdPipelineBarrier(cmdBuffer, initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
GrVkMemory::LayoutToPipelineStageFlags(initialLayout), VK_CALL(CmdPipelineBarrier(cmdBuffer,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, GrVkMemory::LayoutToPipelineStageFlags(initialLayout),
0, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
0, nullptr, 0,
0, nullptr, 0, nullptr,
1, &barrier)); 0, nullptr,
1, &barrier));
}
// End CommandBuffer // End CommandBuffer
err = VK_CALL(EndCommandBuffer(cmdBuffer)); err = VK_CALL(EndCommandBuffer(cmdBuffer));
@ -1471,15 +1480,24 @@ GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(void* srcData, int w,
VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer)); VK_CALL(FreeCommandBuffers(fDevice, fCmdPool, 1, &cmdBuffer));
VK_CALL(DestroyFence(fDevice, fence, nullptr)); VK_CALL(DestroyFence(fDevice, fence, nullptr));
info->fImage = image;
info->fAlloc = alloc;
info->fImageTiling = VK_IMAGE_TILING_OPTIMAL;
info->fImageLayout = initialLayout;
info->fFormat = pixelFormat;
info->fLevelCount = mipLevels;
return true;
}
GrBackendTexture GrVkGpu::createTestingOnlyBackendTexture(const void* srcData, int w, int h,
GrPixelConfig config, bool isRenderTarget,
GrMipMapped mipMapped) {
GrVkImageInfo info; GrVkImageInfo info;
info.fImage = image; if (!this->createTestingOnlyVkImage(config, w, h, true, isRenderTarget, mipMapped, srcData,
info.fAlloc = alloc; &info)) {
info.fImageTiling = VK_IMAGE_TILING_OPTIMAL; return {};
info.fImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; }
info.fFormat = pixelFormat;
info.fLevelCount = mipLevels;
return GrBackendTexture(w, h, info); return GrBackendTexture(w, h, info);
} }
@ -1512,13 +1530,29 @@ void GrVkGpu::deleteTestingOnlyBackendTexture(const GrBackendTexture& tex) {
} }
} }
GrBackendRenderTarget GrVkGpu::createTestingOnlyBackendRenderTarget(int w, int h, GrColorType, GrBackendRenderTarget GrVkGpu::createTestingOnlyBackendRenderTarget(int w, int h, GrColorType ct,
GrSRGBEncoded) { GrSRGBEncoded srgbEncoded) {
return GrBackendRenderTarget(); GrVkImageInfo info;
auto config = GrColorTypeToPixelConfig(ct, srgbEncoded);
if (kUnknown_GrPixelConfig == config) {
return {};
}
if (!this->createTestingOnlyVkImage(config, w, h, false, true, GrMipMapped::kNo, nullptr,
&info)) {
return {};
}
return {w, h, 1, 0, info};
} }
void GrVkGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {} void GrVkGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& rt) {
SkASSERT(kVulkan_GrBackend == rt.fBackend);
if (const auto* info = rt.getVkImageInfo()) {
// something in the command buffer may still be using this, so force submit
this->submitCommandBuffer(kForce_SyncQueue);
GrVkImage::DestroyImageInfo(this, const_cast<GrVkImageInfo*>(info));
}
}
void GrVkGpu::testingOnly_flushGpuAndSync() { void GrVkGpu::testingOnly_flushGpuAndSync() {
this->submitCommandBuffer(kForce_SyncQueue); this->submitCommandBuffer(kForce_SyncQueue);

View File

@ -70,9 +70,8 @@ public:
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {} void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
#if GR_TEST_UTILS #if GR_TEST_UTILS
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h, GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
GrPixelConfig config, GrPixelConfig config, bool isRenderTarget,
bool isRenderTarget,
GrMipMapped) override; GrMipMapped) override;
bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override; void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;
@ -247,6 +246,12 @@ private:
void resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect, void resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect,
const SkIPoint& dstPoint); const SkIPoint& dstPoint);
#if GR_TEST_UTILS
bool createTestingOnlyVkImage(GrPixelConfig config, int w, int h, bool texturable,
bool renderable, GrMipMapped mipMapped, const void* srcData,
GrVkImageInfo* info);
#endif
sk_sp<const GrVkBackendContext> fBackendContext; sk_sp<const GrVkBackendContext> fBackendContext;
sk_sp<GrVkCaps> fVkCaps; sk_sp<GrVkCaps> fVkCaps;

View File

@ -12,6 +12,7 @@
#if SK_SUPPORT_GPU #if SK_SUPPORT_GPU
#include "GrBackendSurface.h" #include "GrBackendSurface.h"
#include "GrContextPriv.h" #include "GrContextPriv.h"
#include "GrGpu.h"
#include "GrProxyProvider.h" #include "GrProxyProvider.h"
#include "GrRenderTarget.h" #include "GrRenderTarget.h"
#include "GrRenderTargetProxy.h" #include "GrRenderTargetProxy.h"
@ -19,36 +20,46 @@
#include "GrTexture.h" #include "GrTexture.h"
#include "GrTextureProxy.h" #include "GrTextureProxy.h"
static sk_sp<GrSurfaceProxy> make_wrapped_FBO0(GrProxyProvider* provider, static sk_sp<GrSurfaceProxy> make_wrapped_rt(GrProxyProvider* provider,
skiatest::Reporter* reporter, GrGpu* gpu,
const GrSurfaceDesc& desc, skiatest::Reporter* reporter,
GrSurfaceOrigin origin) { const GrSurfaceDesc& desc,
GrGLFramebufferInfo fboInfo; GrSurfaceOrigin origin) {
fboInfo.fFBOID = 0; // We don't currently have a way of making MSAA backend render targets.
GrBackendRenderTarget backendRT(desc.fWidth, desc.fHeight, desc.fSampleCnt, 8, SkASSERT(1 == desc.fSampleCnt);
desc.fConfig, fboInfo); GrSRGBEncoded srgbEncoded;
auto ct = GrPixelConfigToColorTypeAndEncoding(desc.fConfig, &srgbEncoded);
auto backendRT = gpu->createTestingOnlyBackendRenderTarget(desc.fWidth, desc.fHeight, ct,
GrSRGBEncoded::kNo);
return provider->wrapBackendRenderTarget(backendRT, origin); return provider->wrapBackendRenderTarget(backendRT, origin);
} }
static sk_sp<GrSurfaceProxy> make_wrapped_offscreen_rt(GrProxyProvider* provider, void clean_up_wrapped_rt(GrGpu* gpu, sk_sp<GrSurfaceProxy> proxy) {
const GrSurfaceDesc& desc, SkASSERT(proxy->isUnique_debugOnly());
GrSurfaceOrigin origin) { SkASSERT(proxy->priv().peekRenderTarget());
GrBackendRenderTarget rt = proxy->priv().peekRenderTarget()->getBackendRenderTarget();
proxy.reset();
gpu->deleteTestingOnlyBackendRenderTarget(rt);
}
static sk_sp<GrSurfaceProxy> make_offscreen_rt(GrProxyProvider* provider,
const GrSurfaceDesc& desc,
GrSurfaceOrigin origin) {
SkASSERT(kRenderTarget_GrSurfaceFlag == desc.fFlags); SkASSERT(kRenderTarget_GrSurfaceFlag == desc.fFlags);
return provider->createInstantiatedProxy(desc, origin, SkBackingFit::kExact, SkBudgeted::kYes); return provider->createInstantiatedProxy(desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
} }
static sk_sp<GrSurfaceProxy> make_wrapped_texture(GrProxyProvider* provider, static sk_sp<GrSurfaceProxy> make_texture(GrProxyProvider* provider,
const GrSurfaceDesc& desc, const GrSurfaceDesc& desc,
GrSurfaceOrigin origin) { GrSurfaceOrigin origin) {
return provider->createInstantiatedProxy(desc, origin, SkBackingFit::kExact, SkBudgeted::kYes); return provider->createInstantiatedProxy(desc, origin, SkBackingFit::kExact, SkBudgeted::kYes);
} }
// Test converting between RenderTargetProxies and TextureProxies for wrapped // Test converting between RenderTargetProxies and TextureProxies for preinstantiated Proxies
// Proxies DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PreinstantiatedProxyConversionTest, reporter, ctxInfo) {
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyConversionTest, reporter, ctxInfo) {
GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider(); GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
GrGpu* gpu = ctxInfo.grContext()->contextPriv().getGpu();
GrSurfaceDesc desc; GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fFlags = kRenderTarget_GrSurfaceFlag;
@ -56,23 +67,24 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyConversionTest, reporter, ctxInfo
desc.fHeight = 64; desc.fHeight = 64;
desc.fConfig = kRGBA_8888_GrPixelConfig; desc.fConfig = kRGBA_8888_GrPixelConfig;
if (kOpenGL_GrBackend == ctxInfo.backend()) { {
// External on-screen render target. // External on-screen render target.
sk_sp<GrSurfaceProxy> sProxy( sk_sp<GrSurfaceProxy> sProxy(
make_wrapped_FBO0(proxyProvider, reporter, desc, kBottomLeft_GrSurfaceOrigin)); make_wrapped_rt(proxyProvider, gpu, reporter, desc, kBottomLeft_GrSurfaceOrigin));
if (sProxy) { if (sProxy) {
// RenderTarget-only // RenderTarget-only
GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy(); GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy();
REPORTER_ASSERT(reporter, rtProxy); REPORTER_ASSERT(reporter, rtProxy);
REPORTER_ASSERT(reporter, !rtProxy->asTextureProxy()); REPORTER_ASSERT(reporter, !rtProxy->asTextureProxy());
REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy); REPORTER_ASSERT(reporter, rtProxy->asRenderTargetProxy() == rtProxy);
clean_up_wrapped_rt(gpu, std::move(sProxy));
} }
} }
{ {
// Internal offscreen render target. // Internal offscreen render target.
sk_sp<GrSurfaceProxy> sProxy( sk_sp<GrSurfaceProxy> sProxy(
make_wrapped_offscreen_rt(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin)); make_offscreen_rt(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin));
if (sProxy) { if (sProxy) {
// Both RenderTarget and Texture // Both RenderTarget and Texture
GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy(); GrRenderTargetProxy* rtProxy = sProxy->asRenderTargetProxy();
@ -87,7 +99,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyConversionTest, reporter, ctxInfo
{ {
// Internal offscreen render target - but through GrTextureProxy // Internal offscreen render target - but through GrTextureProxy
sk_sp<GrSurfaceProxy> sProxy( sk_sp<GrSurfaceProxy> sProxy(
make_wrapped_texture(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin)); make_texture(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin));
if (sProxy) { if (sProxy) {
// Both RenderTarget and Texture // Both RenderTarget and Texture
GrTextureProxy* tProxy = sProxy->asTextureProxy(); GrTextureProxy* tProxy = sProxy->asTextureProxy();
@ -103,7 +115,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyConversionTest, reporter, ctxInfo
desc.fFlags = kNone_GrSurfaceFlags; // force no-RT desc.fFlags = kNone_GrSurfaceFlags; // force no-RT
sk_sp<GrSurfaceProxy> sProxy( sk_sp<GrSurfaceProxy> sProxy(
make_wrapped_texture(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin)); make_texture(proxyProvider, desc, kBottomLeft_GrSurfaceOrigin));
if (sProxy) { if (sProxy) {
// Texture-only // Texture-only
GrTextureProxy* tProxy = sProxy->asTextureProxy(); GrTextureProxy* tProxy = sProxy->asTextureProxy();

View File

@ -201,12 +201,28 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
static const int kWidthHeight = 100; static const int kWidthHeight = 100;
if (kOpenGL_GrBackend != ctxInfo.backend()) {
return;
}
for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) { for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
for (auto colorType : { kAlpha_8_SkColorType, kRGBA_8888_SkColorType, for (auto colorType : { kAlpha_8_SkColorType, kRGBA_8888_SkColorType,
kRGBA_1010102_SkColorType }) { kRGBA_1010102_SkColorType }) {
// External on-screen render target.
// Tests wrapBackendRenderTarget with a GrBackendRenderTarget
// Our test-only function that creates a backend render target doesn't currently support
// sample counts :(.
if (ctxInfo.grContext()->colorTypeSupportedAsSurface(colorType)) {
GrBackendRenderTarget backendRT = gpu->createTestingOnlyBackendRenderTarget(
kWidthHeight, kWidthHeight, SkColorTypeToGrColorType(colorType),
GrSRGBEncoded::kNo);
sk_sp<GrSurfaceProxy> sProxy(
proxyProvider->wrapBackendRenderTarget(backendRT, origin));
check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight,
backendRT.testingOnly_getPixelConfig(), SkBudgeted::kNo);
static constexpr int kExpectedNumSamples = 1;
check_rendertarget(reporter, caps, resourceProvider, sProxy->asRenderTargetProxy(),
kExpectedNumSamples, SkBackingFit::kExact,
caps.maxWindowRectangles());
gpu->deleteTestingOnlyBackendRenderTarget(backendRT);
}
for (auto numSamples : {1, 4}) { for (auto numSamples : {1, 4}) {
GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, caps); GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, caps);
SkASSERT(kUnknown_GrPixelConfig != config); SkASSERT(kUnknown_GrPixelConfig != config);
@ -216,14 +232,14 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
continue; continue;
} }
// External on-screen render target. // Test wrapping FBO 0 (with made up properties). This tests sample count and the
// Tests wrapBackendRenderTarget with a GrBackendRenderTarget // special case where FBO 0 doesn't support window rectangles.
{ if (kOpenGL_GrBackend == ctxInfo.backend()) {
GrGLFramebufferInfo fboInfo; GrGLFramebufferInfo fboInfo;
fboInfo.fFBOID = 0; fboInfo.fFBOID = 0;
GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples, 8, static constexpr int kStencilBits = 8;
config, fboInfo); GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples,
kStencilBits, config, fboInfo);
sk_sp<GrSurfaceProxy> sProxy( sk_sp<GrSurfaceProxy> sProxy(
proxyProvider->wrapBackendRenderTarget(backendRT, origin)); proxyProvider->wrapBackendRenderTarget(backendRT, origin));
check_surface(reporter, sProxy.get(), origin, check_surface(reporter, sProxy.get(), origin,

View File

@ -89,6 +89,8 @@ static const struct {
,{ "vkwide", "gpu", "api=vulkan,color=f16_wide" } ,{ "vkwide", "gpu", "api=vulkan,color=f16_wide" }
,{ "vkmsaa4", "gpu", "api=vulkan,samples=4" } ,{ "vkmsaa4", "gpu", "api=vulkan,samples=4" }
,{ "vkmsaa8", "gpu", "api=vulkan,samples=8" } ,{ "vkmsaa8", "gpu", "api=vulkan,samples=8" }
,{ "vkbetex", "gpu", "api=vulkan,surf=betex" }
,{ "vkbert", "gpu", "api=vulkan,surf=bert" }
#endif #endif
#ifdef SK_METAL #ifdef SK_METAL
,{ "mtl", "gpu", "api=metal" } ,{ "mtl", "gpu", "api=metal" }

View File

@ -212,7 +212,7 @@ void GrGpu::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>*
#endif #endif
GrBackendTexture GrGpu::createTestingOnlyBackendTexture(void* pixels, int w, int h, GrBackendTexture GrGpu::createTestingOnlyBackendTexture(const void* pixels, int w, int h,
SkColorType colorType, bool isRenderTarget, SkColorType colorType, bool isRenderTarget,
GrMipMapped mipMapped) { GrMipMapped mipMapped) {
GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps()); GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, *this->caps());