2018-03-01 16:34:59 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
|
|
|
|
2018-05-31 18:27:17 +00:00
|
|
|
#if defined(SK_VULKAN)
|
2018-03-01 16:34:59 +00:00
|
|
|
|
2018-11-20 22:12:36 +00:00
|
|
|
#include "vk/GrVkVulkan.h"
|
|
|
|
|
2018-09-04 17:27:00 +00:00
|
|
|
#include "GrBackendSurface.h"
|
2018-03-01 16:34:59 +00:00
|
|
|
#include "GrContextFactory.h"
|
|
|
|
#include "GrContextPriv.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() {"
|
2019-02-05 21:54:35 +00:00
|
|
|
"vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;"
|
2018-03-01 16:34:59 +00:00
|
|
|
"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;"
|
|
|
|
|
|
|
|
"// Copy Program FS\n"
|
|
|
|
"void main() {"
|
2018-03-16 12:52:32 +00:00
|
|
|
"sk_FragColor = texture(uTextureSampler, vTexCoord);"
|
2018-03-01 16:34:59 +00:00
|
|
|
"}";
|
|
|
|
|
|
|
|
SkSL::Program::Settings settings;
|
2018-12-19 18:12:10 +00:00
|
|
|
SkSL::String spirv;
|
2018-03-01 16:34:59 +00:00
|
|
|
SkSL::Program::Inputs inputs;
|
|
|
|
if (!GrCompileVkShaderModule(gpu, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT,
|
2018-12-19 18:12:10 +00:00
|
|
|
&fVertShaderModule, &fShaderStageInfo[0], settings,
|
|
|
|
&spirv, &inputs)) {
|
2018-03-01 16:34:59 +00:00
|
|
|
this->destroyResources(gpu);
|
|
|
|
REPORTER_ASSERT(reporter, false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SkASSERT(inputs.isEmpty());
|
|
|
|
|
|
|
|
if (!GrCompileVkShaderModule(gpu, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT,
|
2018-12-19 18:12:10 +00:00
|
|
|
&fFragShaderModule, &fShaderStageInfo[1], settings,
|
|
|
|
&spirv, &inputs)) {
|
2018-03-01 16:34:59 +00:00
|
|
|
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.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();
|
2019-02-04 18:26:26 +00:00
|
|
|
GrVkGpu* gpu = static_cast<GrVkGpu*>(context->priv().getGpu());
|
2018-03-01 16:34:59 +00:00
|
|
|
|
|
|
|
TestVkCopyProgram copyProgram;
|
|
|
|
copyProgram.test(gpu, reporter);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|