summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/hlsl.meta.slang21
-rw-r--r--source/slang/slang-check-decl.cpp47
-rw-r--r--source/slang/slang-check.h3
-rw-r--r--source/slang/slang-mangle.cpp31
-rw-r--r--tests/hlsl-intrinsic/vector-dot-int.slang23
-rw-r--r--tests/hlsl-intrinsic/vector-dot-int.slang.expected.txt4
-rw-r--r--tools/gfx/vulkan/render-vk.cpp32
-rw-r--r--tools/gfx/vulkan/render-vk.h2
-rw-r--r--tools/gfx/vulkan/vk-util.cpp57
-rw-r--r--tools/gfx/vulkan/vk-util.h4
10 files changed, 193 insertions, 31 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 2c969e174..7d107888a 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -1582,7 +1582,7 @@ T distance(vector<T, N> x, vector<T, N> y)
// Vector dot product
-__generic<T : __BuiltinArithmeticType, let N : int>
+__generic<T : __BuiltinFloatingPointType, let N : int>
__target_intrinsic(hlsl)
__target_intrinsic(glsl)
T dot(vector<T, N> x, vector<T, N> y)
@@ -1593,6 +1593,17 @@ T dot(vector<T, N> x, vector<T, N> y)
return result;
}
+__generic<T : __BuiltinIntegerType, let N : int>
+__target_intrinsic(hlsl)
+T dot(vector<T, N> x, vector<T, N> y)
+{
+ T result = T(0);
+ for(int i = 0; i < N; ++i)
+ result += x[i] * y[i];
+ return result;
+}
+
+
// Helper for computing distance terms for lighting (obsolete)
__generic<T : __BuiltinFloatingPointType> vector<T,4> dst(vector<T,4> x, vector<T,4> y);
@@ -2568,13 +2579,19 @@ __intrinsic_op($(kIROp_Mul))
matrix<T, N, M> mul(T x, matrix<T, N, M> y);
// vector-vector (dot product)
-__generic<T : __BuiltinArithmeticType, let N : int>
+__generic<T : __BuiltinFloatingPointType, let N : int>
__target_intrinsic(hlsl)
__target_intrinsic(glsl, "dot")
T mul(vector<T, N> x, vector<T, N> y)
{
return dot(x, y);
}
+__generic<T : __BuiltinIntegerType, let N : int>
+__target_intrinsic(hlsl)
+T mul(vector<T, N> x, vector<T, N> y)
+{
+ return dot(x, y);
+}
// vector-matrix
__generic<T : __BuiltinArithmeticType, let N : int, let M : int>
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 8db157a37..3c654a48b 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -12,6 +12,8 @@
#include "slang-lookup.h"
+#include "slang-syntax.h"
+
namespace Slang
{
/// Visitor to transition declarations to `DeclCheckState::CheckedModifiers`
@@ -5342,4 +5344,49 @@ namespace Slang
}
}
+ static void _getCanonicalConstraintTypes(List<Type*>& outTypeList, Type* type)
+ {
+ if (auto andType = as<AndType>(type))
+ {
+ _getCanonicalConstraintTypes(outTypeList, andType->left);
+ _getCanonicalConstraintTypes(outTypeList, andType->right);
+ }
+ else
+ {
+ outTypeList.add(type);
+ }
+ }
+ OrderedDictionary<GenericTypeParamDecl*, List<Type*>> getCanonicalGenericConstraints(
+ DeclRef<ContainerDecl> genericDecl)
+ {
+ OrderedDictionary<GenericTypeParamDecl*, List<Type*>> genericConstraints;
+ for (auto mm : getMembersOfType<GenericTypeParamDecl>(genericDecl))
+ {
+ genericConstraints[mm.getDecl()] = List<Type*>();
+ }
+ for (auto genericTypeConstraintDecl : getMembersOfType<GenericTypeConstraintDecl>(genericDecl))
+ {
+ assert(
+ genericTypeConstraintDecl.getDecl()->sub.type->astNodeType ==
+ ASTNodeType::DeclRefType);
+ auto typeParamDecl = as<DeclRefType>(genericTypeConstraintDecl.getDecl()->sub.type)->declRef.getDecl();
+ List<Type*>* constraintTypes = genericConstraints.TryGetValue(typeParamDecl);
+ assert(constraintTypes);
+ constraintTypes->add(genericTypeConstraintDecl.getDecl()->getSup().type);
+ }
+
+ OrderedDictionary<GenericTypeParamDecl*, List<Type*>> result;
+ for (auto& constraints : genericConstraints)
+ {
+ List<Type*> typeList;
+ for (auto type : constraints.Value)
+ {
+ _getCanonicalConstraintTypes(typeList, type);
+ }
+ // TODO: we also need to sort the types within the list for each generic type param.
+ result[constraints.Key] = typeList;
+ }
+ return result;
+ }
+
}
diff --git a/source/slang/slang-check.h b/source/slang/slang-check.h
index e84ad0bc5..a7d51f951 100644
--- a/source/slang/slang-check.h
+++ b/source/slang/slang-check.h
@@ -22,4 +22,7 @@ namespace Slang
bool isFromStdLib(Decl* decl);
void registerBuiltinDecls(Session* session, Decl* decl);
+
+ OrderedDictionary<GenericTypeParamDecl*, List<Type*>> getCanonicalGenericConstraints(
+ DeclRef<ContainerDecl> genericDecl);
}
diff --git a/source/slang/slang-mangle.cpp b/source/slang/slang-mangle.cpp
index e6c0a8e7f..ca6dcecd7 100644
--- a/source/slang/slang-mangle.cpp
+++ b/source/slang/slang-mangle.cpp
@@ -2,6 +2,7 @@
#include "../compiler-core/slang-name.h"
#include "slang-syntax.h"
+#include "slang-check.h"
namespace Slang
{
@@ -330,6 +331,12 @@ namespace Slang
return;
}
+ // TODO: we should special case GenericTypeParamDecl and GenericValueParamDecl nodes
+ // instead of just dumping their names here to avoid the name of a generic parameter
+ // to have affect the binary signature.
+ // For each generic parameter, we should assign it a unique ID (i, j), where i is the
+ // nesting level of the generic, and j is the sequential order of the parameter within
+ // its generic parent, and use this 2D ID to refer to such a parameter.
emitName(context, declRef.getName());
// Special case: accessors need some way to distinguish themselves
@@ -392,26 +399,34 @@ namespace Slang
}
emit(context, genericParameterCount);
- for( auto mm : getMembers(parentGenericDeclRef) )
+
+ OrderedDictionary<GenericTypeParamDecl*, List<Type*>> genericConstraints;
+ for (auto mm : getMembers(parentGenericDeclRef))
{
- if(auto genericTypeParamDecl = mm.as<GenericTypeParamDecl>())
+ if (auto genericTypeParamDecl = mm.as<GenericTypeParamDecl>())
{
emitRaw(context, "T");
}
- else if(auto genericValueParamDecl = mm.as<GenericValueParamDecl>())
+ else if (auto genericValueParamDecl = mm.as<GenericValueParamDecl>())
{
emitRaw(context, "v");
emitType(context, getType(context->astBuilder, genericValueParamDecl));
}
- else if(mm.as<GenericTypeConstraintDecl>())
- {
- emitRaw(context, "C");
- // TODO: actually emit info about the constraint
- }
else
+ {}
+ }
+
+ auto canonicalizedConstraints = getCanonicalGenericConstraints(parentGenericDeclRef);
+ for (auto& constraint : canonicalizedConstraints)
+ {
+ for (auto type : constraint.Value)
{
+ emitRaw(context, "C");
+ emitQualifiedName(context, DeclRef<Decl>(constraint.Key, nullptr));
+ emitType(context, type);
}
}
+
}
}
diff --git a/tests/hlsl-intrinsic/vector-dot-int.slang b/tests/hlsl-intrinsic/vector-dot-int.slang
new file mode 100644
index 000000000..922bd001d
--- /dev/null
+++ b/tests/hlsl-intrinsic/vector-dot-int.slang
@@ -0,0 +1,23 @@
+//TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -shaderobj
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -shaderobj
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-cuda -compute -shaderobj
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(1, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ int idx = int(dispatchThreadID.x);
+
+ float tmp = dot(float3(idx), float3(1));
+
+ int3 a = { idx + 1, idx + 2, idx + 3};
+ int3 b = { 1, 2, 3};
+
+ int result = dot(a, b);
+
+ outputBuffer[idx] = result;
+} \ No newline at end of file
diff --git a/tests/hlsl-intrinsic/vector-dot-int.slang.expected.txt b/tests/hlsl-intrinsic/vector-dot-int.slang.expected.txt
new file mode 100644
index 000000000..18ff54819
--- /dev/null
+++ b/tests/hlsl-intrinsic/vector-dot-int.slang.expected.txt
@@ -0,0 +1,4 @@
+E
+0
+0
+0 \ No newline at end of file
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index acc22af02..f47ca5873 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -2007,6 +2007,10 @@ Result DeviceImpl::createSamplerState(ISamplerState::Desc const& desc, ISamplerS
samplerInfo.minLod = Math::Max(0.0f, desc.minLOD);
samplerInfo.maxLod = Math::Clamp(desc.maxLOD, samplerInfo.minLod, VK_LOD_CLAMP_NONE);
+ VkSamplerReductionModeCreateInfo reductionInfo = {VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO};
+ reductionInfo.reductionMode = VulkanUtil::translateReductionOp(desc.reductionOp);
+ samplerInfo.pNext = &reductionInfo;
+
VkSampler sampler;
SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateSampler(m_device, &samplerInfo, nullptr, &sampler));
@@ -6575,19 +6579,6 @@ void ResourceCommandEncoder::writeTimestamp(IQueryPool* queryPool, GfxIndex inde
&m_commandBuffer->m_renderer->m_api, m_commandBuffer->m_commandBuffer, queryPool, index);
}
-VkImageAspectFlags ResourceCommandEncoder::getAspectMask(TextureAspect aspect)
-{
- VkImageAspectFlags flags = 0;
-
- if ((uint32_t)aspect & (uint32_t)TextureAspect::Depth)
- flags |= VK_IMAGE_ASPECT_DEPTH_BIT;
- if ((uint32_t)aspect & (uint32_t)TextureAspect::Stencil)
- flags |= VK_IMAGE_ASPECT_STENCIL_BIT;
- if ((uint32_t)aspect & (uint32_t)TextureAspect::Color)
- flags |= VK_IMAGE_ASPECT_COLOR_BIT;
- return flags;
-}
-
void ResourceCommandEncoder::copyTexture(
ITextureResource* dst,
ResourceState dstState,
@@ -6622,12 +6613,12 @@ void ResourceCommandEncoder::copyTexture(
srcSubresource.mipLevelCount = dstDesc->numMipLevels;
}
VkImageCopy region = {};
- region.srcSubresource.aspectMask = getAspectMask(srcSubresource.aspectMask);
+ region.srcSubresource.aspectMask = VulkanUtil::getAspectMask(srcSubresource.aspectMask, srcImage->m_vkformat);
region.srcSubresource.baseArrayLayer = srcSubresource.baseArrayLayer;
region.srcSubresource.mipLevel = srcSubresource.mipLevel;
region.srcSubresource.layerCount = srcSubresource.layerCount;
region.srcOffset = {(int32_t)srcOffset.x, (int32_t)srcOffset.y, (int32_t)srcOffset.z};
- region.dstSubresource.aspectMask = getAspectMask(dstSubresource.aspectMask);
+ region.dstSubresource.aspectMask = VulkanUtil::getAspectMask(dstSubresource.aspectMask, dstImage->m_vkformat);
region.dstSubresource.baseArrayLayer = dstSubresource.baseArrayLayer;
region.dstSubresource.mipLevel = dstSubresource.mipLevel;
region.dstSubresource.layerCount = dstSubresource.layerCount;
@@ -6959,8 +6950,11 @@ void ResourceCommandEncoder::clearResourceView(
auto viewImpl = static_cast<PlainBufferResourceViewImpl*>(viewImplBase);
uint64_t clearStart = viewImpl->m_desc.bufferRange.firstElement;
uint64_t clearSize = viewImpl->m_desc.bufferRange.elementCount;
+
if (clearSize == 0)
clearSize = viewImpl->m_buffer->getDesc()->sizeInBytes - clearStart;
+ if (viewImpl->m_desc.bufferElementSize != 0)
+ clearSize *= viewImpl->m_desc.bufferElementSize;
api.vkCmdFillBuffer(
m_commandBuffer->m_commandBuffer,
viewImpl->m_buffer->m_buffer.m_buffer,
@@ -7012,12 +7006,12 @@ void ResourceCommandEncoder::resolveResource(
for (GfxIndex mip = 0; mip < sourceRange.mipLevelCount; ++mip)
{
VkImageResolve region = {};
- region.srcSubresource.aspectMask = getAspectMask(sourceRange.aspectMask);
+ region.srcSubresource.aspectMask = VulkanUtil::getAspectMask(sourceRange.aspectMask, srcTexture->m_vkformat);
region.srcSubresource.baseArrayLayer = layer + sourceRange.baseArrayLayer;
region.srcSubresource.layerCount = 1;
region.srcSubresource.mipLevel = mip + sourceRange.mipLevel;
region.srcOffset = {0, 0, 0};
- region.dstSubresource.aspectMask = getAspectMask(destRange.aspectMask);
+ region.dstSubresource.aspectMask = VulkanUtil::getAspectMask(destRange.aspectMask, dstTexture->m_vkformat);
region.dstSubresource.baseArrayLayer = layer + destRange.baseArrayLayer;
region.dstSubresource.layerCount = 1;
region.dstSubresource.mipLevel = mip + destRange.mipLevel;
@@ -7077,7 +7071,7 @@ void ResourceCommandEncoder::copyTextureToBuffer(
region.bufferOffset = dstOffset;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
- region.imageSubresource.aspectMask = getAspectMask(srcSubresource.aspectMask);
+ region.imageSubresource.aspectMask = VulkanUtil::getAspectMask(srcSubresource.aspectMask, image->m_vkformat);
region.imageSubresource.mipLevel = srcSubresource.mipLevel;
region.imageSubresource.baseArrayLayer = srcSubresource.baseArrayLayer;
region.imageSubresource.layerCount = srcSubresource.layerCount;
@@ -7109,7 +7103,7 @@ void ResourceCommandEncoder::textureSubresourceBarrier(
barrier.image = image->m_image;
barrier.oldLayout = translateImageLayout(src);
barrier.newLayout = translateImageLayout(dst);
- barrier.subresourceRange.aspectMask = getAspectMask(subresourceRange.aspectMask);
+ barrier.subresourceRange.aspectMask = VulkanUtil::getAspectMask(subresourceRange.aspectMask, image->m_vkformat);
barrier.subresourceRange.baseArrayLayer = subresourceRange.baseArrayLayer;
barrier.subresourceRange.baseMipLevel = subresourceRange.mipLevel;
barrier.subresourceRange.layerCount = subresourceRange.layerCount;
diff --git a/tools/gfx/vulkan/render-vk.h b/tools/gfx/vulkan/render-vk.h
index 646c3eb98..5cec63787 100644
--- a/tools/gfx/vulkan/render-vk.h
+++ b/tools/gfx/vulkan/render-vk.h
@@ -1408,8 +1408,6 @@ public:
virtual SLANG_NO_THROW void SLANG_MCALL
writeTimestamp(IQueryPool* queryPool, GfxIndex index) override;
- VkImageAspectFlags getAspectMask(TextureAspect aspect);
-
virtual SLANG_NO_THROW void SLANG_MCALL copyTexture(
ITextureResource* dst,
ResourceState dstState,
diff --git a/tools/gfx/vulkan/vk-util.cpp b/tools/gfx/vulkan/vk-util.cpp
index 8e2a187a3..251e91cab 100644
--- a/tools/gfx/vulkan/vk-util.cpp
+++ b/tools/gfx/vulkan/vk-util.cpp
@@ -113,6 +113,50 @@ namespace gfx {
}
}
+VkImageAspectFlags VulkanUtil::getAspectMask(TextureAspect aspect, VkFormat format)
+{
+ switch (aspect)
+ {
+ case TextureAspect::Default:
+ switch (format)
+ {
+ case VK_FORMAT_D16_UNORM_S8_UINT:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+ case VK_FORMAT_D16_UNORM:
+ case VK_FORMAT_D32_SFLOAT:
+ case VK_FORMAT_X8_D24_UNORM_PACK32:
+ return VK_IMAGE_ASPECT_DEPTH_BIT;
+ case VK_FORMAT_S8_UINT:
+ return VK_IMAGE_ASPECT_STENCIL_BIT;
+ default:
+ return VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ case TextureAspect::Color:
+ return VK_IMAGE_ASPECT_COLOR_BIT;
+ case TextureAspect::Depth:
+ return VK_IMAGE_ASPECT_DEPTH_BIT;
+ case TextureAspect::DepthStencil:
+ return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+ case TextureAspect::Stencil:
+ return VK_IMAGE_ASPECT_STENCIL_BIT;
+ case TextureAspect::Plane0:
+ return VK_IMAGE_ASPECT_PLANE_0_BIT;
+ case TextureAspect::Plane1:
+ return VK_IMAGE_ASPECT_PLANE_1_BIT;
+
+ case TextureAspect::Plane2:
+ return VK_IMAGE_ASPECT_PLANE_2_BIT;
+
+ case TextureAspect::MetaData:
+ return VK_IMAGE_ASPECT_METADATA_BIT;
+ default:
+ SLANG_UNREACHABLE("getAspectMask");
+ return 0;
+ }
+}
+
/* static */SlangResult VulkanUtil::toSlangResult(VkResult res)
{
return (res == VK_SUCCESS) ? SLANG_OK : SLANG_FAIL;
@@ -454,6 +498,19 @@ VkStencilOpState VulkanUtil::translateStencilState(DepthStencilOpDesc desc)
return rs;
}
+VkSamplerReductionMode VulkanUtil::translateReductionOp(TextureReductionOp op)
+{
+ switch (op)
+ {
+ case gfx::TextureReductionOp::Minimum:
+ return VK_SAMPLER_REDUCTION_MODE_MIN;
+ case gfx::TextureReductionOp::Maximum:
+ return VK_SAMPLER_REDUCTION_MODE_MAX;
+ default:
+ return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
+ }
+}
+
/* static */Slang::Result VulkanUtil::handleFail(VkResult res)
{
if (res != VK_SUCCESS)
diff --git a/tools/gfx/vulkan/vk-util.h b/tools/gfx/vulkan/vk-util.h
index 05533dad1..ade62ba59 100644
--- a/tools/gfx/vulkan/vk-util.h
+++ b/tools/gfx/vulkan/vk-util.h
@@ -25,6 +25,8 @@ struct VulkanUtil
/// Returns VK_FORMAT_UNDEFINED if a match is not found
static VkFormat getVkFormat(Format format);
+ static VkImageAspectFlags getAspectMask(TextureAspect aspect, VkFormat format);
+
/// Called by SLANG_VK_RETURN_FAIL if a res is a failure.
/// On debug builds this will cause an assertion on failure.
static Slang::Result handleFail(VkResult res);
@@ -100,6 +102,8 @@ struct VulkanUtil
static VkStencilOpState translateStencilState(DepthStencilOpDesc desc);
+ static VkSamplerReductionMode translateReductionOp(TextureReductionOp op);
+
};
struct AccelerationStructureBuildGeometryInfoBuilder