- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我真的搞不懂这是怎么回事。
我有一个计算着色器,它接收 FFT 结果(来自实际输入)并计算每个 bin 的功率,将它们存储在不同的缓冲区 (UAV) 中。 FFT 实现是 D3DCSX 库的实现。
有问题的着色器:
struct Complex {
float real;
float imag;
};
RWStructuredBuffer<Complex> g_result : register(u0);
RWStructuredBuffer<float> g_powers : register(u1);
[numthreads(1, 1, 1)] void main(uint3 id : SV_DispatchThreadID) {
const uint bin = id.x;
const float real = g_result[bin + 1].real;
const float imag = g_result[bin + 1].imag;
const float power = real * real + imag * imag;
const float mag = sqrt(power);
const float db = 10.0f * log10(1.0f + power);
g_powers[bin] = power;
}
缓冲区创建代码:
//The buffer in which the resulting powers are stored (m_result_buffer1)
buffer_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
buffer_desc.ByteWidth = sizeof(float) * NumBins();
buffer_desc.CPUAccessFlags = 0;
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
buffer_desc.StructureByteStride = sizeof(float);
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
hr = m_device->CreateBuffer (
&buffer_desc,
nullptr,
&m_result_buffer1
); HR_THROW();
//UAV for m_result_buffer1
view_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
view_desc.Buffer.FirstElement = 0;
view_desc.Format = DXGI_FORMAT_R32_TYPELESS;
view_desc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
view_desc.Buffer.NumElements = NumBins();
hr = m_device->CreateUnorderedAccessView (
m_result_buffer1,
&view_desc,
&m_result_view
); HR_THROW();
//Buffer for reading powers to the CPU
buffer_desc.BindFlags = 0;
buffer_desc.ByteWidth = sizeof(float) * NumBins();
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
buffer_desc.MiscFlags = 0;
buffer_desc.StructureByteStride = sizeof(float);
buffer_desc.Usage = D3D11_USAGE_STAGING;
hr = m_device->CreateBuffer (
&buffer_desc,
nullptr,
&m_result_buffer2
); HR_THROW();
发送代码:
CComPtr<ID3D11UnorderedAccessView> result_view;
hr = m_fft->ForwardTransform (
m_sample_view,
&result_view
); HR_THROW();
ID3D11UnorderedAccessView* views[] = {
result_view, //FFT UAV (u0)
m_result_view //Power UAV (u1)
};
m_context->CSSetShader(m_power_cs, nullptr, 0);
m_context->CSSetUnorderedAccessViews(0, 2, views, nullptr);
m_context->Dispatch(NumBins(), 1, 1);
最后是 CPU 映射代码:
m_context->CopyResource(m_result_buffer2, m_result_buffer1);
D3D11_MAPPED_SUBRESOURCE sub = { 0 };
m_context->Map(m_result_buffer2, 0, D3D11_MAP_READ, 0, &sub);
memcpy(result, sub.pData, sizeof(float) * NumBins());
m_context->Unmap(m_result_buffer2, 0);
发生的事情是这个着色器似乎让每个线程写入输出缓冲区中的相同索引。映射缓冲区始终为第一个 bin 读取正确的值,然后为所有其他 bin 读取 0.0f。 CPU 上的等效代码运行得很好。奇怪的是我已经放置了条件并且知道 bin
并不总是 0,而且 bin 0 之外的每个 bin 的功率也不总是 0.0f。我还尝试使用 for 循环在同一个线程上写入多个 bin,同样的事情发生了。我做错了什么?
我有一种预感,缓冲区创建代码或映射代码才是问题的根源。我知道我在 GPU 上运行了正确数量的线程并且调度 ID 是正确的,错误的是 CPU 端的结果。
最佳答案
问题解决了!
我使用 RWStructuredBuffer
来表示 RWByteOrderBuffer
。不完全确定这是如何导致这个结果的,但确实如此。因此,FFT 结果现在是 RWByteOrderBuffer
。不过,这个缓冲区的奇怪之处在于 D3DCSX 实现将浮点值间隔得如此之远 - 可能是出于缓存原因,但老实说我不太确定为什么。现在这是我的计算着色器(这次计算分贝而不是功率 - 一个不相关的更改):
RWByteAddressBuffer g_result : register(u0);
RWStructuredBuffer<float> g_decibels : register(u1);
[numthreads(256, 1, 1)] void main(uint3 id : SV_DispatchThreadID) {
const float real = asfloat(g_result.Load(id.x * 8 + 0));
const float imag = asfloat(g_result.Load(id.x * 8 + 4));
const float power = real * real + imag * imag;
const float db = 10.0f * log10(1.0f + power);
g_decibels[id.x] = db;
}
不过,我将分贝缓冲器的描述更改为结构化缓冲器的描述,只是为了让事情对我来说更容易:
buffer_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
buffer_desc.ByteWidth = sizeof(float) * NumBins();
buffer_desc.CPUAccessFlags = 0;
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
buffer_desc.StructureByteStride = sizeof(float);
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
hr = m_device->CreateBuffer (
&buffer_desc,
nullptr,
&m_result_buffer1
); HR_THROW();
view_desc.Buffer.FirstElement = 0;
view_desc.Buffer.Flags = 0;
view_desc.Buffer.NumElements = NumBins();
view_desc.Format = DXGI_FORMAT_UNKNOWN;
view_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
hr = m_device->CreateUnorderedAccessView (
m_result_buffer1,
&view_desc,
&m_result_view
); HR_THROW();
这就是为什么 g_decibels
仍然是 RWStructuredBuffer
。
我仍然不知道当只需要访问时结果缓冲区的读/写是否重要 - 如果我将 g_result
更改为常规 ByteOrderBuffer
我没有输出。但至少它现在可以正常工作了。
关于c++ - DX11 Compute Shader 只写入一个索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28785495/
我正在编写一个着色器,对场景渲染的纹理产生模糊效果。 我需要在 2 遍中做到这一点,所以通过 P0 进行水平模糊,并在 P1 中进行垂直模糊。 问题是: 我如何在 P0 channel 上获取 PS
我正在尝试从源代码运行 python 应用程序,它具有: from shader import ShaderProgram,ShaderCode 我不知道要下载+安装什么才能获得“着色器”。它非常不具
着色器编译成功,但程序在渲染开始后立即崩溃...这是我得到的错误:“着色器中没有名称为‘u_texture’的制服”。这是我的着色器的样子: #ifdef GL_ES precision medium
当我使用 xcode 8 在 ios 10 中运行我的应用程序时,我在调试控制台中收到以下消息,并且通过 UI 卡住,任何人都可以知道为什么会发生这种情况 ERROR /BuildRoot/Lib
我第一次实现延迟渲染/着色时遇到了一些我自己无法解决的问题:/。 同时渲染几何 channel 和延迟 channel 时,我得到了这个看起来很奇怪的输出 在设置拓扑、输入布局等之前,我在延迟传递的开
我正在为教程开发法线贴图实现,出于教学目的,我想将 TBN 矩阵传递给片段着色器(从顶点着色器),这样我就可以将切线空间中的法线 vector 转换为世界 -照明计算的空间。法线贴图应用于二维平面,其
我第一次尝试将 bool 值传递到我的顶点着色器中;到目前为止我只使用过 float 。 所讨论的 bool 值是特定于原语的,因此不能作为统一传递。然而,对于任何给定图元的所有顶点,它具有相同的值。
这两个是我的 VertexShader 和 Fragment Shader 文件: 顶点着色器文件: attribute vec4 position; attribute vec4 input
我正在尝试在 Unity 中创建线框顶点/片段着色器。根据 this paper 似乎可能.一般的想法似乎是将顶点着色器中计算的距离向量传递给片段着色器中的每个片段,它可以使用它来确定根据线框线在多边
当前正在制作游戏,并试图在单击“菜单”按钮时获得覆盖屏幕的覆盖层-我想这应该是相当普遍/简单的,但是在实现它时仍然有问题。 我当前的设置是: TiledMapRenderer:渲染TMX切片(背景/
什么是应用亮度和对比度的简单像素着色器脚本效果? 我找到了这个,但它似乎不正确: sampler2D input : register(s0); float brightness : register
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在编写一个 PixelShader(HLSL、SM40)并尝试在某些情况下完全跳过输出。我当前的代码如下所示: float4 PS( PS_INPUT input) : SV_Target {
我有一个变量,可以是负数,也可以是正数。 确保其始终为正值的一种方法是: if (var < 0) var = -var; 但是,我认为必须有一个着色器函数可以做到这一点。我正在使用 Cg,但是如果我
就会出现标准 Assets 效应Screen Space Ambient Obscurance不适用于正交相机。这很奇怪,因为基本 SSAO脚本工作得很好。我怀疑问题在于片段深度的计算错误。 有没有办
我需要 CG 片段着色器方面的帮助。我有一个大纹理可以容纳所有瓷砖。我真的不知道从哪里开始。 现在,当四边形/ Sprite 超过一定大小时,我需要重复纹理,因为它是一个纹理。 最佳答案 0Matth
对于运行时生成的着色器代码,我有兴趣探索是否可以直接自动生成编译的 Metal 着色器语言 (MSL) 代码(如 .metallib 文件,并与 newLibraryWithData:error: 方
我正在编写一个 PixelShader(HLSL、SM40)并尝试在某些情况下完全跳过输出。我当前的代码如下所示: float4 PS( PS_INPUT input) : SV_Target {
我有一个变量,它可以是负数也可以是正数。 确保它始终为正的一种方法是: if (var < 0) var = -var; 但是,我认为必须有一个着色器函数可以做到这一点。我正在使用 Cg,但是如果我知
在像素着色器中,您可以丢弃一个像素,但我想即使是为每个像素调用的快速失败着色器也需要花费大量时间?顶点着色器有什么办法可以丢弃整个三角形......我很确定VS无法访问图元但是有什么技巧可以让我们得到
我是一名优秀的程序员,十分优秀!