Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Unified Diff: src/gpu/vk/GrVkProgramBuilder.cpp

Issue 1718693002: Add vulkan files into skia repo. (Closed) Base URL: https://skia.googlesource.com/skia.git@merge
Patch Set: fix path Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/vk/GrVkProgramBuilder.h ('k') | src/gpu/vk/GrVkProgramDataManager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/vk/GrVkProgramBuilder.cpp
diff --git a/src/gpu/vk/GrVkProgramBuilder.cpp b/src/gpu/vk/GrVkProgramBuilder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..13daf714d909ffe338e4d4bd137bd56962801496
--- /dev/null
+++ b/src/gpu/vk/GrVkProgramBuilder.cpp
@@ -0,0 +1,323 @@
+/*
+* Copyright 2016 Google Inc.
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#include "vk/GrVkProgramBuilder.h"
+
+#include "vk/GrVkGpu.h"
+#include "vk/GrVkRenderPass.h"
+#include "vk/GrVkProgram.h"
+
+GrVkProgram* GrVkProgramBuilder::CreateProgram(GrVkGpu* gpu,
+ const DrawArgs& args,
+ GrPrimitiveType primitiveType,
+ const GrVkRenderPass& renderPass) {
+ // create a builder. This will be handed off to effects so they can use it to add
+ // uniforms, varyings, textures, etc
+ GrVkProgramBuilder builder(gpu, args);
+
+ GrGLSLExpr4 inputColor;
+ GrGLSLExpr4 inputCoverage;
+
+ if (!builder.emitAndInstallProcs(&inputColor,
+ &inputCoverage,
+ gpu->vkCaps().maxSampledTextures())) {
+ builder.cleanupFragmentProcessors();
+ return nullptr;
+ }
+
+ return builder.finalize(args, primitiveType, renderPass);
+}
+
+GrVkProgramBuilder::GrVkProgramBuilder(GrVkGpu* gpu, const DrawArgs& args)
+ : INHERITED(args)
+ , fGpu(gpu)
+ , fVaryingHandler(this)
+ , fUniformHandler(this) {
+}
+
+const GrCaps* GrVkProgramBuilder::caps() const {
+ return fGpu->caps();
+}
+const GrGLSLCaps* GrVkProgramBuilder::glslCaps() const {
+ return fGpu->vkCaps().glslCaps();
+}
+
+void GrVkProgramBuilder::finalizeFragmentOutputColor(GrGLSLShaderVar& outputColor) {
+ outputColor.setLayoutQualifier("location = 0");
+}
+
+void GrVkProgramBuilder::emitSamplers(const GrProcessor& processor,
+ GrGLSLTextureSampler::TextureSamplerArray* outSamplers) {
+ int numTextures = processor.numTextures();
+ UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures);
+ SkString name;
+ for (int t = 0; t < numTextures; ++t) {
+ name.printf("%d", t);
+ localSamplerUniforms[t] =
+ fUniformHandler.addUniform(kFragment_GrShaderFlag,
+ kSampler2D_GrSLType, kDefault_GrSLPrecision,
+ name.c_str());
+ outSamplers->emplace_back(localSamplerUniforms[t], processor.textureAccess(t));
+ }
+}
+
+VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
+ VkShaderStageFlags flags = 0;
+
+ if (visibility & kVertex_GrShaderFlag) {
+ flags |= VK_SHADER_STAGE_VERTEX_BIT;
+ }
+ if (visibility & kGeometry_GrShaderFlag) {
+ flags |= VK_SHADER_STAGE_GEOMETRY_BIT;
+ }
+ if (visibility & kFragment_GrShaderFlag) {
+ flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
+ }
+ return flags;
+}
+
+shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage) {
+ if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
+ return shaderc_glsl_vertex_shader;
+ }
+ SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage);
+ return shaderc_glsl_fragment_shader;
+}
+
+bool GrVkProgramBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
+ VkShaderStageFlagBits stage,
+ const GrGLSLShaderBuilder& builder,
+ VkShaderModule* shaderModule,
+ VkPipelineShaderStageCreateInfo* stageInfo) {
+ SkString shaderString;
+ for (int i = 0; i < builder.fCompilerStrings.count(); ++i) {
+ if (builder.fCompilerStrings[i]) {
+ shaderString.append(builder.fCompilerStrings[i]);
+ shaderString.append("\n");
+ }
+ }
+
+ shaderc_compiler_t compiler = gpu->shadercCompiler();
+
+ shaderc_compile_options_t options = shaderc_compile_options_initialize();
+ shaderc_compile_options_set_forced_version_profile(options, 140, shaderc_profile_none);
+
+ shaderc_shader_kind shadercStage = vk_shader_stage_to_shaderc_kind(stage);
+ shaderc_spv_module_t module = shaderc_compile_into_spv(compiler,
+ shaderString.c_str(),
+ strlen(shaderString.c_str()),
+ shadercStage,
+ "shader",
+ "main",
+ options);
+ shaderc_compile_options_release(options);
+#ifdef SK_DEBUG
+ if (shaderc_module_get_num_errors(module)) {
+ SkDebugf("%s\n", shaderString.c_str());
+ SkDebugf("%s\n", shaderc_module_get_error_message(module));
+ return false;
+ }
+#endif
+
+ VkShaderModuleCreateInfo moduleCreateInfo;
+ memset(&moduleCreateInfo, 0, sizeof(VkShaderModuleCreateInfo));
+ moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+ moduleCreateInfo.pNext = nullptr;
+ moduleCreateInfo.flags = 0;
+ moduleCreateInfo.codeSize = shaderc_module_get_length(module);
+ moduleCreateInfo.pCode = (const uint32_t*)shaderc_module_get_bytes(module);
+
+ VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(),
+ &moduleCreateInfo,
+ nullptr,
+ shaderModule));
+ shaderc_module_release(module);
+ if (err) {
+ return false;
+ }
+
+ memset(stageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo));
+ stageInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ stageInfo->pNext = nullptr;
+ stageInfo->flags = 0;
+ stageInfo->stage = stage;
+ stageInfo->module = *shaderModule;
+ stageInfo->pName = "main";
+ stageInfo->pSpecializationInfo = nullptr;
+
+ return true;
+}
+
+GrVkProgram* GrVkProgramBuilder::finalize(const DrawArgs& args,
+ GrPrimitiveType primitiveType,
+ const GrVkRenderPass& renderPass) {
+ VkDescriptorSetLayout dsLayout[2];
+ VkPipelineLayout pipelineLayout;
+ VkShaderModule vertShaderModule;
+ VkShaderModule fragShaderModule;
+
+ uint32_t numSamplers = fSamplerUniforms.count();
+
+ SkAutoTDeleteArray<VkDescriptorSetLayoutBinding> dsSamplerBindings(
+ new VkDescriptorSetLayoutBinding[numSamplers]);
+ for (uint32_t i = 0; i < numSamplers; ++i) {
+ UniformHandle uniHandle = fSamplerUniforms[i];
+ GrVkUniformHandler::UniformInfo uniformInfo = fUniformHandler.getUniformInfo(uniHandle);
+ SkASSERT(kSampler2D_GrSLType == uniformInfo.fVariable.getType());
+ SkASSERT(0 == uniformInfo.fSetNumber);
+ SkASSERT(uniformInfo.fBinding == i);
+ dsSamplerBindings[i].binding = uniformInfo.fBinding;
+ dsSamplerBindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ dsSamplerBindings[i].descriptorCount = 1;
+ dsSamplerBindings[i].stageFlags = visibility_to_vk_stage_flags(uniformInfo.fVisibility);
+ dsSamplerBindings[i].pImmutableSamplers = nullptr;
+ }
+
+ VkDescriptorSetLayoutCreateInfo dsSamplerLayoutCreateInfo;
+ memset(&dsSamplerLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
+ dsSamplerLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ dsSamplerLayoutCreateInfo.pNext = nullptr;
+ dsSamplerLayoutCreateInfo.flags = 0;
+ dsSamplerLayoutCreateInfo.bindingCount = fSamplerUniforms.count();
+ // Setting to nullptr fixes an error in the param checker validation layer. Even though
+ // bindingCount is 0 (which is valid), it still tries to validate pBindings unless it is null.
+ dsSamplerLayoutCreateInfo.pBindings = fSamplerUniforms.count() ? dsSamplerBindings.get() :
+ nullptr;
+
+ GR_VK_CALL_ERRCHECK(fGpu->vkInterface(),
+ CreateDescriptorSetLayout(fGpu->device(),
+ &dsSamplerLayoutCreateInfo,
+ nullptr,
+ &dsLayout[GrVkUniformHandler::kSamplerDescSet]));
+
+ // Create Uniform Buffer Descriptor
+ // We always attach uniform buffers to descriptor set 1. The vertex uniform buffer will have
+ // binding 0 and the fragment binding 1.
+ VkDescriptorSetLayoutBinding dsUniBindings[2];
+ memset(&dsUniBindings, 0, 2 * sizeof(VkDescriptorSetLayoutBinding));
+ dsUniBindings[0].binding = GrVkUniformHandler::kVertexBinding;
+ dsUniBindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ dsUniBindings[0].descriptorCount = fUniformHandler.hasVertexUniforms() ? 1 : 0;
+ dsUniBindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+ dsUniBindings[0].pImmutableSamplers = nullptr;
+ dsUniBindings[1].binding = GrVkUniformHandler::kFragBinding;
+ dsUniBindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ dsUniBindings[1].descriptorCount = fUniformHandler.hasFragmentUniforms() ? 1 : 0;
+ dsUniBindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+ dsUniBindings[1].pImmutableSamplers = nullptr;
+
+ VkDescriptorSetLayoutCreateInfo dsUniformLayoutCreateInfo;
+ memset(&dsUniformLayoutCreateInfo, 0, sizeof(VkDescriptorSetLayoutCreateInfo));
+ dsUniformLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ dsUniformLayoutCreateInfo.pNext = nullptr;
+ dsUniformLayoutCreateInfo.flags = 0;
+ dsUniformLayoutCreateInfo.bindingCount = 2;
+ dsUniformLayoutCreateInfo.pBindings = dsUniBindings;
+
+ GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreateDescriptorSetLayout(
+ fGpu->device(),
+ &dsUniformLayoutCreateInfo,
+ nullptr,
+ &dsLayout[GrVkUniformHandler::kUniformBufferDescSet]));
+
+ // 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;
+
+ GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), CreatePipelineLayout(fGpu->device(),
+ &layoutCreateInfo,
+ nullptr,
+ &pipelineLayout));
+
+ // We need to enable the following extensions so that the compiler can correctly make spir-v
+ // from our glsl shaders.
+ fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
+ fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
+ fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
+ fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
+
+ this->finalizeShaders();
+
+ VkPipelineShaderStageCreateInfo shaderStageInfo[2];
+ SkAssertResult(CreateVkShaderModule(fGpu,
+ VK_SHADER_STAGE_VERTEX_BIT,
+ fVS,
+ &vertShaderModule,
+ &shaderStageInfo[0]));
+
+ SkAssertResult(CreateVkShaderModule(fGpu,
+ VK_SHADER_STAGE_FRAGMENT_BIT,
+ fFS,
+ &fragShaderModule,
+ &shaderStageInfo[1]));
+
+ GrVkResourceProvider& resourceProvider = fGpu->resourceProvider();
+ GrVkPipeline* pipeline = resourceProvider.createPipeline(*args.fPipeline,
+ *args.fPrimitiveProcessor,
+ shaderStageInfo,
+ 2,
+ primitiveType,
+ renderPass,
+ pipelineLayout);
+ GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), vertShaderModule,
+ nullptr));
+ GR_VK_CALL(fGpu->vkInterface(), DestroyShaderModule(fGpu->device(), fragShaderModule,
+ nullptr));
+
+ if (!pipeline) {
+ GR_VK_CALL(fGpu->vkInterface(), DestroyPipelineLayout(fGpu->device(), pipelineLayout,
+ nullptr));
+ GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[0],
+ nullptr));
+ GR_VK_CALL(fGpu->vkInterface(), DestroyDescriptorSetLayout(fGpu->device(), dsLayout[1],
+ nullptr));
+ return nullptr;
+ }
+
+
+ GrVkDescriptorPool::DescriptorTypeCounts typeCounts;
+ typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2);
+ SkASSERT(numSamplers < 256);
+ typeCounts.setTypeCount(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (uint8_t)numSamplers);
+ GrVkDescriptorPool* descriptorPool =
+ fGpu->resourceProvider().findOrCreateCompatibleDescriptorPool(typeCounts);
+
+ VkDescriptorSetAllocateInfo dsAllocateInfo;
+ memset(&dsAllocateInfo, 0, sizeof(VkDescriptorSetAllocateInfo));
+ dsAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ dsAllocateInfo.pNext = nullptr;
+ dsAllocateInfo.descriptorPool = descriptorPool->descPool();
+ dsAllocateInfo.descriptorSetCount = 2;
+ dsAllocateInfo.pSetLayouts = dsLayout;
+
+ VkDescriptorSet descriptorSets[2];
+ GR_VK_CALL_ERRCHECK(fGpu->vkInterface(), AllocateDescriptorSets(fGpu->device(),
+ &dsAllocateInfo,
+ descriptorSets));
+
+ return new GrVkProgram(fGpu,
+ pipeline,
+ pipelineLayout,
+ dsLayout,
+ descriptorPool,
+ descriptorSets,
+ fUniformHandles,
+ fUniformHandler.fUniforms,
+ fUniformHandler.fCurrentVertexUBOOffset,
+ fUniformHandler.fCurrentFragmentUBOOffset,
+ numSamplers,
+ fGeometryProcessor,
+ fXferProcessor,
+ fFragmentProcessors);
+}
« no previous file with comments | « src/gpu/vk/GrVkProgramBuilder.h ('k') | src/gpu/vk/GrVkProgramDataManager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698