diff options
-rw-r--r-- | gn/tests.gni | 1 | ||||
-rw-r--r-- | src/gpu/vk/GrVkResourceProvider.cpp | 3 | ||||
-rw-r--r-- | tests/VkMakeCopyPipelineTest.cpp | 191 |
3 files changed, 195 insertions, 0 deletions
diff --git a/gn/tests.gni b/gn/tests.gni index 02293a0b48..50cca5487e 100644 --- a/gn/tests.gni +++ b/gn/tests.gni @@ -274,6 +274,7 @@ tests_sources = [ "$_tests/VerticesTest.cpp", "$_tests/VkClearTests.cpp", "$_tests/VkHeapTests.cpp", + "$_tests/VkMakeCopyPipelineTest.cpp", "$_tests/VkUploadPixelsTests.cpp", "$_tests/VkWrapTests.cpp", "$_tests/VptrTest.cpp", diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp index 765e8388f0..9a219c8861 100644 --- a/src/gpu/vk/GrVkResourceProvider.cpp +++ b/src/gpu/vk/GrVkResourceProvider.cpp @@ -88,6 +88,9 @@ GrVkCopyPipeline* GrVkResourceProvider::findOrCreateCopyPipeline( dst->numColorSamples(), *dst->simpleRenderPass(), fPipelineCache); + if (!pipeline) { + return nullptr; + } fCopyPipelines.push_back(pipeline); } SkASSERT(pipeline); diff --git a/tests/VkMakeCopyPipelineTest.cpp b/tests/VkMakeCopyPipelineTest.cpp new file mode 100644 index 0000000000..f9a0ec60df --- /dev/null +++ b/tests/VkMakeCopyPipelineTest.cpp @@ -0,0 +1,191 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// This is a GPU-backend specific test. It relies on static intializers to work + +#include "SkTypes.h" + +#if SK_SUPPORT_GPU && defined(SK_VULKAN) + +#include "GrContextFactory.h" +#include "GrContextPriv.h" +#include "GrTest.h" +#include "GrTexture.h" +#include "Test.h" +#include "vk/GrVkCopyPipeline.h" +#include "vk/GrVkGpu.h" +#include "vk/GrVkRenderTarget.h" +#include "vk/GrVkUtil.h" + +using sk_gpu_test::GrContextFactory; + +class TestVkCopyProgram { +public: + TestVkCopyProgram() + : fVertShaderModule(VK_NULL_HANDLE) + , fFragShaderModule(VK_NULL_HANDLE) + , fPipelineLayout(VK_NULL_HANDLE) {} + + void test(GrVkGpu* gpu, skiatest::Reporter* reporter) { + const char vertShaderText[] = + "#extension GL_ARB_separate_shader_objects : enable\n" + "#extension GL_ARB_shading_language_420pack : enable\n" + + "layout(set = 0, binding = 0) uniform vertexUniformBuffer {" + "half4 uPosXform;" + "half4 uTexCoordXform;" + "};" + "layout(location = 0) in float2 inPosition;" + "layout(location = 1) out half2 vTexCoord;" + + "// Copy Program VS\n" + "void main() {" + "vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;" + "sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;" + "sk_Position.zw = half2(0, 1);" + "}"; + + const char fragShaderText[] = + "#extension GL_ARB_separate_shader_objects : enable\n" + "#extension GL_ARB_shading_language_420pack : enable\n" + + "layout(set = 1, binding = 0) uniform sampler2D uTextureSampler;" + "layout(location = 1) in half2 vTexCoord;" + "layout(location = 0, index = 0) out half4 fsColorOut;" + + "// Copy Program FS\n" + "void main() {" + "fsColorOut = texture(uTextureSampler, vTexCoord);" + "}"; + + SkSL::Program::Settings settings; + SkSL::Program::Inputs inputs; + if (!GrCompileVkShaderModule(gpu, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, + &fVertShaderModule, &fShaderStageInfo[0], settings, &inputs)) { + this->destroyResources(gpu); + REPORTER_ASSERT(reporter, false); + return; + } + SkASSERT(inputs.isEmpty()); + + if (!GrCompileVkShaderModule(gpu, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, + &fFragShaderModule, &fShaderStageInfo[1], settings, &inputs)) { + this->destroyResources(gpu); + REPORTER_ASSERT(reporter, false); + return; + } + + VkDescriptorSetLayout dsLayout[2]; + + GrVkResourceProvider& resourceProvider = gpu->resourceProvider(); + + dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout(); + + uint32_t samplerVisibility = kFragment_GrShaderFlag; + SkTArray<uint32_t> visibilityArray(&samplerVisibility, 1); + + resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + visibilityArray, &fSamplerDSHandle); + dsLayout[GrVkUniformHandler::kSamplerDescSet] = + resourceProvider.getSamplerDSLayout(fSamplerDSHandle); + + // Create the VkPipelineLayout + VkPipelineLayoutCreateInfo layoutCreateInfo; + memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags)); + layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layoutCreateInfo.pNext = 0; + layoutCreateInfo.flags = 0; + layoutCreateInfo.setLayoutCount = 2; + layoutCreateInfo.pSetLayouts = dsLayout; + layoutCreateInfo.pushConstantRangeCount = 0; + layoutCreateInfo.pPushConstantRanges = nullptr; + + VkResult err = GR_VK_CALL(gpu->vkInterface(), CreatePipelineLayout(gpu->device(), + &layoutCreateInfo, + nullptr, + &fPipelineLayout)); + if (err) { + this->destroyResources(gpu); + REPORTER_ASSERT(reporter, false); + return; + } + + GrSurfaceDesc surfDesc; + surfDesc.fFlags = kRenderTarget_GrSurfaceFlag; + surfDesc.fOrigin = kTopLeft_GrSurfaceOrigin; + surfDesc.fWidth = 16; + surfDesc.fHeight = 16; + surfDesc.fConfig = kRGBA_8888_GrPixelConfig; + surfDesc.fSampleCnt = 1; + sk_sp<GrTexture> tex = gpu->createTexture(surfDesc, SkBudgeted::kNo); + if (!tex) { + this->destroyResources(gpu); + REPORTER_ASSERT(reporter, tex.get()); + return; + + } + GrRenderTarget* rt = tex->asRenderTarget(); + REPORTER_ASSERT(reporter, rt); + GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt); + + GrVkCopyPipeline* copyPipeline = GrVkCopyPipeline::Create(gpu, + fShaderStageInfo, + fPipelineLayout, + 1, + *vkRT->simpleRenderPass(), + VK_NULL_HANDLE); + + REPORTER_ASSERT(reporter, copyPipeline); + if (copyPipeline) { + copyPipeline->unref(gpu); + } + + this->destroyResources(gpu); + } + + void destroyResources(GrVkGpu* gpu) { + if (VK_NULL_HANDLE != fVertShaderModule) { + GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fVertShaderModule, + nullptr)); + fVertShaderModule = VK_NULL_HANDLE; + } + + if (VK_NULL_HANDLE != fFragShaderModule) { + GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fFragShaderModule, + nullptr)); + fFragShaderModule = VK_NULL_HANDLE; + } + + if (VK_NULL_HANDLE != fPipelineLayout) { + GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), fPipelineLayout, + nullptr)); + fPipelineLayout = VK_NULL_HANDLE; + } + } + + VkShaderModule fVertShaderModule; + VkShaderModule fFragShaderModule; + VkPipelineShaderStageCreateInfo fShaderStageInfo[2]; + + GrVkDescriptorSetManager::Handle fSamplerDSHandle; + VkPipelineLayout fPipelineLayout; + +}; + +DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkMakeCopyPipelineTest, reporter, ctxInfo) { + GrContext* context = ctxInfo.grContext(); + GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu()); + + if (!gpu->vkCaps().supportsCopiesAsDraws()) { + return; + } + + TestVkCopyProgram copyProgram; + copyProgram.test(gpu, reporter); +} + +#endif |