Я работаю над прототипом, который объединяет WPF, Direct3D9 (с использованием класса D3DImage WPF от Microsoft) и CUDA (мне нужно иметь возможность генерировать текстуру для D3DImage на графическом процессоре).Обновите текстуру D3D9 от CUDA
Проблема в том, что CUDA не обновляет мою текстуру. Коды ошибок не возвращаются, текстура остается неизменной. Даже если я прочитаю после своей собственной записи, я не вижу никаких изменений. Как обновить текстуру D3D9?
Я даже не запускаю ядра CUDA для целей отладки. Я использую только cuMemcpy2D API для записи CUDA-памяти путем копирования некоторых поддельных данных из CPU.
Вот код, это C#, но я поставил родной API, в комментариях:
static void updateTexture(Texture tx)
{
var size = tx.getSize();
using(CudaDirectXInteropResource res = new CudaDirectXInteropResource(tx.NativePointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D9)) // cuGraphicsD3D9RegisterResource
{
res.Map(); // = cuGraphicsMapResources
using(CudaArray2D arr = res.GetMappedArray2D(0, 0)) // cuGraphicsSubResourceGetMappedArray, cuArrayGetDescriptor. The size is correct here, BTW
{
// Debug code below - don't run any kernels for now, just call cuMemcpy2D to write the GPU memory
uint[] arrWhite = new uint[ size.Width * size.Height ];
for(int i = 0; i < arrWhite.Length; i++)
arrWhite[ i ] = 0xFF0000FF;
arr.CopyFromHostToThis(arrWhite); // cuMemcpy2D
uint[] test = new uint[ size.Width * size.Height ];
arr.CopyFromThisToHost(test); // The values here are correct
}
res.UnMap(); // cuGraphicsUnmapResources
}
tx.AddDirtyRectangle();
// Map again and check what's in the resource
using(CudaDirectXInteropResource res = new CudaDirectXInteropResource(tx.NativePointer, CUGraphicsRegisterFlags.None, CudaContext.DirectXVersion.D3D9))
{
res.Map();
using(CudaArray2D arr = res.GetMappedArray2D(0, 0))
{
uint[] test = new uint[ size.Width * size.Height ];
arr.CopyFromThisToHost(test); // All zeros :-(
Debug.WriteLine("First pixel: {0:X}", test[ 0 ]);
}
res.UnMap();
}
}
Вы пробовали разные CUGraphicsRegisterFlags, такие как WriteDiscard или SurfaceLDST, чтобы явно указать cuda, что вы напишете текстуру? И CudaDirectXInteropResource должен создаваться только один раз в жизни вашей текстуры DirectX (для регистрации ресурсов стоит дорого) – kunzmi
@kunzmi спасибо, вторая часть вашего комментария (где вы сказали о том, что вы думаете, это просто проблема производительности с моим кодом), была действительно полезно. – Soonts