问题标签 [directcompute]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
909 浏览

sorting - DirectX11 基数排序

我正在努力在 DirectX11 中实现高效的基数排序。我需要快速排序不超过 256K 的项目。它不需要就地。使用 CUDA / OpenCL 不是一种选择。

我几乎可以使用它,但是它有一些问题:

  • 直方图的生成速度很快,但仍然比网上引用的数字要长得多
  • 在随后的排序过程中,由于 cp_sort 中直方图缓冲区上的 InterlockedAdd,不保留低位相同的键的顺序(见下文)
  • cp_sort真的很慢,因为在同一个 InterlockedAdd 上进行全局内存访问

我一直在尝试了解如何根据在线算法解决此问题,但我似乎无法理解它们。

这是我的 3 个内核。(它用于广告牌粒子系统,所以术语“四边形”仅指要排序的项目)

任何人都可以就如何解决/优化这个问题提供任何帮助吗?我很想了解一些更复杂的 GPU 基数排序算法实际上在做什么!

谢谢!

0 投票
2 回答
3384 浏览

directx - DirectCompute 最优线程数设置

我最近一直在玩计算着色器,我正在尝试确定设置我的 [numthreads(x,y,z)] 和调度调用的最佳方式。我的演示窗口是 800x600,我每像素启动 1 个线程。我正在执行 2D 纹理修改 - 没有太重。

我的第一次尝试是指定

我的 Dispatch() 电话总是

所以首先是

这以 25-26 fps 的速度运行。然后我减少到以 16 fps 运行的 [numthreads(4,4,1)]。将其增加到 [numthreads(16,16,1)] 开始产生大约 30 fps 的不错结果。玩弄 Y 线程组编号 [numthreads(16,8,1)] 设法将其推到 32 fps。

我的问题是是否有确定线程数的最佳方法,以便我可以最有效地利用 GPU,还是只是好的试错法?

0 投票
2 回答
7726 浏览

directx - 具有 numthreads (1,1,1) 的计算着色器运行速度极慢

我刚刚开始学习 DirectX 编程,使用 F# 和 SharpDX 作为 .NET 包装器。作为一个测试用例,我渲染了 Mandelbrot 集。计算是使用 2 个计算着色器完成的。

第一个着色器计算每个像素的深度(函数“CalcMandel”),结果存储在 RWStructuredBuffer 中。这种计算需要大量的单乘或双乘,但它在我的 GPU (AMD 7790) 上速度非常快。“CalcMandel”具有属性

并通过

这里没有问题——“核心”Mandelbrot 集的 1000 x 800 像素图像以超过 1000 fps 的速度运行(在 GPU 上使用单精度)。


第二个着色器几乎什么都不做:它计算先前计算的最小值、最大值和平均值(函数“CalcMinMax”)。“CalcMinMax”具有属性

并通过调用

对于给定的图像大小,单个 GPU 线程必须遍历缓冲区超过 800.000 个整数来计算最小值、最大值和平均值。我使用单线程,因为我不知道如何以并行方式实现此计算。

问题:“CalcMinMax”非常慢:帧速率从 1000 多帧下降到 5 帧!

我的问题:这里有什么问题?我是否使用了错误的设置/参数(numthreads)?如何加快 min-max 计算?

我的想法:我的第一个假设是访问 RWBuffer 可能很慢——事实并非如此。当我用常量替换缓冲区访问时,帧速率没有增加。

我的 GPU 有 appr。900 个着色器核心并使用数千个线程来计算 Mandelbrot 集,而“CalcMinMax”仅使用一个线程。然而,我仍然不明白为什么事情变得如此缓慢。

我将不胜感激任何建议!

=================================================

// HLSL CONTENT (Mandelbrot 集计算省略):

// * ** * ** * ** * ** * ** * ** * F# 程序(最小-最大部分) * ** * ** * ** * ** *

着色器设置:

着色器用法:

阅读统计:

0 投票
2 回答
8253 浏览

hlsl - 如何使用顶点缓冲区将计算着色器结果输入顶点着色器?

在详细介绍之前,我想概述一下问题:

我使用 RWStructuredBuffers 来存储我的计算着色器 (CS) 的输出。由于顶点和像素着色器无法从 RWStructuredBuffers 中读取,我将一个 StructuredBuffer 映射到同一插槽 (u0/t0) 和 (u4/t4) 上:

我使用 ShaderRecourceView 授予像素和/或顶点着色器访问缓冲区的权限。这个概念适用于我的像素着色器,但顶点着色器似乎只读取 0 值(我使用 SV_VertexID 作为缓冲区的索引):

没有来自 hlsl 编译器的错误消息或警告,renderloop 以 60 fps(使用 vsync)运行,但屏幕仍然是黑色的。由于我在调用 Draw(..) 之前使用 Color.White 将屏幕空白,因此渲染管道似乎处于活动状态。

当我通过 UAView 从 GPU 读取三角形数据内容到“vertArray”并将其反馈到顶点缓冲区时,一切正常:

程序:

HLSL:

这里定义了 2D - Vertex / Pixelshaders。请注意,PS_2D 访问插槽 t0 中的缓冲区“output2” - 这正是我想要为 3D 顶点着色器“VS_3DA”复制的“技巧”:

三天来,我一直在寻找和尝试,但无济于事。我收集的所有信息似乎都证实了我使用 SV_VertexID 的方法应该有效。

有人可以给建议吗?感谢您阅读我的帖子!

==================================================== ====================

细节:

我非常喜欢 DirectX 11 计算着色器的概念,我想将它用于代数计算。作为一个测试用例,我在 3D 中渲染分形(Mandelbrot 集)。一切都按预期工作——除了墙上的最后一块砖不见了。

计算采取以下步骤:

  1. 使用 CS 计算 2D 纹理(输出为“counterTable”和“colorOutbutTable”(有效)

  2. 可选择将此纹理渲染到屏幕(作品)

  3. 使用另一个 CS 生成网格(三角形列表)。此 CS 从步骤 1 中获取 x、y 和颜色值,计算 z 坐标,最后为每个像素创建一个四边形。结果存储在“vertexTable”中。(作品)

  4. 将三角形列表提供给顶点着色器(问题!!!)

  5. 渲染到屏幕(工作 - 使用顶点缓冲区)。

对于编程,我使用 F# 3.0 和 SharpDX 作为 .NET 包装器。两个着色器(像素和顶点)的 ShaderRessourceView 设置了相同的参数(大小参数除外):

这里没什么特别的。创建 2D 缓冲区(绑定到插槽 t0 中的缓冲区“output2”):

创建 3D 缓冲区(绑定到插槽 t4 中的“vertexTable2”):

为 2D 设置资源:

渲染 2D:

为 3D 设置资源:

渲染 3D(不起作用 - 输出结果为黑屏)

最后是插槽号:

0 投票
1 回答
925 浏览

directx-11 - 如何将驻留在 GPU 上的缓冲区资源绑定到输入汇编器 (IA)?

我使用计算着色器来计算三角形列表并将其存储在RWStructuredBuffer. 为了进行测试,我读取了这个缓冲区并通过context.InputAssembler.SetVertexBuffers (…). 这种方法有效,但仅对测试数据的正确性有效。

现在我想使用资源视图(也就是不将指针传递给顶点缓冲区)将(已经存在的)缓冲区绑定到 IA 阶段。

我正在阅读一些好书(Frank D. Luna、Jason Zink),但他们从未提及这个案例。

=============== 编辑:

  1. 我在这里使用的语法是由 SharpDX 包装器强加的。

  2. context.VertexShader.SetShaderResource(...)我可以通过绑定一个 ResoureceView将缓冲区绑定到顶点着色器。SV_VertexID在我用来访问缓冲区的 VS中。所以我暂时有一个可行的解决方案,但将来可能会出现我必须将缓冲区绑定到输入汇编器的情况。

0 投票
1 回答
7536 浏览

unity3d - Unity Compute Shader,通过 SV_DispatchThreadID 进行数组索引

我在 Compute Shader 中的 GPU 上的数组索引存在问题,我已经坚持了好几个星期。

我正在尝试使用 SV_DispatchThreadID 的 x 值作为我的粒子数组的索引(如网络上的某些示例所示)。

它正在工作......但threadID变量(在主函数中)总是返回0,3,6,9,12,15......而不是0,1,2,3,4,......

我在 CPU 端的调度调用是: Dispatch(64, 1, 1);

我尝试了许多调度配置 (32,16,1), (128,1,1),... 有许多配置 numtards (1,1,1), (32,32,1), (16 ,16,1)...但总是相同的结果... threadID 从来没有被很好地排序。

如何获得有序索引?:(...总是得到像0,3,6,9这样的索引,...

有什么建议吗?

非常感谢。

这是我的 CS 内核和 C# 源代码:

用于创建 ComputeBuffer 和其他内容的 C# 代码:

这里是顶点、几何和像素着色器:

0 投票
2 回答
974 浏览

c# - WPF 几何上的 DirectX

我只是有一个问题:我需要在画布上绘制一些 WPF 几何图形,每个几何图形的表面都是 Direct3D 11 中的复杂 Texture2D。我正在使用 SharpDX 并将 Texture2D 转换为 MemoryStream 然后转换为 WPF ImageSource,因为我正在使用计算着色器,UAV 纹理不支持 Format.Bgra,所以我不能使用 D3DImage。由于存在性能问题,如何将 Texture2D 直接绑定到 WPF Geometry?谢谢。

0 投票
1 回答
1827 浏览

c++ - dx11 中的计算着色器基础知识

我即将在我的代码库中添加计算着色器支持,但在寻找一些非常基本的问题的答案时遇到了问题:

  1. 那里的所有文档都说 Compute Shader 管道独立于 GPU 运行,但是所有 dx11 示例代码都使用设备上下文接口来设置着色器本身、资源视图和调用 dispatch() 方法,所以这些在命令中排队与其余渲染命令一起缓冲还是独立执行?

  2. 跟进问题 1,我可以从多个线程调用计算着色器,还是需要缓冲所有计算着色器命令并在创建直接设备上下文的线程上发出它们?

  3. 同步。大多数文章使用 CopyResource 命令,该命令将自动同步计算着色器完成并让 CPU 访问结果,但似乎这也会阻塞 GPU。有没有更有效的同步方式?

我知道我可以通过试验找到答案,但是任何可以节省我时间的帮助都将不胜感激。

0 投票
1 回答
1540 浏览

gpgpu - GPU 和确定性

我正在考虑将一些数学运算卸载到 GPU。因为我已经在使用 D3D11,所以我会使用计算着色器来完成这项工作。但问题是我需要相同输入的结果相同,无论用户可能拥有什么 GPU。(仅要求它支持计算着色器 4.0)。

那么 GPU 上的浮点数学是确定性的吗?

如果不是,GPU 是否支持整数数学?

0 投票
1 回答
5321 浏览

hlsl - 了解 ComputeShaders 中的“采样器数组索引必须是文字表达式”错误

假设我有一个计算着色器,它使用组的 ID 从 Texture2DArray 检索数据,如下所示:

假设我像这样启动它deviceContext->Dispatch(2, 0, 0);

因此,2 组,每组 32 个线程从 Texture2DArray 读取像素值。GroupID.x = 0 中的所有线程将从 gTextureArray[0] 中读取值,而 GroupID.y = 0 中的所有线程将从 gTextureArray[1] 中读取值。事实证明我无法编译那个简单的代码,而是得到了这个编译错误error X3512: sampler array index must be a literal expression

现在,我知道我可以这样做:

或者使用一个开关,以防我有很多组,所以它看起来不那么糟糕(它仍然如此)

请注意没有扭曲分歧,因为每组中的所有线程都将进入一个分支或另一个分支。我的问题是,我在这里错过了什么吗?为什么 HLSL 不支持这种索引,因为我看不到任何分歧或其他问题,至少在这种情况下?