blob: 77359cd539d3a3ec121443a3bf029da82b09ddc7 [file] [log] [blame]
Greg Danielf3a4ef92018-03-01 11:34:59 -05001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8// This is a GPU-backend specific test. It relies on static intializers to work
9
10#include "SkTypes.h"
11
12#if SK_SUPPORT_GPU && defined(SK_VULKAN)
13
14#include "GrContextFactory.h"
15#include "GrContextPriv.h"
16#include "GrTest.h"
17#include "GrTexture.h"
18#include "Test.h"
19#include "vk/GrVkCopyPipeline.h"
20#include "vk/GrVkGpu.h"
21#include "vk/GrVkRenderTarget.h"
22#include "vk/GrVkUtil.h"
23
24using sk_gpu_test::GrContextFactory;
25
26class TestVkCopyProgram {
27public:
28 TestVkCopyProgram()
29 : fVertShaderModule(VK_NULL_HANDLE)
30 , fFragShaderModule(VK_NULL_HANDLE)
31 , fPipelineLayout(VK_NULL_HANDLE) {}
32
33 void test(GrVkGpu* gpu, skiatest::Reporter* reporter) {
34 const char vertShaderText[] =
35 "#extension GL_ARB_separate_shader_objects : enable\n"
36 "#extension GL_ARB_shading_language_420pack : enable\n"
37
38 "layout(set = 0, binding = 0) uniform vertexUniformBuffer {"
39 "half4 uPosXform;"
40 "half4 uTexCoordXform;"
41 "};"
42 "layout(location = 0) in float2 inPosition;"
43 "layout(location = 1) out half2 vTexCoord;"
44
45 "// Copy Program VS\n"
46 "void main() {"
47 "vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;"
48 "sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;"
49 "sk_Position.zw = half2(0, 1);"
50 "}";
51
52 const char fragShaderText[] =
53 "#extension GL_ARB_separate_shader_objects : enable\n"
54 "#extension GL_ARB_shading_language_420pack : enable\n"
55
56 "layout(set = 1, binding = 0) uniform sampler2D uTextureSampler;"
57 "layout(location = 1) in half2 vTexCoord;"
58 "layout(location = 0, index = 0) out half4 fsColorOut;"
59
60 "// Copy Program FS\n"
61 "void main() {"
62 "fsColorOut = texture(uTextureSampler, vTexCoord);"
63 "}";
64
65 SkSL::Program::Settings settings;
66 SkSL::Program::Inputs inputs;
67 if (!GrCompileVkShaderModule(gpu, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT,
68 &fVertShaderModule, &fShaderStageInfo[0], settings, &inputs)) {
69 this->destroyResources(gpu);
70 REPORTER_ASSERT(reporter, false);
71 return;
72 }
73 SkASSERT(inputs.isEmpty());
74
75 if (!GrCompileVkShaderModule(gpu, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
76 &fFragShaderModule, &fShaderStageInfo[1], settings, &inputs)) {
77 this->destroyResources(gpu);
78 REPORTER_ASSERT(reporter, false);
79 return;
80 }
81
82 VkDescriptorSetLayout dsLayout[2];
83
84 GrVkResourceProvider& resourceProvider = gpu->resourceProvider();
85
86 dsLayout[GrVkUniformHandler::kUniformBufferDescSet] = resourceProvider.getUniformDSLayout();
87
88 uint32_t samplerVisibility = kFragment_GrShaderFlag;
89 SkTArray<uint32_t> visibilityArray(&samplerVisibility, 1);
90
91 resourceProvider.getSamplerDescriptorSetHandle(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
92 visibilityArray, &fSamplerDSHandle);
93 dsLayout[GrVkUniformHandler::kSamplerDescSet] =
94 resourceProvider.getSamplerDSLayout(fSamplerDSHandle);
95
96 // Create the VkPipelineLayout
97 VkPipelineLayoutCreateInfo layoutCreateInfo;
98 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
99 layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
100 layoutCreateInfo.pNext = 0;
101 layoutCreateInfo.flags = 0;
102 layoutCreateInfo.setLayoutCount = 2;
103 layoutCreateInfo.pSetLayouts = dsLayout;
104 layoutCreateInfo.pushConstantRangeCount = 0;
105 layoutCreateInfo.pPushConstantRanges = nullptr;
106
107 VkResult err = GR_VK_CALL(gpu->vkInterface(), CreatePipelineLayout(gpu->device(),
108 &layoutCreateInfo,
109 nullptr,
110 &fPipelineLayout));
111 if (err) {
112 this->destroyResources(gpu);
113 REPORTER_ASSERT(reporter, false);
114 return;
115 }
116
117 GrSurfaceDesc surfDesc;
118 surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
Greg Danielf3a4ef92018-03-01 11:34:59 -0500119 surfDesc.fWidth = 16;
120 surfDesc.fHeight = 16;
121 surfDesc.fConfig = kRGBA_8888_GrPixelConfig;
122 surfDesc.fSampleCnt = 1;
123 sk_sp<GrTexture> tex = gpu->createTexture(surfDesc, SkBudgeted::kNo);
124 if (!tex) {
125 this->destroyResources(gpu);
126 REPORTER_ASSERT(reporter, tex.get());
127 return;
128
129 }
130 GrRenderTarget* rt = tex->asRenderTarget();
131 REPORTER_ASSERT(reporter, rt);
132 GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(rt);
133
134 GrVkCopyPipeline* copyPipeline = GrVkCopyPipeline::Create(gpu,
135 fShaderStageInfo,
136 fPipelineLayout,
137 1,
138 *vkRT->simpleRenderPass(),
139 VK_NULL_HANDLE);
140
141 REPORTER_ASSERT(reporter, copyPipeline);
142 if (copyPipeline) {
143 copyPipeline->unref(gpu);
144 }
145
146 this->destroyResources(gpu);
147 }
148
149 void destroyResources(GrVkGpu* gpu) {
150 if (VK_NULL_HANDLE != fVertShaderModule) {
151 GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fVertShaderModule,
152 nullptr));
153 fVertShaderModule = VK_NULL_HANDLE;
154 }
155
156 if (VK_NULL_HANDLE != fFragShaderModule) {
157 GR_VK_CALL(gpu->vkInterface(), DestroyShaderModule(gpu->device(), fFragShaderModule,
158 nullptr));
159 fFragShaderModule = VK_NULL_HANDLE;
160 }
161
162 if (VK_NULL_HANDLE != fPipelineLayout) {
163 GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(), fPipelineLayout,
164 nullptr));
165 fPipelineLayout = VK_NULL_HANDLE;
166 }
167 }
168
169 VkShaderModule fVertShaderModule;
170 VkShaderModule fFragShaderModule;
171 VkPipelineShaderStageCreateInfo fShaderStageInfo[2];
172
173 GrVkDescriptorSetManager::Handle fSamplerDSHandle;
174 VkPipelineLayout fPipelineLayout;
175
176};
177
178DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkMakeCopyPipelineTest, reporter, ctxInfo) {
179 GrContext* context = ctxInfo.grContext();
180 GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu());
181
182 if (!gpu->vkCaps().supportsCopiesAsDraws()) {
183 return;
184 }
185
186 TestVkCopyProgram copyProgram;
187 copyProgram.test(gpu, reporter);
188}
189
190#endif