D3D,Vulkan: Prep work to share useful functions from D3D
- Refactor and move some functions used by D3D that are not really
renderer specific to be used by the Vulkan implementation to support
setting matx uniforms.
Bug: angleproject:2581
Change-Id: Ib37ddf4fc62bb8ecb3629893a24969e1f515795b
Reviewed-on: https://chromium-review.googlesource.com/1079845
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/renderer_utils.cpp b/src/libANGLE/renderer/renderer_utils.cpp
index 8fa4a77..c21ef6b 100644
--- a/src/libANGLE/renderer/renderer_utils.cpp
+++ b/src/libANGLE/renderer/renderer_utils.cpp
@@ -225,6 +225,66 @@
colorWriteFunction(reinterpret_cast<const uint8_t *>(&color), destPixelData);
}
+template <typename T, int cols, int rows>
+bool TransposeExpandMatrix(T *target, const GLfloat *value)
+{
+ constexpr int targetWidth = 4;
+ constexpr int targetHeight = rows;
+ constexpr int srcWidth = rows;
+ constexpr int srcHeight = cols;
+
+ constexpr int copyWidth = std::min(targetHeight, srcWidth);
+ constexpr int copyHeight = std::min(targetWidth, srcHeight);
+
+ T staging[targetWidth * targetHeight] = {0};
+
+ for (int x = 0; x < copyWidth; x++)
+ {
+ for (int y = 0; y < copyHeight; y++)
+ {
+ staging[x * targetWidth + y] = static_cast<T>(value[y * srcWidth + x]);
+ }
+ }
+
+ if (memcmp(target, staging, targetWidth * targetHeight * sizeof(T)) == 0)
+ {
+ return false;
+ }
+
+ memcpy(target, staging, targetWidth * targetHeight * sizeof(T));
+ return true;
+}
+
+template <typename T, int cols, int rows>
+bool ExpandMatrix(T *target, const GLfloat *value)
+{
+ constexpr int kTargetWidth = 4;
+ constexpr int kTargetHeight = rows;
+ constexpr int kSrcWidth = cols;
+ constexpr int kSrcHeight = rows;
+
+ constexpr int kCopyWidth = std::min(kTargetWidth, kSrcWidth);
+ constexpr int kCopyHeight = std::min(kTargetHeight, kSrcHeight);
+
+ T staging[kTargetWidth * kTargetHeight] = {0};
+
+ for (int y = 0; y < kCopyHeight; y++)
+ {
+ for (int x = 0; x < kCopyWidth; x++)
+ {
+ staging[y * kTargetWidth + x] = static_cast<T>(value[y * kSrcWidth + x]);
+ }
+ }
+
+ if (memcmp(target, staging, kTargetWidth * kTargetHeight * sizeof(T)) == 0)
+ {
+ return false;
+ }
+
+ memcpy(target, staging, kTargetWidth * kTargetHeight * sizeof(T));
+ return true;
+}
+
} // anonymous namespace
PackPixelsParams::PackPixelsParams()
@@ -546,4 +606,54 @@
return gl::NoError();
}
+#define ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(cols, rows) \
+ template bool SetFloatUniformMatrix<cols, rows>(unsigned int, unsigned int, GLsizei, \
+ GLboolean, const GLfloat *, uint8_t *)
+
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(2, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(3, 3);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(4, 4);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(2, 3);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(3, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(2, 4);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(4, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(3, 4);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(4, 3);
+
+#undef ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC
+
+template <int cols, int rows>
+bool SetFloatUniformMatrix(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ unsigned int count =
+ std::min(elementCount - arrayElementOffset, static_cast<unsigned int>(countIn));
+
+ const unsigned int targetMatrixStride = (4 * rows);
+ GLfloat *target = reinterpret_cast<GLfloat *>(
+ targetData + arrayElementOffset * sizeof(GLfloat) * targetMatrixStride);
+
+ bool dirty = false;
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (transpose == GL_FALSE)
+ {
+ dirty = ExpandMatrix<GLfloat, cols, rows>(target, value) || dirty;
+ }
+ else
+ {
+ dirty = TransposeExpandMatrix<GLfloat, cols, rows>(target, value) || dirty;
+ }
+ target += targetMatrixStride;
+ value += cols * rows;
+ }
+
+ return dirty;
+}
+
} // namespace rx