Add GrD3DPipelineStateDataManager.
* Creates a common class between GrVkPipelineStateDataManager and
GrD3DPipelineStateDataManager so they can share code (will do
for Metal as well in separate CL)
* Adds means for tracking and setting uniform data.
Change-Id: Ie0dc3a3d26f533201e316d255965a646bcecb842
Bug: skia:9935
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290636
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 2310000..cf26ed1 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -244,6 +244,8 @@
"$_src/gpu/GrTransferFromRenderTask.h",
"$_src/gpu/GrTriangulator.cpp",
"$_src/gpu/GrTriangulator.h",
+ "$_src/gpu/GrUniformDataManager.cpp",
+ "$_src/gpu/GrUniformDataManager.h",
"$_src/gpu/GrUserStencilSettings.h",
"$_src/gpu/GrWaitRenderTask.cpp",
"$_src/gpu/GrWaitRenderTask.h",
@@ -759,6 +761,8 @@
"$_src/gpu/d3d/GrD3DPipelineState.h",
"$_src/gpu/d3d/GrD3DPipelineStateBuilder.cpp",
"$_src/gpu/d3d/GrD3DPipelineStateBuilder.h",
+ "$_src/gpu/d3d/GrD3DPipelineStateDataManager.cpp",
+ "$_src/gpu/d3d/GrD3DPipelineStateDataManager.h",
"$_src/gpu/d3d/GrD3DRenderTarget.cpp",
"$_src/gpu/d3d/GrD3DRenderTarget.h",
"$_src/gpu/d3d/GrD3DResourceProvider.cpp",
diff --git a/src/gpu/GrUniformDataManager.cpp b/src/gpu/GrUniformDataManager.cpp
new file mode 100644
index 0000000..549057a
--- /dev/null
+++ b/src/gpu/GrUniformDataManager.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/GrUniformDataManager.h"
+
+#include "src/gpu/GrShaderVar.h"
+
+GrUniformDataManager::GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize)
+ : fUniformSize(uniformSize)
+ , fUniformsDirty(false) {
+ fUniformData.reset(uniformSize);
+ fUniforms.push_back_n(uniformCount);
+ // subclasses fill in the uniforms in their constructor
+}
+
+void* GrUniformDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
+ fUniformsDirty = true;
+ return static_cast<char*>(fUniformData.get())+uni.fOffset;
+}
+
+void GrUniformDataManager::set1i(UniformHandle u, int32_t i) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ memcpy(buffer, &i, sizeof(int32_t));
+}
+
+void GrUniformDataManager::set1iv(UniformHandle u,
+ int arrayCount,
+ const int32_t v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(int32_t) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const int32_t* curVec = &v[i];
+ memcpy(buffer, curVec, sizeof(int32_t));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
+ }
+}
+
+void GrUniformDataManager::set1f(UniformHandle u, float v0) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ memcpy(buffer, &v0, sizeof(float));
+}
+
+void GrUniformDataManager::set1fv(UniformHandle u,
+ int arrayCount,
+ const float v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const float* curVec = &v[i];
+ memcpy(buffer, curVec, sizeof(float));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(float);
+ }
+}
+
+void GrUniformDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ int32_t v[2] = { i0, i1 };
+ memcpy(buffer, v, 2 * sizeof(int32_t));
+}
+
+void GrUniformDataManager::set2iv(UniformHandle u,
+ int arrayCount,
+ const int32_t v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(int32_t) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const int32_t* curVec = &v[2 * i];
+ memcpy(buffer, curVec, 2 * sizeof(int32_t));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
+ }
+}
+
+void GrUniformDataManager::set2f(UniformHandle u, float v0, float v1) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ float v[2] = { v0, v1 };
+ memcpy(buffer, v, 2 * sizeof(float));
+}
+
+void GrUniformDataManager::set2fv(UniformHandle u,
+ int arrayCount,
+ const float v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const float* curVec = &v[2 * i];
+ memcpy(buffer, curVec, 2 * sizeof(float));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(float);
+ }
+}
+
+void GrUniformDataManager::set3i(UniformHandle u,
+ int32_t i0,
+ int32_t i1,
+ int32_t i2) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ int32_t v[3] = { i0, i1, i2 };
+ memcpy(buffer, v, 3 * sizeof(int32_t));
+}
+
+void GrUniformDataManager::set3iv(UniformHandle u,
+ int arrayCount,
+ const int32_t v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(int32_t) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const int32_t* curVec = &v[3 * i];
+ memcpy(buffer, curVec, 3 * sizeof(int32_t));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
+ }
+}
+
+void GrUniformDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ float v[3] = { v0, v1, v2 };
+ memcpy(buffer, v, 3 * sizeof(float));
+}
+
+void GrUniformDataManager::set3fv(UniformHandle u,
+ int arrayCount,
+ const float v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const float* curVec = &v[3 * i];
+ memcpy(buffer, curVec, 3 * sizeof(float));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(float);
+ }
+}
+
+void GrUniformDataManager::set4i(UniformHandle u,
+ int32_t i0,
+ int32_t i1,
+ int32_t i2,
+ int32_t i3) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ int32_t v[4] = { i0, i1, i2, i3 };
+ memcpy(buffer, v, 4 * sizeof(int32_t));
+}
+
+void GrUniformDataManager::set4iv(UniformHandle u,
+ int arrayCount,
+ const int32_t v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(int32_t) == 4);
+ for (int i = 0; i < arrayCount; ++i) {
+ const int32_t* curVec = &v[4 * i];
+ memcpy(buffer, curVec, 4 * sizeof(int32_t));
+ buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
+ }
+}
+
+void GrUniformDataManager::set4f(UniformHandle u,
+ float v0,
+ float v1,
+ float v2,
+ float v3) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
+ SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ float v[4] = { v0, v1, v2, v3 };
+ memcpy(buffer, v, 4 * sizeof(float));
+}
+
+void GrUniformDataManager::set4fv(UniformHandle u,
+ int arrayCount,
+ const float v[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = this->getBufferPtrAndMarkDirty(uni);
+ SkASSERT(sizeof(float) == 4);
+ memcpy(buffer, v, arrayCount * 4 * sizeof(float));
+}
+
+void GrUniformDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
+ this->setMatrices<2>(u, 1, matrix);
+}
+
+void GrUniformDataManager::setMatrix2fv(UniformHandle u,
+ int arrayCount,
+ const float m[]) const {
+ this->setMatrices<2>(u, arrayCount, m);
+}
+
+void GrUniformDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
+ this->setMatrices<3>(u, 1, matrix);
+}
+
+void GrUniformDataManager::setMatrix3fv(UniformHandle u,
+ int arrayCount,
+ const float m[]) const {
+ this->setMatrices<3>(u, arrayCount, m);
+}
+
+void GrUniformDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
+ this->setMatrices<4>(u, 1, matrix);
+}
+
+void GrUniformDataManager::setMatrix4fv(UniformHandle u,
+ int arrayCount,
+ const float m[]) const {
+ this->setMatrices<4>(u, arrayCount, m);
+}
+
+template<int N> struct set_uniform_matrix;
+
+template<int N> inline void GrUniformDataManager::setMatrices(UniformHandle u,
+ int arrayCount,
+ const float matrices[]) const {
+ const Uniform& uni = fUniforms[u.toIndex()];
+ SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
+ uni.fType == kHalf2x2_GrSLType + (N - 2));
+ SkASSERT(arrayCount > 0);
+ SkASSERT(arrayCount <= uni.fArrayCount ||
+ (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
+
+ void* buffer = fUniformData.get();
+ fUniformsDirty = true;
+
+ set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
+}
+
+template<int N> struct set_uniform_matrix {
+ inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
+ static_assert(sizeof(float) == 4);
+ buffer = static_cast<char*>(buffer) + uniformOffset;
+ for (int i = 0; i < count; ++i) {
+ const float* matrix = &matrices[N * N * i];
+ for (int j = 0; j < N; ++j) {
+ memcpy(buffer, &matrix[j * N], N * sizeof(float));
+ buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
+ }
+ }
+ }
+};
+
+template<> struct set_uniform_matrix<4> {
+ inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
+ static_assert(sizeof(float) == 4);
+ buffer = static_cast<char*>(buffer) + uniformOffset;
+ memcpy(buffer, matrices, count * 16 * sizeof(float));
+ }
+};
+
diff --git a/src/gpu/GrUniformDataManager.h b/src/gpu/GrUniformDataManager.h
new file mode 100644
index 0000000..d36e69a
--- /dev/null
+++ b/src/gpu/GrUniformDataManager.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrUniformDataManager_DEFINED
+#define GrUniformDataManager_DEFINED
+
+#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
+
+#include "include/private/GrTypesPriv.h"
+#include "include/private/SkTArray.h"
+#include "src/core/SkAutoMalloc.h"
+
+class GrUniformDataManager : public GrGLSLProgramDataManager {
+public:
+ GrUniformDataManager(uint32_t uniformCount, uint32_t uniformSize);
+
+ void set1i(UniformHandle, int32_t) const override;
+ void set1iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
+ void set1f(UniformHandle, float v0) const override;
+ void set1fv(UniformHandle, int arrayCount, const float v[]) const override;
+ void set2i(UniformHandle, int32_t, int32_t) const override;
+ void set2iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
+ void set2f(UniformHandle, float, float) const override;
+ void set2fv(UniformHandle, int arrayCount, const float v[]) const override;
+ void set3i(UniformHandle, int32_t, int32_t, int32_t) const override;
+ void set3iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
+ void set3f(UniformHandle, float, float, float) const override;
+ void set3fv(UniformHandle, int arrayCount, const float v[]) const override;
+ void set4i(UniformHandle, int32_t, int32_t, int32_t, int32_t) const override;
+ void set4iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
+ void set4f(UniformHandle, float, float, float, float) const override;
+ void set4fv(UniformHandle, int arrayCount, const float v[]) const override;
+ // matrices are column-major, the first two upload a single matrix, the latter two upload
+ // arrayCount matrices into a uniform array.
+ void setMatrix2f(UniformHandle, const float matrix[]) const override;
+ void setMatrix3f(UniformHandle, const float matrix[]) const override;
+ void setMatrix4f(UniformHandle, const float matrix[]) const override;
+ void setMatrix2fv(UniformHandle, int arrayCount, const float matrices[]) const override;
+ void setMatrix3fv(UniformHandle, int arrayCount, const float matrices[]) const override;
+ void setMatrix4fv(UniformHandle, int arrayCount, const float matrices[]) const override;
+
+ // for nvpr only
+ void setPathFragmentInputTransform(VaryingHandle u, int components,
+ const SkMatrix& matrix) const override {
+ SK_ABORT("Only supported in NVPR, which is only available in GL");
+ }
+
+protected:
+ struct Uniform {
+ uint32_t fOffset;
+ SkDEBUGCODE(
+ GrSLType fType;
+ int fArrayCount;
+ );
+ };
+
+ template<int N> inline void setMatrices(UniformHandle, int arrayCount,
+ const float matrices[]) const;
+
+ void* getBufferPtrAndMarkDirty(const Uniform& uni) const;
+
+ uint32_t fUniformSize;
+
+ SkTArray<Uniform, true> fUniforms;
+
+ mutable SkAutoMalloc fUniformData;
+ mutable bool fUniformsDirty;
+};
+
+#endif
diff --git a/src/gpu/d3d/GrD3DOpsRenderPass.cpp b/src/gpu/d3d/GrD3DOpsRenderPass.cpp
index bd681f9..689a11c 100644
--- a/src/gpu/d3d/GrD3DOpsRenderPass.cpp
+++ b/src/gpu/d3d/GrD3DOpsRenderPass.cpp
@@ -145,6 +145,7 @@
return false;
}
+ pipelineState->setData(fRenderTarget, info);
fGpu->currentCommandList()->setPipelineState(std::move(pipelineState));
set_stencil_ref(fGpu, info);
diff --git a/src/gpu/d3d/GrD3DPipelineState.cpp b/src/gpu/d3d/GrD3DPipelineState.cpp
index 2135176..073a7a0 100644
--- a/src/gpu/d3d/GrD3DPipelineState.cpp
+++ b/src/gpu/d3d/GrD3DPipelineState.cpp
@@ -12,391 +12,66 @@
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
+#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
+#include "src/gpu/glsl/GrGLSLXferProcessor.h"
-static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) {
- switch (type) {
- case kFloat_GrVertexAttribType:
- return DXGI_FORMAT_R32_FLOAT;
- case kFloat2_GrVertexAttribType:
- return DXGI_FORMAT_R32G32_FLOAT;
- case kFloat3_GrVertexAttribType:
- return DXGI_FORMAT_R32G32B32_FLOAT;
- case kFloat4_GrVertexAttribType:
- return DXGI_FORMAT_R32G32B32A32_FLOAT;
- case kHalf_GrVertexAttribType:
- return DXGI_FORMAT_R16_FLOAT;
- case kHalf2_GrVertexAttribType:
- return DXGI_FORMAT_R16G16_FLOAT;
- case kHalf4_GrVertexAttribType:
- return DXGI_FORMAT_R16G16B16A16_FLOAT;
- case kInt2_GrVertexAttribType:
- return DXGI_FORMAT_R32G32_SINT;
- case kInt3_GrVertexAttribType:
- return DXGI_FORMAT_R32G32B32_SINT;
- case kInt4_GrVertexAttribType:
- return DXGI_FORMAT_R32G32B32A32_SINT;
- case kByte_GrVertexAttribType:
- return DXGI_FORMAT_R8_SINT;
- case kByte2_GrVertexAttribType:
- return DXGI_FORMAT_R8G8_SINT;
- case kByte4_GrVertexAttribType:
- return DXGI_FORMAT_R8G8B8A8_SINT;
- case kUByte_GrVertexAttribType:
- return DXGI_FORMAT_R8_UINT;
- case kUByte2_GrVertexAttribType:
- return DXGI_FORMAT_R8G8_UINT;
- case kUByte4_GrVertexAttribType:
- return DXGI_FORMAT_R8G8B8A8_UINT;
- case kUByte_norm_GrVertexAttribType:
- return DXGI_FORMAT_R8_UNORM;
- case kUByte4_norm_GrVertexAttribType:
- return DXGI_FORMAT_R8G8B8A8_UNORM;
- case kShort2_GrVertexAttribType:
- return DXGI_FORMAT_R16G16_SINT;
- case kShort4_GrVertexAttribType:
- return DXGI_FORMAT_R16G16B16A16_SINT;
- case kUShort2_GrVertexAttribType:
- return DXGI_FORMAT_R16G16_UINT;
- case kUShort2_norm_GrVertexAttribType:
- return DXGI_FORMAT_R16G16_UNORM;
- case kInt_GrVertexAttribType:
- return DXGI_FORMAT_R32_SINT;
- case kUint_GrVertexAttribType:
- return DXGI_FORMAT_R32_UINT;
- case kUShort_norm_GrVertexAttribType:
- return DXGI_FORMAT_R16_UNORM;
- case kUShort4_norm_GrVertexAttribType:
- return DXGI_FORMAT_R16G16B16A16_UNORM;
+GrD3DPipelineState::GrD3DPipelineState(
+ gr_cp<ID3D12PipelineState> pipelineState,
+ const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
+ const UniformInfoArray& uniforms, uint32_t uniformSize,
+ std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
+ std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
+ std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragmentProcessors,
+ int fragmentProcessorCnt)
+ : fPipelineState(std::move(pipelineState))
+ , fBuiltinUniformHandles(builtinUniformHandles)
+ , fGeometryProcessor(std::move(geometryProcessor))
+ , fXferProcessor(std::move(xferProcessor))
+ , fFragmentProcessors(std::move(fragmentProcessors))
+ , fFragmentProcessorCnt(fragmentProcessorCnt)
+ , fDataManager(uniforms, uniformSize) {}
+
+void GrD3DPipelineState::setData(const GrRenderTarget* renderTarget,
+ const GrProgramInfo& programInfo) {
+ this->setRenderTargetState(renderTarget, programInfo.origin());
+
+ GrFragmentProcessor::PipelineCoordTransformRange transformRange(programInfo.pipeline());
+ fGeometryProcessor->setData(fDataManager, programInfo.primProc(), transformRange);
+ GrFragmentProcessor::CIter fpIter(programInfo.pipeline());
+ GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.get(), fFragmentProcessorCnt);
+ for (; fpIter && glslIter; ++fpIter, ++glslIter) {
+ glslIter->setData(fDataManager, *fpIter);
}
- SK_ABORT("Unknown vertex attrib type");
-}
+ SkASSERT(!fpIter && !glslIter);
-static void setup_vertex_input_layout(const GrPrimitiveProcessor& primProc,
- D3D12_INPUT_ELEMENT_DESC* inputElements) {
- unsigned int slotNumber = 0;
- unsigned int vertexSlot = 0;
- unsigned int instanceSlot = 0;
- if (primProc.hasVertexAttributes()) {
- vertexSlot = slotNumber++;
- }
- if (primProc.hasInstanceAttributes()) {
- instanceSlot = slotNumber++;
- }
+ {
+ SkIPoint offset;
+ GrTexture* dstTexture = programInfo.pipeline().peekDstTexture(&offset);
- unsigned int currentAttrib = 0;
- unsigned int vertexAttributeOffset = 0;
-
- for (const auto& attrib : primProc.vertexAttributes()) {
- // When using SPIRV-Cross it converts the location modifier in SPIRV to be
- // TEXCOORD<N> where N is the location value for eveery vertext attribute
- inputElements[currentAttrib] = {"TEXCOORD", currentAttrib,
- attrib_type_to_format(attrib.cpuType()),
- vertexSlot, vertexAttributeOffset,
- D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0};
- vertexAttributeOffset += attrib.sizeAlign4();
- currentAttrib++;
- }
- SkASSERT(vertexAttributeOffset == primProc.vertexStride());
-
- unsigned int instanceAttributeOffset = 0;
- for (const auto& attrib : primProc.instanceAttributes()) {
- // When using SPIRV-Cross it converts the location modifier in SPIRV to be
- // TEXCOORD<N> where N is the location value for eveery vertext attribute
- inputElements[currentAttrib] = {"TEXCOORD", currentAttrib,
- attrib_type_to_format(attrib.cpuType()),
- instanceSlot, instanceAttributeOffset,
- D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0};
- instanceAttributeOffset += attrib.sizeAlign4();
- currentAttrib++;
- }
- SkASSERT(instanceAttributeOffset == primProc.instanceStride());
-}
-
-static D3D12_BLEND blend_coeff_to_d3d_blend(GrBlendCoeff coeff) {
- switch (coeff) {
- case kZero_GrBlendCoeff:
- return D3D12_BLEND_ZERO;
- case kOne_GrBlendCoeff:
- return D3D12_BLEND_ONE;
- case kSC_GrBlendCoeff:
- return D3D12_BLEND_SRC_COLOR;
- case kISC_GrBlendCoeff:
- return D3D12_BLEND_INV_SRC_COLOR;
- case kDC_GrBlendCoeff:
- return D3D12_BLEND_DEST_COLOR;
- case kIDC_GrBlendCoeff:
- return D3D12_BLEND_INV_DEST_COLOR;
- case kSA_GrBlendCoeff:
- return D3D12_BLEND_SRC_ALPHA;
- case kISA_GrBlendCoeff:
- return D3D12_BLEND_INV_SRC_ALPHA;
- case kDA_GrBlendCoeff:
- return D3D12_BLEND_DEST_ALPHA;
- case kIDA_GrBlendCoeff:
- return D3D12_BLEND_INV_DEST_ALPHA;
- case kConstC_GrBlendCoeff:
- return D3D12_BLEND_BLEND_FACTOR;
- case kIConstC_GrBlendCoeff:
- return D3D12_BLEND_INV_BLEND_FACTOR;
- case kS2C_GrBlendCoeff:
- return D3D12_BLEND_SRC1_COLOR;
- case kIS2C_GrBlendCoeff:
- return D3D12_BLEND_INV_SRC1_COLOR;
- case kS2A_GrBlendCoeff:
- return D3D12_BLEND_SRC1_ALPHA;
- case kIS2A_GrBlendCoeff:
- return D3D12_BLEND_INV_SRC1_ALPHA;
- case kIllegal_GrBlendCoeff:
- return D3D12_BLEND_ZERO;
- }
- SkUNREACHABLE;
-}
-
-static D3D12_BLEND blend_coeff_to_d3d_blend_for_alpha(GrBlendCoeff coeff) {
- switch (coeff) {
- // Force all srcColor used in alpha slot to alpha version.
- case kSC_GrBlendCoeff:
- return D3D12_BLEND_SRC_ALPHA;
- case kISC_GrBlendCoeff:
- return D3D12_BLEND_INV_SRC_ALPHA;
- case kDC_GrBlendCoeff:
- return D3D12_BLEND_DEST_ALPHA;
- case kIDC_GrBlendCoeff:
- return D3D12_BLEND_INV_DEST_ALPHA;
- case kS2C_GrBlendCoeff:
- return D3D12_BLEND_SRC1_ALPHA;
- case kIS2C_GrBlendCoeff:
- return D3D12_BLEND_INV_SRC1_ALPHA;
-
- default:
- return blend_coeff_to_d3d_blend(coeff);
+ fXferProcessor->setData(fDataManager, programInfo.pipeline().getXferProcessor(),
+ dstTexture, offset);
}
}
+void GrD3DPipelineState::setRenderTargetState(const GrRenderTarget* rt, GrSurfaceOrigin origin) {
-static D3D12_BLEND_OP blend_equation_to_d3d_op(GrBlendEquation equation) {
- switch (equation) {
- case kAdd_GrBlendEquation:
- return D3D12_BLEND_OP_ADD;
- case kSubtract_GrBlendEquation:
- return D3D12_BLEND_OP_SUBTRACT;
- case kReverseSubtract_GrBlendEquation:
- return D3D12_BLEND_OP_REV_SUBTRACT;
- default:
- SkUNREACHABLE;
- }
-}
-
-static void fill_in_blend_state(const GrPipeline& pipeline, D3D12_BLEND_DESC* blendDesc) {
- blendDesc->AlphaToCoverageEnable = false;
- blendDesc->IndependentBlendEnable = false;
-
- const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
-
- GrBlendEquation equation = blendInfo.fEquation;
- GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
- GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
- bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff);
-
- auto& rtBlend = blendDesc->RenderTarget[0];
- rtBlend.BlendEnable = !blendOff;
- if (!blendOff) {
- rtBlend.SrcBlend = blend_coeff_to_d3d_blend(srcCoeff);
- rtBlend.DestBlend = blend_coeff_to_d3d_blend(dstCoeff);
- rtBlend.BlendOp = blend_equation_to_d3d_op(equation);
- rtBlend.SrcBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(srcCoeff);
- rtBlend.DestBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(dstCoeff);
- rtBlend.BlendOpAlpha = blend_equation_to_d3d_op(equation);
+ // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
+ if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
+ fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
+ fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
}
- if (!blendInfo.fWriteColor) {
- rtBlend.RenderTargetWriteMask = 0;
- } else {
- rtBlend.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
+ // set RT adjustment
+ SkISize dimensions = rt->dimensions();
+ SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
+ if (fRenderTargetState.fRenderTargetOrigin != origin ||
+ fRenderTargetState.fRenderTargetSize != dimensions) {
+ fRenderTargetState.fRenderTargetSize = dimensions;
+ fRenderTargetState.fRenderTargetOrigin = origin;
+
+ float rtAdjustmentVec[4];
+ fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
+ fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
}
}
-
-static void fill_in_rasterizer_state(const GrPipeline& pipeline, const GrCaps* caps,
- D3D12_RASTERIZER_DESC* rasterizer) {
- rasterizer->FillMode = (caps->wireframeMode() || pipeline.isWireframe()) ?
- D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID;
- rasterizer->CullMode = D3D12_CULL_MODE_NONE;
- rasterizer->FrontCounterClockwise = true;
- rasterizer->DepthBias = 0;
- rasterizer->DepthBiasClamp = 0.0f;
- rasterizer->SlopeScaledDepthBias = 0.0f;
- rasterizer->DepthClipEnable = false;
- rasterizer->MultisampleEnable = pipeline.isHWAntialiasState();
- rasterizer->AntialiasedLineEnable = false;
- rasterizer->ForcedSampleCount = 0;
- rasterizer->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
-}
-
-static D3D12_STENCIL_OP stencil_op_to_d3d_op(GrStencilOp op) {
- switch (op) {
- case GrStencilOp::kKeep:
- return D3D12_STENCIL_OP_KEEP;
- case GrStencilOp::kZero:
- return D3D12_STENCIL_OP_ZERO;
- case GrStencilOp::kReplace:
- return D3D12_STENCIL_OP_REPLACE;
- case GrStencilOp::kInvert:
- return D3D12_STENCIL_OP_INVERT;
- case GrStencilOp::kIncWrap:
- return D3D12_STENCIL_OP_INCR;
- case GrStencilOp::kDecWrap:
- return D3D12_STENCIL_OP_DECR;
- case GrStencilOp::kIncClamp:
- return D3D12_STENCIL_OP_INCR_SAT;
- case GrStencilOp::kDecClamp:
- return D3D12_STENCIL_OP_DECR_SAT;
- }
- SkUNREACHABLE;
-}
-
-static D3D12_COMPARISON_FUNC stencil_test_to_d3d_func(GrStencilTest test) {
- switch (test) {
- case GrStencilTest::kAlways:
- return D3D12_COMPARISON_FUNC_ALWAYS;
- case GrStencilTest::kNever:
- return D3D12_COMPARISON_FUNC_NEVER;
- case GrStencilTest::kGreater:
- return D3D12_COMPARISON_FUNC_GREATER;
- case GrStencilTest::kGEqual:
- return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
- case GrStencilTest::kLess:
- return D3D12_COMPARISON_FUNC_LESS;
- case GrStencilTest::kLEqual:
- return D3D12_COMPARISON_FUNC_LESS_EQUAL;
- case GrStencilTest::kEqual:
- return D3D12_COMPARISON_FUNC_EQUAL;
- case GrStencilTest::kNotEqual:
- return D3D12_COMPARISON_FUNC_NOT_EQUAL;
- }
- SkUNREACHABLE;
-}
-
-static void setup_stencilop_desc(D3D12_DEPTH_STENCILOP_DESC* desc,
- const GrStencilSettings::Face& stencilFace) {
- desc->StencilFailOp = stencil_op_to_d3d_op(stencilFace.fFailOp);
- desc->StencilDepthFailOp = desc->StencilFailOp;
- desc->StencilPassOp = stencil_op_to_d3d_op(stencilFace.fPassOp);
- desc->StencilFunc = stencil_test_to_d3d_func(stencilFace.fTest);
-}
-
-static void fill_in_depth_stencil_state(const GrProgramInfo& programInfo,
- D3D12_DEPTH_STENCIL_DESC* dsDesc) {
- GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
- GrSurfaceOrigin origin = programInfo.origin();
-
- dsDesc->DepthEnable = false;
- dsDesc->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
- dsDesc->DepthFunc = D3D12_COMPARISON_FUNC_NEVER;
- dsDesc->StencilEnable = !stencilSettings.isDisabled();
- if (!stencilSettings.isDisabled()) {
- if (stencilSettings.isTwoSided()) {
- const auto& frontFace = stencilSettings.postOriginCCWFace(origin);
- const auto& backFace = stencilSettings.postOriginCCWFace(origin);
-
- SkASSERT(frontFace.fTestMask == backFace.fTestMask);
- SkASSERT(frontFace.fWriteMask == backFace.fWriteMask);
- dsDesc->StencilReadMask = frontFace.fTestMask;
- dsDesc->StencilWriteMask = frontFace.fWriteMask;
-
- setup_stencilop_desc(&dsDesc->FrontFace, frontFace);
- setup_stencilop_desc(&dsDesc->BackFace, backFace);
- } else {
- dsDesc->StencilReadMask = stencilSettings.singleSidedFace().fTestMask;
- dsDesc->StencilWriteMask = stencilSettings.singleSidedFace().fTestMask;
- setup_stencilop_desc(&dsDesc->FrontFace, stencilSettings.singleSidedFace());
- dsDesc->BackFace = dsDesc->FrontFace;
- }
- }
-}
-
-static D3D12_PRIMITIVE_TOPOLOGY_TYPE gr_primitive_type_to_d3d(GrPrimitiveType primitiveType) {
- switch (primitiveType) {
- case GrPrimitiveType::kTriangles:
- case GrPrimitiveType::kTriangleStrip: //fall through
- return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
- case GrPrimitiveType::kPoints:
- return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
- case GrPrimitiveType::kLines: // fall through
- case GrPrimitiveType::kLineStrip:
- return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
- case GrPrimitiveType::kPatches: // fall through, unsupported
- case GrPrimitiveType::kPath: // fall through, unsupported
- default:
- SkUNREACHABLE;
- }
-}
-
-sk_sp<GrD3DPipelineState> GrD3DPipelineState::Make(GrD3DGpu* gpu,
- const GrProgramInfo& programInfo,
- sk_sp<GrD3DRootSignature> rootSig,
- gr_cp<ID3DBlob> vertexShader,
- gr_cp<ID3DBlob> geometryShader,
- gr_cp<ID3DBlob> pixelShader,
- DXGI_FORMAT renderTargetFormat,
- DXGI_FORMAT depthStencilFormat,
- unsigned int sampleQualityLevel) {
- D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
-
- psoDesc.pRootSignature = rootSig->rootSignature();
-
- psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()),
- vertexShader->GetBufferSize() };
- psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()),
- pixelShader->GetBufferSize() };
-
- if (geometryShader.get()) {
- psoDesc.GS = { reinterpret_cast<UINT8*>(geometryShader->GetBufferPointer()),
- geometryShader->GetBufferSize() };
- }
-
- psoDesc.StreamOutput = {nullptr, 0, nullptr, 0, 0};
-
- fill_in_blend_state(programInfo.pipeline(), &psoDesc.BlendState);
- psoDesc.SampleMask = UINT_MAX;
-
- fill_in_rasterizer_state(programInfo.pipeline(), gpu->caps(), &psoDesc.RasterizerState);
-
- fill_in_depth_stencil_state(programInfo, &psoDesc.DepthStencilState);
-
- unsigned int totalAttributeCnt = programInfo.primProc().numVertexAttributes() +
- programInfo.primProc().numInstanceAttributes();
- SkAutoSTArray<4, D3D12_INPUT_ELEMENT_DESC> inputElements(totalAttributeCnt);
- setup_vertex_input_layout(programInfo.primProc(), inputElements.get());
-
- psoDesc.InputLayout = { inputElements.get(), totalAttributeCnt };
-
- psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
-
- // This is for geometry or hull shader primitives
- psoDesc.PrimitiveTopologyType = gr_primitive_type_to_d3d(programInfo.primitiveType());
-
- psoDesc.NumRenderTargets = 1;
-
- psoDesc.RTVFormats[0] = renderTargetFormat;
-
- psoDesc.DSVFormat = depthStencilFormat;
-
- unsigned int numRasterSamples = programInfo.numRasterSamples();
- psoDesc.SampleDesc = {numRasterSamples, sampleQualityLevel};
-
- // Only used for multi-adapter systems.
- psoDesc.NodeMask = 0;
-
- psoDesc.CachedPSO = {nullptr, 0};
- psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
-
- gr_cp<ID3D12PipelineState> pipelineState;
- SkDEBUGCODE(HRESULT hr = )gpu->device()->CreateGraphicsPipelineState(
- &psoDesc, IID_PPV_ARGS(&pipelineState));
- SkASSERT(SUCCEEDED(hr));
-
- return sk_sp<GrD3DPipelineState>(new GrD3DPipelineState(std::move(pipelineState)));
-}
-
-GrD3DPipelineState::GrD3DPipelineState(gr_cp<ID3D12PipelineState> pipelineState)
- : fPipelineState(std::move(pipelineState)) {}
diff --git a/src/gpu/d3d/GrD3DPipelineState.h b/src/gpu/d3d/GrD3DPipelineState.h
index b6eb50a..e8c6c45 100644
--- a/src/gpu/d3d/GrD3DPipelineState.h
+++ b/src/gpu/d3d/GrD3DPipelineState.h
@@ -12,6 +12,8 @@
#include "include/gpu/GrTypes.h"
#include "include/gpu/d3d/GrD3DTypes.h"
#include "src/gpu/GrManagedResource.h"
+#include "src/gpu/d3d/GrD3DPipelineStateDataManager.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
class GrD3DGpu;
class GrD3DRootSignature;
@@ -19,14 +21,16 @@
class GrD3DPipelineState : public GrManagedResource {
public:
- static sk_sp<GrD3DPipelineState> Make(GrD3DGpu* gpu, const GrProgramInfo&,
- sk_sp<GrD3DRootSignature> rootSig,
- gr_cp<ID3DBlob> vertexShader,
- gr_cp<ID3DBlob> geometryShader,
- gr_cp<ID3DBlob> pixelShader,
- DXGI_FORMAT renderTargetFormat,
- DXGI_FORMAT depthStencilFormat,
- unsigned int sampleQualityLevel);
+ using UniformInfoArray = GrD3DPipelineStateDataManager::UniformInfoArray;
+
+ GrD3DPipelineState(gr_cp<ID3D12PipelineState> pipelineState,
+ const GrGLSLBuiltinUniformHandles& builtinUniformHandles,
+ const UniformInfoArray& uniforms,
+ uint32_t uniformSize,
+ std::unique_ptr<GrGLSLPrimitiveProcessor> geometryProcessor,
+ std::unique_ptr<GrGLSLXferProcessor> xferProcessor,
+ std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fragProcessors,
+ int fragmentProcessorCnt);
#ifdef SK_TRACE_MANAGED_RESOURCES
/** Output a human-readable dump of this resource's information
@@ -42,11 +46,61 @@
ID3D12PipelineState* pipelineState() const { return fPipelineState.get(); }
+ void setData(const GrRenderTarget* renderTarget, const GrProgramInfo& programInfo);
+
private:
- GrD3DPipelineState(gr_cp<ID3D12PipelineState> pipelineState);
+ /**
+ * We use the RT's size and origin to adjust from Skia device space to d3d normalized device
+ * space and to make device space positions have the correct origin for processors that require
+ * them.
+ */
+ struct RenderTargetState {
+ SkISize fRenderTargetSize;
+ GrSurfaceOrigin fRenderTargetOrigin;
+
+ RenderTargetState() { this->invalidate(); }
+ void invalidate() {
+ fRenderTargetSize.fWidth = -1;
+ fRenderTargetSize.fHeight = -1;
+ fRenderTargetOrigin = (GrSurfaceOrigin)-1;
+ }
+
+ /**
+ * Gets a float4 that adjusts the position from Skia device coords to D3D's normalized device
+ * coords. Assuming the transformed position, pos, is a homogeneous float3, the vec, v, is
+ * applied as such:
+ * pos.x = dot(v.xy, pos.xz)
+ * pos.y = dot(v.zw, pos.yz)
+ */
+ void getRTAdjustmentVec(float* destVec) {
+ destVec[0] = 2.f / fRenderTargetSize.fWidth;
+ destVec[1] = -1.f;
+ if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
+ destVec[2] = -2.f / fRenderTargetSize.fHeight;
+ destVec[3] = 1.f;
+ } else {
+ destVec[2] = 2.f / fRenderTargetSize.fHeight;
+ destVec[3] = -1.f;
+ }
+ }
+ };
+
+ // Helper for setData() that sets the view matrix and loads the render target height uniform
+ void setRenderTargetState(const GrRenderTarget*, GrSurfaceOrigin);
gr_cp<ID3D12PipelineState> fPipelineState;
+ // Tracks the current render target uniforms stored in the vertex buffer.
+ RenderTargetState fRenderTargetState;
+ GrGLSLBuiltinUniformHandles fBuiltinUniformHandles;
+
+ // Processors in the GrD3DPipelineState
+ std::unique_ptr<GrGLSLPrimitiveProcessor> fGeometryProcessor;
+ std::unique_ptr<GrGLSLXferProcessor> fXferProcessor;
+ std::unique_ptr<std::unique_ptr<GrGLSLFragmentProcessor>[]> fFragmentProcessors;
+ int fFragmentProcessorCnt;
+
+ GrD3DPipelineStateDataManager fDataManager;
};
#endif
diff --git a/src/gpu/d3d/GrD3DPipelineStateBuilder.cpp b/src/gpu/d3d/GrD3DPipelineStateBuilder.cpp
index f03858e..4e60fe4 100644
--- a/src/gpu/d3d/GrD3DPipelineStateBuilder.cpp
+++ b/src/gpu/d3d/GrD3DPipelineStateBuilder.cpp
@@ -120,6 +120,387 @@
}
}
+static DXGI_FORMAT attrib_type_to_format(GrVertexAttribType type) {
+ switch (type) {
+ case kFloat_GrVertexAttribType:
+ return DXGI_FORMAT_R32_FLOAT;
+ case kFloat2_GrVertexAttribType:
+ return DXGI_FORMAT_R32G32_FLOAT;
+ case kFloat3_GrVertexAttribType:
+ return DXGI_FORMAT_R32G32B32_FLOAT;
+ case kFloat4_GrVertexAttribType:
+ return DXGI_FORMAT_R32G32B32A32_FLOAT;
+ case kHalf_GrVertexAttribType:
+ return DXGI_FORMAT_R16_FLOAT;
+ case kHalf2_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16_FLOAT;
+ case kHalf4_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16B16A16_FLOAT;
+ case kInt2_GrVertexAttribType:
+ return DXGI_FORMAT_R32G32_SINT;
+ case kInt3_GrVertexAttribType:
+ return DXGI_FORMAT_R32G32B32_SINT;
+ case kInt4_GrVertexAttribType:
+ return DXGI_FORMAT_R32G32B32A32_SINT;
+ case kByte_GrVertexAttribType:
+ return DXGI_FORMAT_R8_SINT;
+ case kByte2_GrVertexAttribType:
+ return DXGI_FORMAT_R8G8_SINT;
+ case kByte4_GrVertexAttribType:
+ return DXGI_FORMAT_R8G8B8A8_SINT;
+ case kUByte_GrVertexAttribType:
+ return DXGI_FORMAT_R8_UINT;
+ case kUByte2_GrVertexAttribType:
+ return DXGI_FORMAT_R8G8_UINT;
+ case kUByte4_GrVertexAttribType:
+ return DXGI_FORMAT_R8G8B8A8_UINT;
+ case kUByte_norm_GrVertexAttribType:
+ return DXGI_FORMAT_R8_UNORM;
+ case kUByte4_norm_GrVertexAttribType:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case kShort2_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16_SINT;
+ case kShort4_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16B16A16_SINT;
+ case kUShort2_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16_UINT;
+ case kUShort2_norm_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16_UNORM;
+ case kInt_GrVertexAttribType:
+ return DXGI_FORMAT_R32_SINT;
+ case kUint_GrVertexAttribType:
+ return DXGI_FORMAT_R32_UINT;
+ case kUShort_norm_GrVertexAttribType:
+ return DXGI_FORMAT_R16_UNORM;
+ case kUShort4_norm_GrVertexAttribType:
+ return DXGI_FORMAT_R16G16B16A16_UNORM;
+ }
+ SK_ABORT("Unknown vertex attrib type");
+}
+
+static void setup_vertex_input_layout(const GrPrimitiveProcessor& primProc,
+ D3D12_INPUT_ELEMENT_DESC* inputElements) {
+ unsigned int slotNumber = 0;
+ unsigned int vertexSlot = 0;
+ unsigned int instanceSlot = 0;
+ if (primProc.hasVertexAttributes()) {
+ vertexSlot = slotNumber++;
+ }
+ if (primProc.hasInstanceAttributes()) {
+ instanceSlot = slotNumber++;
+ }
+
+ unsigned int currentAttrib = 0;
+ unsigned int vertexAttributeOffset = 0;
+
+ for (const auto& attrib : primProc.vertexAttributes()) {
+ // When using SPIRV-Cross it converts the location modifier in SPIRV to be
+ // TEXCOORD<N> where N is the location value for eveery vertext attribute
+ inputElements[currentAttrib] = { "TEXCOORD", currentAttrib,
+ attrib_type_to_format(attrib.cpuType()),
+ vertexSlot, vertexAttributeOffset,
+ D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 };
+ vertexAttributeOffset += attrib.sizeAlign4();
+ currentAttrib++;
+ }
+ SkASSERT(vertexAttributeOffset == primProc.vertexStride());
+
+ unsigned int instanceAttributeOffset = 0;
+ for (const auto& attrib : primProc.instanceAttributes()) {
+ // When using SPIRV-Cross it converts the location modifier in SPIRV to be
+ // TEXCOORD<N> where N is the location value for eveery vertext attribute
+ inputElements[currentAttrib] = { "TEXCOORD", currentAttrib,
+ attrib_type_to_format(attrib.cpuType()),
+ instanceSlot, instanceAttributeOffset,
+ D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 };
+ instanceAttributeOffset += attrib.sizeAlign4();
+ currentAttrib++;
+ }
+ SkASSERT(instanceAttributeOffset == primProc.instanceStride());
+}
+
+static D3D12_BLEND blend_coeff_to_d3d_blend(GrBlendCoeff coeff) {
+ switch (coeff) {
+ case kZero_GrBlendCoeff:
+ return D3D12_BLEND_ZERO;
+ case kOne_GrBlendCoeff:
+ return D3D12_BLEND_ONE;
+ case kSC_GrBlendCoeff:
+ return D3D12_BLEND_SRC_COLOR;
+ case kISC_GrBlendCoeff:
+ return D3D12_BLEND_INV_SRC_COLOR;
+ case kDC_GrBlendCoeff:
+ return D3D12_BLEND_DEST_COLOR;
+ case kIDC_GrBlendCoeff:
+ return D3D12_BLEND_INV_DEST_COLOR;
+ case kSA_GrBlendCoeff:
+ return D3D12_BLEND_SRC_ALPHA;
+ case kISA_GrBlendCoeff:
+ return D3D12_BLEND_INV_SRC_ALPHA;
+ case kDA_GrBlendCoeff:
+ return D3D12_BLEND_DEST_ALPHA;
+ case kIDA_GrBlendCoeff:
+ return D3D12_BLEND_INV_DEST_ALPHA;
+ case kConstC_GrBlendCoeff:
+ return D3D12_BLEND_BLEND_FACTOR;
+ case kIConstC_GrBlendCoeff:
+ return D3D12_BLEND_INV_BLEND_FACTOR;
+ case kS2C_GrBlendCoeff:
+ return D3D12_BLEND_SRC1_COLOR;
+ case kIS2C_GrBlendCoeff:
+ return D3D12_BLEND_INV_SRC1_COLOR;
+ case kS2A_GrBlendCoeff:
+ return D3D12_BLEND_SRC1_ALPHA;
+ case kIS2A_GrBlendCoeff:
+ return D3D12_BLEND_INV_SRC1_ALPHA;
+ case kIllegal_GrBlendCoeff:
+ return D3D12_BLEND_ZERO;
+ }
+ SkUNREACHABLE;
+}
+
+static D3D12_BLEND blend_coeff_to_d3d_blend_for_alpha(GrBlendCoeff coeff) {
+ switch (coeff) {
+ // Force all srcColor used in alpha slot to alpha version.
+ case kSC_GrBlendCoeff:
+ return D3D12_BLEND_SRC_ALPHA;
+ case kISC_GrBlendCoeff:
+ return D3D12_BLEND_INV_SRC_ALPHA;
+ case kDC_GrBlendCoeff:
+ return D3D12_BLEND_DEST_ALPHA;
+ case kIDC_GrBlendCoeff:
+ return D3D12_BLEND_INV_DEST_ALPHA;
+ case kS2C_GrBlendCoeff:
+ return D3D12_BLEND_SRC1_ALPHA;
+ case kIS2C_GrBlendCoeff:
+ return D3D12_BLEND_INV_SRC1_ALPHA;
+
+ default:
+ return blend_coeff_to_d3d_blend(coeff);
+ }
+}
+
+
+static D3D12_BLEND_OP blend_equation_to_d3d_op(GrBlendEquation equation) {
+ switch (equation) {
+ case kAdd_GrBlendEquation:
+ return D3D12_BLEND_OP_ADD;
+ case kSubtract_GrBlendEquation:
+ return D3D12_BLEND_OP_SUBTRACT;
+ case kReverseSubtract_GrBlendEquation:
+ return D3D12_BLEND_OP_REV_SUBTRACT;
+ default:
+ SkUNREACHABLE;
+ }
+}
+
+static void fill_in_blend_state(const GrPipeline& pipeline, D3D12_BLEND_DESC* blendDesc) {
+ blendDesc->AlphaToCoverageEnable = false;
+ blendDesc->IndependentBlendEnable = false;
+
+ const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
+
+ GrBlendEquation equation = blendInfo.fEquation;
+ GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
+ GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
+ bool blendOff = GrBlendShouldDisable(equation, srcCoeff, dstCoeff);
+
+ auto& rtBlend = blendDesc->RenderTarget[0];
+ rtBlend.BlendEnable = !blendOff;
+ if (!blendOff) {
+ rtBlend.SrcBlend = blend_coeff_to_d3d_blend(srcCoeff);
+ rtBlend.DestBlend = blend_coeff_to_d3d_blend(dstCoeff);
+ rtBlend.BlendOp = blend_equation_to_d3d_op(equation);
+ rtBlend.SrcBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(srcCoeff);
+ rtBlend.DestBlendAlpha = blend_coeff_to_d3d_blend_for_alpha(dstCoeff);
+ rtBlend.BlendOpAlpha = blend_equation_to_d3d_op(equation);
+ }
+
+ if (!blendInfo.fWriteColor) {
+ rtBlend.RenderTargetWriteMask = 0;
+ } else {
+ rtBlend.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
+ }
+}
+
+static void fill_in_rasterizer_state(const GrPipeline& pipeline, const GrCaps* caps,
+ D3D12_RASTERIZER_DESC* rasterizer) {
+ rasterizer->FillMode = (caps->wireframeMode() || pipeline.isWireframe()) ?
+ D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID;
+ rasterizer->CullMode = D3D12_CULL_MODE_NONE;
+ rasterizer->FrontCounterClockwise = true;
+ rasterizer->DepthBias = 0;
+ rasterizer->DepthBiasClamp = 0.0f;
+ rasterizer->SlopeScaledDepthBias = 0.0f;
+ rasterizer->DepthClipEnable = false;
+ rasterizer->MultisampleEnable = pipeline.isHWAntialiasState();
+ rasterizer->AntialiasedLineEnable = false;
+ rasterizer->ForcedSampleCount = 0;
+ rasterizer->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
+}
+
+static D3D12_STENCIL_OP stencil_op_to_d3d_op(GrStencilOp op) {
+ switch (op) {
+ case GrStencilOp::kKeep:
+ return D3D12_STENCIL_OP_KEEP;
+ case GrStencilOp::kZero:
+ return D3D12_STENCIL_OP_ZERO;
+ case GrStencilOp::kReplace:
+ return D3D12_STENCIL_OP_REPLACE;
+ case GrStencilOp::kInvert:
+ return D3D12_STENCIL_OP_INVERT;
+ case GrStencilOp::kIncWrap:
+ return D3D12_STENCIL_OP_INCR;
+ case GrStencilOp::kDecWrap:
+ return D3D12_STENCIL_OP_DECR;
+ case GrStencilOp::kIncClamp:
+ return D3D12_STENCIL_OP_INCR_SAT;
+ case GrStencilOp::kDecClamp:
+ return D3D12_STENCIL_OP_DECR_SAT;
+ }
+ SkUNREACHABLE;
+}
+
+static D3D12_COMPARISON_FUNC stencil_test_to_d3d_func(GrStencilTest test) {
+ switch (test) {
+ case GrStencilTest::kAlways:
+ return D3D12_COMPARISON_FUNC_ALWAYS;
+ case GrStencilTest::kNever:
+ return D3D12_COMPARISON_FUNC_NEVER;
+ case GrStencilTest::kGreater:
+ return D3D12_COMPARISON_FUNC_GREATER;
+ case GrStencilTest::kGEqual:
+ return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
+ case GrStencilTest::kLess:
+ return D3D12_COMPARISON_FUNC_LESS;
+ case GrStencilTest::kLEqual:
+ return D3D12_COMPARISON_FUNC_LESS_EQUAL;
+ case GrStencilTest::kEqual:
+ return D3D12_COMPARISON_FUNC_EQUAL;
+ case GrStencilTest::kNotEqual:
+ return D3D12_COMPARISON_FUNC_NOT_EQUAL;
+ }
+ SkUNREACHABLE;
+}
+
+static void setup_stencilop_desc(D3D12_DEPTH_STENCILOP_DESC* desc,
+ const GrStencilSettings::Face& stencilFace) {
+ desc->StencilFailOp = stencil_op_to_d3d_op(stencilFace.fFailOp);
+ desc->StencilDepthFailOp = desc->StencilFailOp;
+ desc->StencilPassOp = stencil_op_to_d3d_op(stencilFace.fPassOp);
+ desc->StencilFunc = stencil_test_to_d3d_func(stencilFace.fTest);
+}
+
+static void fill_in_depth_stencil_state(const GrProgramInfo& programInfo,
+ D3D12_DEPTH_STENCIL_DESC* dsDesc) {
+ GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
+ GrSurfaceOrigin origin = programInfo.origin();
+
+ dsDesc->DepthEnable = false;
+ dsDesc->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
+ dsDesc->DepthFunc = D3D12_COMPARISON_FUNC_NEVER;
+ dsDesc->StencilEnable = !stencilSettings.isDisabled();
+ if (!stencilSettings.isDisabled()) {
+ if (stencilSettings.isTwoSided()) {
+ const auto& frontFace = stencilSettings.postOriginCCWFace(origin);
+ const auto& backFace = stencilSettings.postOriginCCWFace(origin);
+
+ SkASSERT(frontFace.fTestMask == backFace.fTestMask);
+ SkASSERT(frontFace.fWriteMask == backFace.fWriteMask);
+ dsDesc->StencilReadMask = frontFace.fTestMask;
+ dsDesc->StencilWriteMask = frontFace.fWriteMask;
+
+ setup_stencilop_desc(&dsDesc->FrontFace, frontFace);
+ setup_stencilop_desc(&dsDesc->BackFace, backFace);
+ } else {
+ dsDesc->StencilReadMask = stencilSettings.singleSidedFace().fTestMask;
+ dsDesc->StencilWriteMask = stencilSettings.singleSidedFace().fTestMask;
+ setup_stencilop_desc(&dsDesc->FrontFace, stencilSettings.singleSidedFace());
+ dsDesc->BackFace = dsDesc->FrontFace;
+ }
+ }
+}
+
+static D3D12_PRIMITIVE_TOPOLOGY_TYPE gr_primitive_type_to_d3d(GrPrimitiveType primitiveType) {
+ switch (primitiveType) {
+ case GrPrimitiveType::kTriangles:
+ case GrPrimitiveType::kTriangleStrip: //fall through
+ return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ case GrPrimitiveType::kPoints:
+ return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
+ case GrPrimitiveType::kLines: // fall through
+ case GrPrimitiveType::kLineStrip:
+ return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
+ case GrPrimitiveType::kPatches: // fall through, unsupported
+ case GrPrimitiveType::kPath: // fall through, unsupported
+ default:
+ SkUNREACHABLE;
+ }
+}
+
+gr_cp<ID3D12PipelineState> create_pipeline_state(
+ GrD3DGpu* gpu, const GrProgramInfo& programInfo, sk_sp<GrD3DRootSignature> rootSig,
+ gr_cp<ID3DBlob> vertexShader, gr_cp<ID3DBlob> geometryShader, gr_cp<ID3DBlob> pixelShader,
+ DXGI_FORMAT renderTargetFormat, DXGI_FORMAT depthStencilFormat,
+ unsigned int sampleQualityLevel) {
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
+
+ psoDesc.pRootSignature = rootSig->rootSignature();
+
+ psoDesc.VS = { reinterpret_cast<UINT8*>(vertexShader->GetBufferPointer()),
+ vertexShader->GetBufferSize() };
+ psoDesc.PS = { reinterpret_cast<UINT8*>(pixelShader->GetBufferPointer()),
+ pixelShader->GetBufferSize() };
+
+ if (geometryShader.get()) {
+ psoDesc.GS = { reinterpret_cast<UINT8*>(geometryShader->GetBufferPointer()),
+ geometryShader->GetBufferSize() };
+ }
+
+ psoDesc.StreamOutput = { nullptr, 0, nullptr, 0, 0 };
+
+ fill_in_blend_state(programInfo.pipeline(), &psoDesc.BlendState);
+ psoDesc.SampleMask = UINT_MAX;
+
+ fill_in_rasterizer_state(programInfo.pipeline(), gpu->caps(), &psoDesc.RasterizerState);
+
+ fill_in_depth_stencil_state(programInfo, &psoDesc.DepthStencilState);
+
+ unsigned int totalAttributeCnt = programInfo.primProc().numVertexAttributes() +
+ programInfo.primProc().numInstanceAttributes();
+ SkAutoSTArray<4, D3D12_INPUT_ELEMENT_DESC> inputElements(totalAttributeCnt);
+ setup_vertex_input_layout(programInfo.primProc(), inputElements.get());
+
+ psoDesc.InputLayout = { inputElements.get(), totalAttributeCnt };
+
+ psoDesc.IBStripCutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
+
+ // This is for geometry or hull shader primitives
+ psoDesc.PrimitiveTopologyType = gr_primitive_type_to_d3d(programInfo.primitiveType());
+
+ psoDesc.NumRenderTargets = 1;
+
+ psoDesc.RTVFormats[0] = renderTargetFormat;
+
+ psoDesc.DSVFormat = depthStencilFormat;
+
+ unsigned int numRasterSamples = programInfo.numRasterSamples();
+ psoDesc.SampleDesc = { numRasterSamples, sampleQualityLevel };
+
+ // Only used for multi-adapter systems.
+ psoDesc.NodeMask = 0;
+
+ psoDesc.CachedPSO = { nullptr, 0 };
+ psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
+
+ gr_cp<ID3D12PipelineState> pipelineState;
+ SkDEBUGCODE(HRESULT hr = )gpu->device()->CreateGraphicsPipelineState(
+ &psoDesc, IID_PPV_ARGS(&pipelineState));
+ SkASSERT(SUCCEEDED(hr));
+
+ return pipelineState;
+}
+
sk_sp<GrD3DPipelineState> GrD3DPipelineStateBuilder::finalize() {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
@@ -170,8 +551,17 @@
}
const GrD3DRenderTarget* rt = static_cast<const GrD3DRenderTarget*>(fRenderTarget);
- return GrD3DPipelineState::Make(fGpu, fProgramInfo, std::move(rootSig),
- std::move(vertexShader), std::move(geometryShader),
- std::move(pixelShader), rt->dxgiFormat(),
- rt->stencilDxgiFormat(), rt->sampleQualityLevel());
+ gr_cp<ID3D12PipelineState> pipelineState = create_pipeline_state(
+ fGpu, fProgramInfo, std::move(rootSig), std::move(vertexShader),
+ std::move(geometryShader), std::move(pixelShader), rt->dxgiFormat(),
+ rt->stencilDxgiFormat(), rt->sampleQualityLevel());
+
+ return sk_sp<GrD3DPipelineState>(new GrD3DPipelineState(std::move(pipelineState),
+ fUniformHandles,
+ fUniformHandler.fUniforms,
+ fUniformHandler.fCurrentUBOOffset,
+ std::move(fGeometryProcessor),
+ std::move(fXferProcessor),
+ std::move(fFragmentProcessors),
+ fFragmentProcessorCnt));
}
diff --git a/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp b/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp
new file mode 100644
index 0000000..9326099
--- /dev/null
+++ b/src/gpu/d3d/GrD3DPipelineStateDataManager.cpp
@@ -0,0 +1,28 @@
+/*
+* 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 "src/gpu/d3d/GrD3DPipelineStateDataManager.h"
+
+GrD3DPipelineStateDataManager::GrD3DPipelineStateDataManager(const UniformInfoArray& uniforms,
+ uint32_t uniformSize)
+ : INHERITED(uniforms.count(), uniformSize) {
+ // We must add uniforms in same order as the UniformInfoArray so that UniformHandles already
+ // owned by other objects will still match up here.
+ int i = 0;
+ for (const auto& uniformInfo : uniforms.items()) {
+ Uniform& uniform = fUniforms[i];
+ SkASSERT(GrShaderVar::kNonArray == uniformInfo.fVariable.getArrayCount() ||
+ uniformInfo.fVariable.getArrayCount() > 0);
+ SkDEBUGCODE(
+ uniform.fArrayCount = uniformInfo.fVariable.getArrayCount();
+ uniform.fType = uniformInfo.fVariable.getType();
+ )
+
+ uniform.fOffset = uniformInfo.fUBOOffset;
+ ++i;
+ }
+}
diff --git a/src/gpu/d3d/GrD3DPipelineStateDataManager.h b/src/gpu/d3d/GrD3DPipelineStateDataManager.h
new file mode 100644
index 0000000..14d9c2e
--- /dev/null
+++ b/src/gpu/d3d/GrD3DPipelineStateDataManager.h
@@ -0,0 +1,29 @@
+/*
+* Copyright 2020 Google LLC
+*
+* Use of this source code is governed by a BSD-style license that can be
+* found in the LICENSE file.
+*/
+
+#ifndef GrD3DPipelineStateDataManager_DEFINED
+#define GrD3DPipelineStateDataManager_DEFINED
+
+#include "src/gpu/GrUniformDataManager.h"
+
+#include "include/gpu/d3d/GrD3DTypes.h"
+#include "src/gpu/GrSPIRVUniformHandler.h"
+
+class GrD3DPipelineStateDataManager : public GrUniformDataManager {
+public:
+ typedef GrSPIRVUniformHandler::UniformInfoArray UniformInfoArray;
+
+ GrD3DPipelineStateDataManager(const UniformInfoArray&,
+ uint32_t uniformSize);
+
+ // TODO: upload to uniform buffer
+
+private:
+ typedef GrUniformDataManager INHERITED;
+};
+
+#endif
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.cpp b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
index bd0c8d4..8377437 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.cpp
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.cpp
@@ -12,11 +12,8 @@
GrVkPipelineStateDataManager::GrVkPipelineStateDataManager(const UniformInfoArray& uniforms,
uint32_t uniformSize)
- : fUniformSize(uniformSize)
- , fUniformsDirty(false) {
- fUniformData.reset(uniformSize);
- fUniforms.push_back_n(uniforms.count());
- // We must add uniforms in same order is the UniformInfoArray so that UniformHandles already
+ : INHERITED(uniforms.count(), uniformSize) {
+ // We must add uniforms in same order as the UniformInfoArray so that UniformHandles already
// owned by other objects will still match up here.
int i = 0;
for (const auto& uniformInfo : uniforms.items()) {
@@ -33,306 +30,6 @@
}
}
-void* GrVkPipelineStateDataManager::getBufferPtrAndMarkDirty(const Uniform& uni) const {
- fUniformsDirty = true;
- return static_cast<char*>(fUniformData.get())+uni.fOffset;
-}
-
-void GrVkPipelineStateDataManager::set1i(UniformHandle u, int32_t i) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- memcpy(buffer, &i, sizeof(int32_t));
-}
-
-void GrVkPipelineStateDataManager::set1iv(UniformHandle u,
- int arrayCount,
- const int32_t v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(int32_t) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const int32_t* curVec = &v[i];
- memcpy(buffer, curVec, sizeof(int32_t));
- buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
- }
-}
-
-void GrVkPipelineStateDataManager::set1f(UniformHandle u, float v0) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- memcpy(buffer, &v0, sizeof(float));
-}
-
-void GrVkPipelineStateDataManager::set1fv(UniformHandle u,
- int arrayCount,
- const float v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const float* curVec = &v[i];
- memcpy(buffer, curVec, sizeof(float));
- buffer = static_cast<char*>(buffer) + 4*sizeof(float);
- }
-}
-
-void GrVkPipelineStateDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- int32_t v[2] = { i0, i1 };
- memcpy(buffer, v, 2 * sizeof(int32_t));
-}
-
-void GrVkPipelineStateDataManager::set2iv(UniformHandle u,
- int arrayCount,
- const int32_t v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(int32_t) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const int32_t* curVec = &v[2 * i];
- memcpy(buffer, curVec, 2 * sizeof(int32_t));
- buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
- }
-}
-
-void GrVkPipelineStateDataManager::set2f(UniformHandle u, float v0, float v1) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- float v[2] = { v0, v1 };
- memcpy(buffer, v, 2 * sizeof(float));
-}
-
-void GrVkPipelineStateDataManager::set2fv(UniformHandle u,
- int arrayCount,
- const float v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const float* curVec = &v[2 * i];
- memcpy(buffer, curVec, 2 * sizeof(float));
- buffer = static_cast<char*>(buffer) + 4*sizeof(float);
- }
-}
-
-void GrVkPipelineStateDataManager::set3i(UniformHandle u,
- int32_t i0,
- int32_t i1,
- int32_t i2) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- int32_t v[3] = { i0, i1, i2 };
- memcpy(buffer, v, 3 * sizeof(int32_t));
-}
-
-void GrVkPipelineStateDataManager::set3iv(UniformHandle u,
- int arrayCount,
- const int32_t v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(int32_t) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const int32_t* curVec = &v[3 * i];
- memcpy(buffer, curVec, 3 * sizeof(int32_t));
- buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
- }
-}
-
-void GrVkPipelineStateDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- float v[3] = { v0, v1, v2 };
- memcpy(buffer, v, 3 * sizeof(float));
-}
-
-void GrVkPipelineStateDataManager::set3fv(UniformHandle u,
- int arrayCount,
- const float v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const float* curVec = &v[3 * i];
- memcpy(buffer, curVec, 3 * sizeof(float));
- buffer = static_cast<char*>(buffer) + 4*sizeof(float);
- }
-}
-
-void GrVkPipelineStateDataManager::set4i(UniformHandle u,
- int32_t i0,
- int32_t i1,
- int32_t i2,
- int32_t i3) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- int32_t v[4] = { i0, i1, i2, i3 };
- memcpy(buffer, v, 4 * sizeof(int32_t));
-}
-
-void GrVkPipelineStateDataManager::set4iv(UniformHandle u,
- int arrayCount,
- const int32_t v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(int32_t) == 4);
- for (int i = 0; i < arrayCount; ++i) {
- const int32_t* curVec = &v[4 * i];
- memcpy(buffer, curVec, 4 * sizeof(int32_t));
- buffer = static_cast<char*>(buffer) + 4*sizeof(int32_t);
- }
-}
-
-void GrVkPipelineStateDataManager::set4f(UniformHandle u,
- float v0,
- float v1,
- float v2,
- float v3) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
- SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- float v[4] = { v0, v1, v2, v3 };
- memcpy(buffer, v, 4 * sizeof(float));
-}
-
-void GrVkPipelineStateDataManager::set4fv(UniformHandle u,
- int arrayCount,
- const float v[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = this->getBufferPtrAndMarkDirty(uni);
- SkASSERT(sizeof(float) == 4);
- memcpy(buffer, v, arrayCount * 4 * sizeof(float));
-}
-
-void GrVkPipelineStateDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
- this->setMatrices<2>(u, 1, matrix);
-}
-
-void GrVkPipelineStateDataManager::setMatrix2fv(UniformHandle u,
- int arrayCount,
- const float m[]) const {
- this->setMatrices<2>(u, arrayCount, m);
-}
-
-void GrVkPipelineStateDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
- this->setMatrices<3>(u, 1, matrix);
-}
-
-void GrVkPipelineStateDataManager::setMatrix3fv(UniformHandle u,
- int arrayCount,
- const float m[]) const {
- this->setMatrices<3>(u, arrayCount, m);
-}
-
-void GrVkPipelineStateDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
- this->setMatrices<4>(u, 1, matrix);
-}
-
-void GrVkPipelineStateDataManager::setMatrix4fv(UniformHandle u,
- int arrayCount,
- const float m[]) const {
- this->setMatrices<4>(u, arrayCount, m);
-}
-
-template<int N> struct set_uniform_matrix;
-
-template<int N> inline void GrVkPipelineStateDataManager::setMatrices(UniformHandle u,
- int arrayCount,
- const float matrices[]) const {
- const Uniform& uni = fUniforms[u.toIndex()];
- SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
- uni.fType == kHalf2x2_GrSLType + (N - 2));
- SkASSERT(arrayCount > 0);
- SkASSERT(arrayCount <= uni.fArrayCount ||
- (1 == arrayCount && GrShaderVar::kNonArray == uni.fArrayCount));
-
- void* buffer = fUniformData.get();
- fUniformsDirty = true;
-
- set_uniform_matrix<N>::set(buffer, uni.fOffset, arrayCount, matrices);
-}
-
-template<int N> struct set_uniform_matrix {
- inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
- static_assert(sizeof(float) == 4);
- buffer = static_cast<char*>(buffer) + uniformOffset;
- for (int i = 0; i < count; ++i) {
- const float* matrix = &matrices[N * N * i];
- for (int j = 0; j < N; ++j) {
- memcpy(buffer, &matrix[j * N], N * sizeof(float));
- buffer = static_cast<char*>(buffer) + 4 * sizeof(float);
- }
- }
- }
-};
-
-template<> struct set_uniform_matrix<4> {
- inline static void set(void* buffer, int uniformOffset, int count, const float matrices[]) {
- static_assert(sizeof(float) == 4);
- buffer = static_cast<char*>(buffer) + uniformOffset;
- memcpy(buffer, matrices, count * 16 * sizeof(float));
- }
-};
-
bool GrVkPipelineStateDataManager::uploadUniformBuffers(GrVkGpu* gpu,
GrVkUniformBuffer* buffer) const {
bool updatedBuffer = false;
diff --git a/src/gpu/vk/GrVkPipelineStateDataManager.h b/src/gpu/vk/GrVkPipelineStateDataManager.h
index 91d5092..b090dd6 100644
--- a/src/gpu/vk/GrVkPipelineStateDataManager.h
+++ b/src/gpu/vk/GrVkPipelineStateDataManager.h
@@ -8,78 +8,28 @@
#ifndef GrVkPipelineStateDataManager_DEFINED
#define GrVkPipelineStateDataManager_DEFINED
-#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
+#include "src/gpu/GrUniformDataManager.h"
#include "include/gpu/vk/GrVkTypes.h"
-#include "src/core/SkAutoMalloc.h"
#include "src/gpu/vk/GrVkUniformHandler.h"
class GrVkGpu;
class GrVkUniformBuffer;
-class GrVkPipelineStateDataManager : public GrGLSLProgramDataManager {
+class GrVkPipelineStateDataManager : public GrUniformDataManager {
public:
typedef GrVkUniformHandler::UniformInfoArray UniformInfoArray;
GrVkPipelineStateDataManager(const UniformInfoArray&,
uint32_t uniformSize);
- void set1i(UniformHandle, int32_t) const override;
- void set1iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
- void set1f(UniformHandle, float v0) const override;
- void set1fv(UniformHandle, int arrayCount, const float v[]) const override;
- void set2i(UniformHandle, int32_t, int32_t) const override;
- void set2iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
- void set2f(UniformHandle, float, float) const override;
- void set2fv(UniformHandle, int arrayCount, const float v[]) const override;
- void set3i(UniformHandle, int32_t, int32_t, int32_t) const override;
- void set3iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
- void set3f(UniformHandle, float, float, float) const override;
- void set3fv(UniformHandle, int arrayCount, const float v[]) const override;
- void set4i(UniformHandle, int32_t, int32_t, int32_t, int32_t) const override;
- void set4iv(UniformHandle, int arrayCount, const int32_t v[]) const override;
- void set4f(UniformHandle, float, float, float, float) const override;
- void set4fv(UniformHandle, int arrayCount, const float v[]) const override;
- // matrices are column-major, the first two upload a single matrix, the latter two upload
- // arrayCount matrices into a uniform array.
- void setMatrix2f(UniformHandle, const float matrix[]) const override;
- void setMatrix3f(UniformHandle, const float matrix[]) const override;
- void setMatrix4f(UniformHandle, const float matrix[]) const override;
- void setMatrix2fv(UniformHandle, int arrayCount, const float matrices[]) const override;
- void setMatrix3fv(UniformHandle, int arrayCount, const float matrices[]) const override;
- void setMatrix4fv(UniformHandle, int arrayCount, const float matrices[]) const override;
-
- // for nvpr only
- void setPathFragmentInputTransform(VaryingHandle u, int components,
- const SkMatrix& matrix) const override {
- SK_ABORT("Only supported in NVPR, which is not in vulkan");
- }
-
// Returns true if either the geometry or fragment buffers needed to generate a new underlying
// VkBuffer object in order upload data. If true is returned, this is a signal to the caller
// that they will need to update the descriptor set that is using these buffers.
bool uploadUniformBuffers(GrVkGpu* gpu,
GrVkUniformBuffer* buffer) const;
private:
- struct Uniform {
- uint32_t fOffset;
- SkDEBUGCODE(
- GrSLType fType;
- int fArrayCount;
- );
- };
-
- template<int N> inline void setMatrices(UniformHandle, int arrayCount,
- const float matrices[]) const;
-
- void* getBufferPtrAndMarkDirty(const Uniform& uni) const;
-
- uint32_t fUniformSize;
-
- SkTArray<Uniform, true> fUniforms;
-
- mutable SkAutoMalloc fUniformData;
- mutable bool fUniformsDirty;
+ typedef GrUniformDataManager INHERITED;
};
#endif