summaryrefslogtreecommitdiffstats
path: root/tools/gfx/cpu/cpu-resource-views.cpp
diff options
context:
space:
mode:
authorlucy96chen <47800040+lucy96chen@users.noreply.github.com>2022-07-27 15:53:36 -0700
committerGitHub <noreply@github.com>2022-07-27 15:53:36 -0700
commited37dcbc175d07134cb0493f5e379a19e97c82f5 (patch)
tree0abd3202401d89e76a979ab7c18569afd63db8a6 /tools/gfx/cpu/cpu-resource-views.cpp
parentde0f8cf1be0770b87a117b637943db4ad4e1158b (diff)
Split render-cpu into smaller files (#2340)
* render-cpu split, does not compile * split finished, one compile error * added missing include and missing destructor implementation * Rerun TeamCity CI
Diffstat (limited to 'tools/gfx/cpu/cpu-resource-views.cpp')
-rw-r--r--tools/gfx/cpu/cpu-resource-views.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/tools/gfx/cpu/cpu-resource-views.cpp b/tools/gfx/cpu/cpu-resource-views.cpp
new file mode 100644
index 000000000..ccf253cab
--- /dev/null
+++ b/tools/gfx/cpu/cpu-resource-views.cpp
@@ -0,0 +1,176 @@
+// cpu-resource-views.cpp
+#include "cpu-resource-views.h"
+
+namespace gfx
+{
+using namespace Slang;
+
+namespace cpu
+{
+
+ResourceViewImpl::ResourceViewImpl(Kind kind, Desc const& desc)
+ : m_kind(kind)
+{
+ m_desc = desc;
+}
+
+BufferResourceImpl* BufferResourceViewImpl::getBuffer() const
+{
+ return m_buffer;
+}
+
+TextureResourceImpl* TextureResourceViewImpl::getTexture() const
+{
+ return m_texture;
+}
+
+slang_prelude::TextureDimensions TextureResourceViewImpl::GetDimensions(int mipLevel)
+{
+ slang_prelude::TextureDimensions dimensions = {};
+
+ TextureResourceImpl* texture = m_texture;
+ auto& desc = texture->_getDesc();
+ auto baseShape = texture->m_baseShape;
+
+ dimensions.arrayElementCount = desc.arraySize;
+ dimensions.numberOfLevels = desc.numMipLevels;
+ dimensions.shape = baseShape->rank;
+ dimensions.width = desc.size.width;
+ dimensions.height = desc.size.height;
+ dimensions.depth = desc.size.depth;
+
+ return dimensions;
+}
+
+void TextureResourceViewImpl::Load(const int32_t* texelCoords, void* outData, size_t dataSize)
+{
+ void* texelPtr = _getTexelPtr(texelCoords);
+
+ m_texture->m_formatInfo->unpackFunc(texelPtr, outData, dataSize);
+}
+
+void TextureResourceViewImpl::Sample(
+ slang_prelude::SamplerState samplerState,
+ const float* coords,
+ void* outData,
+ size_t dataSize)
+{
+ // We have no access to information from fragment quads, so we cannot
+ // compute the finite-difference derivatives needed from `coords`.
+ //
+ // The only reasonable thing to do is to sample mip level zero.
+ //
+ SampleLevel(samplerState, coords, 0.0f, outData, dataSize);
+}
+
+void TextureResourceViewImpl::SampleLevel(
+ slang_prelude::SamplerState samplerState,
+ const float* coords,
+ float level,
+ void* outData,
+ size_t dataSize)
+{
+ TextureResourceImpl* texture = m_texture;
+ auto baseShape = texture->m_baseShape;
+ auto& desc = texture->_getDesc();
+ int32_t rank = baseShape->rank;
+ int32_t baseCoordCount = baseShape->baseCoordCount;
+
+ int32_t integerMipLevel = int32_t(level + 0.5f);
+ if (integerMipLevel >= desc.numMipLevels) integerMipLevel = desc.numMipLevels - 1;
+ if (integerMipLevel < 0) integerMipLevel = 0;
+
+ auto& mipLevelInfo = texture->m_mipLevels[integerMipLevel];
+
+ bool isArray = (desc.arraySize != 0) || (desc.type == ITextureResource::Type::TextureCube);
+ int32_t effectiveArrayElementCount = texture->m_effectiveArrayElementCount;
+ int32_t coordIndex = baseCoordCount;
+ int32_t elementIndex = 0;
+ if (isArray)
+ {
+ elementIndex = int32_t(coords[coordIndex++] + 0.5f);
+ }
+ if (elementIndex >= effectiveArrayElementCount) elementIndex = effectiveArrayElementCount - 1;
+ if (elementIndex < 0) elementIndex = 0;
+
+ // Note: for now we are just going to do nearest-neighbor sampling
+ //
+ int64_t texelOffset = mipLevelInfo.offset;
+ texelOffset += elementIndex * mipLevelInfo.strides[3];
+ for (int32_t axis = 0; axis < rank; ++axis)
+ {
+ int32_t extent = mipLevelInfo.extents[axis];
+
+ float coord = coords[axis];
+
+ // TODO: deal with wrap/clamp/repeat if `coord < 0` or `coord > 1`
+
+ int32_t integerCoord = int32_t(coord * (extent - 1) + 0.5f);
+
+ if (integerCoord >= extent) integerCoord = extent - 1;
+ if (integerCoord < 0) integerCoord = 0;
+
+ texelOffset += integerCoord * mipLevelInfo.strides[axis];
+ }
+
+ auto texelPtr = (char const*)texture->m_data + texelOffset;
+
+ m_texture->m_formatInfo->unpackFunc(texelPtr, outData, dataSize);
+}
+
+void* TextureResourceViewImpl::refAt(const uint32_t* texelCoords)
+{
+ return _getTexelPtr((int32_t const*)texelCoords);
+}
+
+void* TextureResourceViewImpl::_getTexelPtr(int32_t const* texelCoords)
+{
+ TextureResourceImpl* texture = m_texture;
+ auto baseShape = texture->m_baseShape;
+ auto& desc = texture->_getDesc();
+
+ int32_t rank = baseShape->rank;
+ int32_t baseCoordCount = baseShape->baseCoordCount;
+
+ bool isArray = (desc.arraySize != 0) || (desc.type == ITextureResource::Type::TextureCube);
+ bool isMultisample = desc.sampleDesc.numSamples > 1;
+ bool isBuffer = desc.type == ITextureResource::Type::Buffer;
+ bool hasMipLevels = !(isMultisample || isBuffer);
+
+ int32_t effectiveArrayElementCount = texture->m_effectiveArrayElementCount;
+
+ int32_t coordIndex = baseCoordCount;
+ int32_t elementIndex = 0;
+ if (isArray)
+ {
+ elementIndex = texelCoords[coordIndex++];
+ }
+ if (elementIndex >= effectiveArrayElementCount) elementIndex = effectiveArrayElementCount - 1;
+ if (elementIndex < 0) elementIndex = 0;
+
+ int32_t mipLevel = 0;
+ if (!hasMipLevels)
+ {
+ mipLevel = texelCoords[coordIndex++];
+ }
+ if (mipLevel >= desc.numMipLevels) mipLevel = desc.numMipLevels - 1;
+ if (mipLevel < 0) mipLevel = 0;
+
+ auto& mipLevelInfo = texture->m_mipLevels[mipLevel];
+
+ int64_t texelOffset = mipLevelInfo.offset;
+ texelOffset += elementIndex * mipLevelInfo.strides[3];
+ for (int32_t axis = 0; axis < rank; ++axis)
+ {
+ int32_t coord = texelCoords[axis];
+ if (coord >= mipLevelInfo.extents[axis]) coord = mipLevelInfo.extents[axis] - 1;
+ if (coord < 0) coord = 0;
+
+ texelOffset += texelCoords[axis] * mipLevelInfo.strides[axis];
+ }
+
+ return (char*)texture->m_data + texelOffset;
+}
+
+} // namespace cpu
+} // namespace gfx