// TestNvidiaDxThreads.cpp : This file contains the ‘main’ function. Program execution begins and ends there.
//
#include “pch.h”
#include
#include
#include
#include
#include
#include
#include
#include // std::string
#include // std::cout
#include
#include <winerror.h>
#include <cuda.h>
#include <cuda_d3d11_interop.h>
#include <dxgi.h>
#include <d3d11.h>
void thread(int parm)
{
std::stringstream ss;
DXGI_ADAPTER_DESC adapterDesc;
try
{
CUresult res = cuInit(0);
if (res != CUDA_SUCCESS)
throw "Could not init Cuda";
IDXGIFactory1* pFactory1 = nullptr;
if(parm == 0)
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
if (SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory1)))
{
IDXGIAdapter1 * pAdapter1 = nullptr;
if (pFactory1->EnumAdapters1(parm, &pAdapter1) == DXGI_ERROR_NOT_FOUND)
throw "Adapter not found";
pAdapter1->GetDesc(&adapterDesc);
CUcontext ctx;
int cudaDevIx = -1;
auto ores = cudaD3D11GetDevice(&cudaDevIx, pAdapter1);
if (ores != cudaError::cudaSuccess)
return;
res = cuCtxCreate(&ctx, CU_CTX_SCHED_BLOCKING_SYNC, cudaDevIx);
if (res != CUDA_SUCCESS)
throw "Couldnt create cuda context";
res = cuCtxPushCurrent(ctx);
if (res != CUDA_SUCCESS)
throw "Couldnt push cuda context";
int m_flags = 0;
ID3D11Device* pDevice;
ID3D11DeviceContext* pContext;
HRESULT hRes = D3D11CreateDevice(pAdapter1,
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
m_flags,
NULL,
NULL,
D3D11_SDK_VERSION,
&pDevice,
NULL,
&pContext);
if (hRes != S_OK)
throw "Couldnt create device";
int height = 10;
const size_t totalNumberOfRows = 15;
const unsigned int bytesPrPixel = 1;
const unsigned int bytesPrReadOperation = 4;
ID3D11Texture2D* pTexture;
D3D11_TEXTURE2D_DESC TextureDesc;
memset(&TextureDesc, 0, sizeof(D3D11_TEXTURE2D_DESC));
TextureDesc.Width = 10;
TextureDesc.Height = 10;
TextureDesc.MipLevels = 1;
TextureDesc.ArraySize = 1;
TextureDesc.Format = DXGI_FORMAT::DXGI_FORMAT_NV12;
TextureDesc.SampleDesc.Count = 1;
TextureDesc.SampleDesc.Quality = 0;
TextureDesc.Usage = D3D11_USAGE_DEFAULT;
TextureDesc.CPUAccessFlags = 0;
TextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
TextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
hRes = pDevice->CreateTexture2D(&TextureDesc, nullptr, &pTexture);
if (hRes != S_OK)
throw "Couldnt create texture";
size_t pitch = 10;
uint8_t *rawPointer;
CUresult result = cuMemAllocPitch((CUdeviceptr *)(uintptr_t *)&rawPointer, &pitch, (size_t)10, totalNumberOfRows, bytesPrReadOperation);
if (result != CUDA_SUCCESS)
throw "couldnt allocate";
cudaGraphicsResource* pCudaResource;
auto cuError = cudaGraphicsD3D11RegisterResource(&pCudaResource, pTexture, CU_GRAPHICS_REGISTER_FLAGS_NONE);
if (cuError != cudaSuccess)
throw "couldnt register resource";
}
ss << "Device " << parm << " (" << std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(adapterDesc.Description) << ") succeeded\r\n";
}
catch (const char* s)
{
ss << "Device " << parm << "(" << std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(adapterDesc.Description) << "): " << s << "\r\n";
}
std::cout << ss.str();
}
int main()
{
std::vectorstd::thread threads;
for (int a = 0; a < 3; a++)
//for (int a = 3; a >=0 ; a--)
{
std::thread threadObj(thread, a);
threads.emplace_back(std::move(threadObj));
}
std::this_thread::sleep_for(std::chrono::milliseconds(100000));
for (auto &t : threads)
{
t.join();
}
}