1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci* Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci* 4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci* found in the LICENSE file. 6cb93a386Sopenharmony_ci*/ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkPipelineStateDataManager.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrGpuBuffer.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCommandBuffer.h" 15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciGrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms, 18cb93a386Sopenharmony_ci uint32_t uniformSize, 19cb93a386Sopenharmony_ci bool usePushConstants) 20cb93a386Sopenharmony_ci : INHERITED(uniforms.count(), uniformSize) 21cb93a386Sopenharmony_ci , fUsePushConstants(usePushConstants) { 22cb93a386Sopenharmony_ci // We must add uniforms in same order as the UniformInfoArray so that UniformHandles already 23cb93a386Sopenharmony_ci // owned by other objects will still match up here. 24cb93a386Sopenharmony_ci int i = 0; 25cb93a386Sopenharmony_ci GrVkUniformHandler::Layout memLayout = usePushConstants ? GrVkUniformHandler::kStd430Layout 26cb93a386Sopenharmony_ci : GrVkUniformHandler::kStd140Layout; 27cb93a386Sopenharmony_ci for (const auto& uniformInfo : uniforms.items()) { 28cb93a386Sopenharmony_ci Uniform& uniform = fUniforms[i]; 29cb93a386Sopenharmony_ci SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() || 30cb93a386Sopenharmony_ci uniformInfo.fVariable.getArrayCount() > 0); 31cb93a386Sopenharmony_ci SkDEBUGCODE( 32cb93a386Sopenharmony_ci uniform.fArrayCount = uniformInfo.fVariable.getArrayCount(); 33cb93a386Sopenharmony_ci ) 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci uniform.fOffset = uniformInfo.fOffsets[memLayout]; 36cb93a386Sopenharmony_ci uniform.fType = uniformInfo.fVariable.getType(); 37cb93a386Sopenharmony_ci ++i; 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_cistd::pair<sk_sp<GrGpuBuffer>, bool> GrVkPipelineStateDataManager::uploadUniforms( 42cb93a386Sopenharmony_ci GrVkGpu* gpu, VkPipelineLayout layout, GrVkCommandBuffer* commandBuffer) { 43cb93a386Sopenharmony_ci if (fUniformSize == 0) { 44cb93a386Sopenharmony_ci return std::make_pair(nullptr, true); 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci if (fUsePushConstants) { 47cb93a386Sopenharmony_ci commandBuffer->pushConstants(gpu, layout, gpu->vkCaps().getPushConstantStageFlags(), 48cb93a386Sopenharmony_ci 0, fUniformSize, fUniformData.get()); 49cb93a386Sopenharmony_ci fUniformBuffer = nullptr; 50cb93a386Sopenharmony_ci } else { 51cb93a386Sopenharmony_ci if (fUniformsDirty) { 52cb93a386Sopenharmony_ci GrResourceProvider* resourceProvider = gpu->getContext()->priv().resourceProvider(); 53cb93a386Sopenharmony_ci fUniformBuffer = resourceProvider->createBuffer( 54cb93a386Sopenharmony_ci fUniformSize, GrGpuBufferType::kUniform, kDynamic_GrAccessPattern, 55cb93a386Sopenharmony_ci fUniformData.get()); 56cb93a386Sopenharmony_ci if (!fUniformBuffer) { 57cb93a386Sopenharmony_ci return std::make_pair(nullptr, false); 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci fUniformsDirty = false; 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci return std::make_pair(fUniformBuffer, true); 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_civoid GrVkPipelineStateDataManager::set1iv(UniformHandle u, 67cb93a386Sopenharmony_ci int arrayCount, 68cb93a386Sopenharmony_ci const int32_t v[]) const { 69cb93a386Sopenharmony_ci if (fUsePushConstants) { 70cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 71cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType); 72cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 73cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 74cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 77cb93a386Sopenharmony_ci SkASSERT(sizeof(int32_t) == 4); 78cb93a386Sopenharmony_ci memcpy(buffer, v, arrayCount * sizeof(int32_t)); 79cb93a386Sopenharmony_ci } else { 80cb93a386Sopenharmony_ci return this->INHERITED::set1iv(u, arrayCount, v); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci} 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_civoid GrVkPipelineStateDataManager::set1fv(UniformHandle u, 85cb93a386Sopenharmony_ci int arrayCount, 86cb93a386Sopenharmony_ci const float v[]) const { 87cb93a386Sopenharmony_ci if (fUsePushConstants) { 88cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 89cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType); 90cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 91cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 92cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 95cb93a386Sopenharmony_ci SkASSERT(sizeof(float) == 4); 96cb93a386Sopenharmony_ci memcpy(buffer, v, arrayCount * sizeof(float)); 97cb93a386Sopenharmony_ci } else { 98cb93a386Sopenharmony_ci return this->INHERITED::set1fv(u, arrayCount, v); 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci} 101cb93a386Sopenharmony_ci 102cb93a386Sopenharmony_civoid GrVkPipelineStateDataManager::set2iv(UniformHandle u, 103cb93a386Sopenharmony_ci int arrayCount, 104cb93a386Sopenharmony_ci const int32_t v[]) const { 105cb93a386Sopenharmony_ci if (fUsePushConstants) { 106cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 107cb93a386Sopenharmony_ci SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType); 108cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 109cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 110cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 113cb93a386Sopenharmony_ci SkASSERT(sizeof(int32_t) == 4); 114cb93a386Sopenharmony_ci memcpy(buffer, v, arrayCount * 2 * sizeof(int32_t)); 115cb93a386Sopenharmony_ci } else { 116cb93a386Sopenharmony_ci return this->INHERITED::set2iv(u, arrayCount, v); 117cb93a386Sopenharmony_ci } 118cb93a386Sopenharmony_ci} 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_civoid GrVkPipelineStateDataManager::set2fv(UniformHandle u, 121cb93a386Sopenharmony_ci int arrayCount, 122cb93a386Sopenharmony_ci const float v[]) const { 123cb93a386Sopenharmony_ci if (fUsePushConstants) { 124cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 125cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType); 126cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 127cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 128cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci void* buffer = this->getBufferPtrAndMarkDirty(uni); 131cb93a386Sopenharmony_ci SkASSERT(sizeof(float) == 4); 132cb93a386Sopenharmony_ci memcpy(buffer, v, arrayCount * 2 * sizeof(float)); 133cb93a386Sopenharmony_ci } else { 134cb93a386Sopenharmony_ci return this->INHERITED::set2fv(u, arrayCount, v); 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci} 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_civoid GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u, 139cb93a386Sopenharmony_ci int arrayCount, 140cb93a386Sopenharmony_ci const float m[]) const { 141cb93a386Sopenharmony_ci if (fUsePushConstants) { 142cb93a386Sopenharmony_ci // upload as std430 143cb93a386Sopenharmony_ci const Uniform& uni = fUniforms[u.toIndex()]; 144cb93a386Sopenharmony_ci SkASSERT(uni.fType == kFloat2x2_GrSLType || uni.fType == kHalf2x2_GrSLType); 145cb93a386Sopenharmony_ci SkASSERT(arrayCount > 0); 146cb93a386Sopenharmony_ci SkASSERT(arrayCount <= uni.fArrayCount || 147cb93a386Sopenharmony_ci (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount)); 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci void* buffer = fUniformData.get(); 150cb93a386Sopenharmony_ci fUniformsDirty = true; 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci static_assert(sizeof(float) == 4); 153cb93a386Sopenharmony_ci buffer = static_cast<char*>(buffer) + uni.fOffset; 154cb93a386Sopenharmony_ci memcpy(buffer, m, arrayCount * 2 * 2 * sizeof(float)); 155cb93a386Sopenharmony_ci } else { 156cb93a386Sopenharmony_ci this->INHERITED::setMatrix2fv(u, arrayCount, m); 157cb93a386Sopenharmony_ci } 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_civoid GrVkPipelineStateDataManager::releaseData() { fUniformBuffer.reset(); } 161