aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/tests.gni1
-rw-r--r--src/gpu/vk/GrVkResourceProvider.cpp3
-rw-r--r--tests/VkMakeCopyPipelineTest.cpp191
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