mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2026-10-13 00:08:26 +08:00
CUDA 13.2 samples update (#432)
- Added Python samples for CUDA Python 1.0 release - Renamed top-level `Samples` directory to `cpp` to accommodate Python samples.
This commit is contained in:
18
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/.vscode/c_cpp_properties.json
vendored
Normal file
18
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/../../../Common"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/local/cuda/bin/nvcc",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "gnu++14",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
7
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/.vscode/extensions.json
vendored
Normal file
7
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"nvidia.nsight-vscode-edition",
|
||||
"ms-vscode.cpptools",
|
||||
"ms-vscode.makefile-tools"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/Modules")
|
||||
|
||||
project(EGLStream_CUDA_Interop LANGUAGES C CXX CUDA)
|
||||
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(CMAKE_CUDA_ARCHITECTURES 75 80 86 87 89 90 100 110 120)
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Wno-deprecated-gpu-targets")
|
||||
if(ENABLE_CUDA_DEBUG)
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -G") # enable cuda-gdb (may significantly affect performance on some targets)
|
||||
else()
|
||||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -lineinfo") # add line information to all builds for debug tools (exclusive to -G option)
|
||||
endif()
|
||||
|
||||
# Include directories and libraries
|
||||
include_directories(../../../Common)
|
||||
|
||||
find_package(EGL)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# Source file
|
||||
if(${EGL_FOUND})
|
||||
# Add target for EGLStream_CUDA_Interop
|
||||
add_executable(EGLStream_CUDA_Interop cuda_consumer.cpp cuda_producer.cpp eglstrm_common.cpp main.cpp)
|
||||
|
||||
target_compile_options(EGLStream_CUDA_Interop PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:--extended-lambda>)
|
||||
|
||||
target_compile_features(EGLStream_CUDA_Interop PRIVATE cxx_std_17 cuda_std_17)
|
||||
|
||||
set_target_properties(EGLStream_CUDA_Interop PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
|
||||
|
||||
target_include_directories(EGLStream_CUDA_Interop PUBLIC
|
||||
${EGL_INCLUDE_DIR}
|
||||
${CUDAToolkit_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(EGLStream_CUDA_Interop
|
||||
${EGL_LIBRARY}
|
||||
CUDA::cuda_driver
|
||||
)
|
||||
|
||||
else()
|
||||
message(STATUS "EGL not found - will not build sample 'EGLStream_CUDA_Interop'")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Will not build sample EGLStream_CUDA_Interop - requires Linux OS")
|
||||
endif()
|
||||
|
||||
# Include installation configuration
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake/InstallSamples.cmake)
|
||||
setup_samples_install()
|
||||
@@ -0,0 +1,39 @@
|
||||
# EGLStream_CUDA_Interop - EGLStream CUDA Interop
|
||||
|
||||
## Description
|
||||
|
||||
Demonstrates data exchange between CUDA and EGL Streams.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
EGLStreams Interop
|
||||
|
||||
## Supported SM Architectures
|
||||
|
||||
[SM 5.0 ](https://developer.nvidia.com/cuda-gpus) [SM 5.2 ](https://developer.nvidia.com/cuda-gpus) [SM 5.3 ](https://developer.nvidia.com/cuda-gpus) [SM 6.0 ](https://developer.nvidia.com/cuda-gpus) [SM 6.1 ](https://developer.nvidia.com/cuda-gpus) [SM 7.0 ](https://developer.nvidia.com/cuda-gpus) [SM 7.2 ](https://developer.nvidia.com/cuda-gpus) [SM 7.5 ](https://developer.nvidia.com/cuda-gpus) [SM 8.0 ](https://developer.nvidia.com/cuda-gpus) [SM 8.6 ](https://developer.nvidia.com/cuda-gpus) [SM 8.7 ](https://developer.nvidia.com/cuda-gpus) [SM 8.9 ](https://developer.nvidia.com/cuda-gpus) [SM 9.0 ](https://developer.nvidia.com/cuda-gpus)
|
||||
|
||||
## Supported OSes
|
||||
|
||||
Linux
|
||||
|
||||
## Supported CPU Architecture
|
||||
|
||||
x86_64, aarch64
|
||||
|
||||
## CUDA APIs involved
|
||||
|
||||
### [CUDA Driver API](http://docs.nvidia.com/cuda/cuda-driver-api/index.html)
|
||||
cuMemcpyDtoH, cuDeviceGetName, cuEGLStreamConsumerReleaseFrame, cuEGLStreamConsumerConnect, cuEGLStreamConsumerDisconnect, cuCtxPushCurrent, cuArrayDestroy, cuEGLStreamProducerReturnFrame, cuEGLStreamProducerPresentFrame, cuMemFree, cuGraphicsResourceGetMappedEglFrame, cuInit, cuEGLStreamConsumerAcquireFrame, cuEGLStreamProducerDisconnect, cuDeviceGetCount, cuEGLStreamProducerConnect, cuDeviceGetAttribute, cuCtxSynchronize, cuMemAlloc, cuCtxPopCurrent, cuCtxCreate, cuMemcpy
|
||||
|
||||
### [CUDA Runtime API](http://docs.nvidia.com/cuda/cuda-runtime-api/index.html)
|
||||
cudaProducerReadYUVFrame, cudaProducerTest, cudaProducerDeinit, cudaDeviceCreateProducer, cudaProducerReadARGBFrame, cudaDeviceCreateConsumer, cudaConsumerTest, cudaProducerInit
|
||||
|
||||
## Dependencies needed to build/run
|
||||
[EGL](../../../README.md#egl)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Download and install the [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) for your corresponding platform.
|
||||
Make sure the dependencies mentioned in [Dependencies]() section above are installed.
|
||||
|
||||
## References (for more details)
|
||||
@@ -0,0 +1,329 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// DESCRIPTION: Simple CUDA consumer rendering sample app
|
||||
//
|
||||
|
||||
#include "cuda_consumer.h"
|
||||
|
||||
#include <helper_cuda_drvapi.h>
|
||||
|
||||
#include "eglstrm_common.h"
|
||||
|
||||
#if defined(EXTENSION_LIST)
|
||||
EXTENSION_LIST(EXTLST_EXTERN)
|
||||
#endif
|
||||
|
||||
int checkbuf(FILE *fp1, FILE *fp2);
|
||||
|
||||
CUresult cudaConsumerTest(test_cuda_consumer_s *data, const char *fileName)
|
||||
{
|
||||
CUresult cuStatus = CUDA_SUCCESS;
|
||||
CUarray cudaArr = NULL;
|
||||
CUeglFrame cudaEgl;
|
||||
CUgraphicsResource cudaResource;
|
||||
unsigned int i;
|
||||
int check_result;
|
||||
FILE *pInFile1 = NULL, *pInFile2 = NULL, *file_p = NULL;
|
||||
EGLint streamState = 0;
|
||||
|
||||
if (!data) {
|
||||
printf("%s: Bad parameter\n", __func__);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!eglQueryStreamKHR(g_display, eglStream, EGL_STREAM_STATE_KHR, &streamState)) {
|
||||
printf("Cuda consumer, eglQueryStreamKHR EGL_STREAM_STATE_KHR failed\n");
|
||||
}
|
||||
if (streamState == EGL_STREAM_STATE_DISCONNECTED_KHR) {
|
||||
printf("CUDA Consumer: - EGL_STREAM_STATE_DISCONNECTED_KHR received\n");
|
||||
}
|
||||
|
||||
if (streamState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) {
|
||||
cuStatus = cuEGLStreamConsumerAcquireFrame(&(data->cudaConn), &cudaResource, NULL, 16000);
|
||||
|
||||
if (cuStatus == CUDA_SUCCESS) {
|
||||
CUdeviceptr pDevPtr = 0;
|
||||
int bufferSize;
|
||||
unsigned char *pCudaCopyMem = NULL;
|
||||
unsigned int copyWidthInBytes = 0, copyHeight = 0;
|
||||
|
||||
file_p = fopen(fileName, "wb+");
|
||||
if (!file_p) {
|
||||
printf("WriteFrame: file open failed %s\n", fileName);
|
||||
cuStatus = CUDA_ERROR_UNKNOWN;
|
||||
goto done;
|
||||
}
|
||||
cuStatus = cuGraphicsResourceGetMappedEglFrame(&cudaEgl, cudaResource, 0, 0);
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("Cuda get resource failed with %d\n", cuStatus);
|
||||
goto done;
|
||||
}
|
||||
cuStatus = cuCtxSynchronize();
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuCtxSynchronize failed \n");
|
||||
goto done;
|
||||
}
|
||||
if (!(cudaEgl.planeCount >= 1 && cudaEgl.planeCount <= 3)) {
|
||||
printf("Plane count is invalid\nExiting\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < cudaEgl.planeCount; i++) {
|
||||
if (cudaEgl.frameType == CU_EGL_FRAME_TYPE_PITCH) {
|
||||
pDevPtr = (CUdeviceptr)cudaEgl.frame.pPitch[i];
|
||||
if (cudaEgl.planeCount == 1) {
|
||||
bufferSize = cudaEgl.pitch * cudaEgl.height;
|
||||
copyWidthInBytes = cudaEgl.pitch;
|
||||
copyHeight = data->height;
|
||||
}
|
||||
else if (i == 1 && cudaEgl.planeCount == 2) { // YUV 420
|
||||
// semi-planar
|
||||
bufferSize = cudaEgl.pitch * cudaEgl.height / 2;
|
||||
copyWidthInBytes = cudaEgl.pitch;
|
||||
copyHeight = data->height / 2;
|
||||
}
|
||||
else {
|
||||
bufferSize = data->width * data->height;
|
||||
copyWidthInBytes = data->width;
|
||||
copyHeight = data->height;
|
||||
if (i > 0) {
|
||||
bufferSize >>= 2;
|
||||
copyWidthInBytes >>= 1;
|
||||
copyHeight >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cudaArr = cudaEgl.frame.pArray[i];
|
||||
if (cudaEgl.planeCount == 1) {
|
||||
bufferSize = data->width * data->height * 4;
|
||||
copyWidthInBytes = data->width * 4;
|
||||
copyHeight = data->height;
|
||||
}
|
||||
else if (i == 1 && cudaEgl.planeCount == 2) { // YUV 420
|
||||
// semi-planar
|
||||
bufferSize = data->width * data->height / 2;
|
||||
copyWidthInBytes = data->width;
|
||||
copyHeight = data->height / 2;
|
||||
}
|
||||
else {
|
||||
bufferSize = data->width * data->height;
|
||||
copyWidthInBytes = data->width;
|
||||
copyHeight = data->height;
|
||||
if (i > 0) {
|
||||
bufferSize >>= 2;
|
||||
copyWidthInBytes >>= 1;
|
||||
copyHeight >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == 0) {
|
||||
pCudaCopyMem = (unsigned char *)malloc(bufferSize);
|
||||
if (pCudaCopyMem == NULL) {
|
||||
printf("pCudaCopyMem malloc failed\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
memset(pCudaCopyMem, 0, bufferSize);
|
||||
if (data->pitchLinearOutput) {
|
||||
cuStatus = cuMemcpyDtoH(pCudaCopyMem, pDevPtr, bufferSize);
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuda_consumer: pitch linear Memcpy failed, bufferSize =%d\n", bufferSize);
|
||||
goto done;
|
||||
}
|
||||
cuStatus = cuCtxSynchronize();
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuda_consumer: cuCtxSynchronize failed after memcpy \n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CUDA_MEMCPY3D cpdesc;
|
||||
memset(&cpdesc, 0, sizeof(cpdesc));
|
||||
cpdesc.srcXInBytes = cpdesc.srcY = cpdesc.srcZ = cpdesc.srcLOD = 0;
|
||||
cpdesc.srcMemoryType = CU_MEMORYTYPE_ARRAY;
|
||||
cpdesc.srcArray = cudaArr;
|
||||
cpdesc.dstXInBytes = cpdesc.dstY = cpdesc.dstZ = cpdesc.dstLOD = 0;
|
||||
cpdesc.dstMemoryType = CU_MEMORYTYPE_HOST;
|
||||
cpdesc.dstHost = (void *)pCudaCopyMem;
|
||||
cpdesc.WidthInBytes = copyWidthInBytes; // data->width * 4;
|
||||
cpdesc.Height = copyHeight; // data->height;
|
||||
cpdesc.Depth = 1;
|
||||
|
||||
cuStatus = cuMemcpy3D(&cpdesc);
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("Cuda consumer: cuMemCpy3D failed, copyWidthInBytes=%d, "
|
||||
"copyHight=%d\n",
|
||||
copyWidthInBytes,
|
||||
copyHeight);
|
||||
}
|
||||
cuStatus = cuCtxSynchronize();
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuCtxSynchronize failed after memcpy \n");
|
||||
}
|
||||
}
|
||||
if (cuStatus == CUDA_SUCCESS) {
|
||||
if (fwrite(pCudaCopyMem, bufferSize, 1, file_p) != 1) {
|
||||
printf("Cuda consumer: output file write failed\n");
|
||||
cuStatus = CUDA_ERROR_UNKNOWN;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
pInFile1 = fopen(data->fileName1, "rb");
|
||||
if (!pInFile1) {
|
||||
printf("Failed to open file :%s\n", data->fileName1);
|
||||
goto done;
|
||||
}
|
||||
pInFile2 = fopen(data->fileName2, "rb");
|
||||
if (!pInFile2) {
|
||||
printf("Failed to open file :%s\n", data->fileName2);
|
||||
goto done;
|
||||
}
|
||||
rewind(file_p);
|
||||
check_result = checkbuf(file_p, pInFile1);
|
||||
if (check_result == -1) {
|
||||
rewind(file_p);
|
||||
check_result = checkbuf(file_p, pInFile2);
|
||||
if (check_result == -1) {
|
||||
printf("Frame received does not match any valid image: FAILED\n");
|
||||
}
|
||||
else {
|
||||
printf("Frame check Passed\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Frame check Passed\n");
|
||||
}
|
||||
if (pCudaCopyMem) {
|
||||
free(pCudaCopyMem);
|
||||
pCudaCopyMem = NULL;
|
||||
}
|
||||
cuStatus = cuEGLStreamConsumerReleaseFrame(&data->cudaConn, cudaResource, NULL);
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuEGLStreamConsumerReleaseFrame failed with cuStatus = %d\n", cuStatus);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("cuda AcquireFrame FAILED with cuStatus=%d\n", cuStatus);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (file_p) {
|
||||
fclose(file_p);
|
||||
file_p = NULL;
|
||||
}
|
||||
if (pInFile1) {
|
||||
fclose(pInFile1);
|
||||
pInFile1 = NULL;
|
||||
}
|
||||
if (pInFile1) {
|
||||
fclose(pInFile2);
|
||||
pInFile2 = NULL;
|
||||
}
|
||||
return cuStatus;
|
||||
}
|
||||
|
||||
int checkbuf(FILE *fp1, FILE *fp2)
|
||||
{
|
||||
int match = 0;
|
||||
int ch1, ch2;
|
||||
if (fp1 == NULL) {
|
||||
printf("Invalid file pointer for first file\n");
|
||||
return -1;
|
||||
}
|
||||
else if (fp2 == NULL) {
|
||||
printf("Invalid file pointer for second file\n");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
ch1 = getc(fp1);
|
||||
ch2 = getc(fp2);
|
||||
while ((ch1 != EOF) && (ch2 != EOF) && (ch1 == ch2)) {
|
||||
ch1 = getc(fp1);
|
||||
ch2 = getc(fp2);
|
||||
}
|
||||
if (ch1 == ch2) {
|
||||
match = 1;
|
||||
}
|
||||
else if (ch1 != ch2) {
|
||||
match = -1;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
CUresult cudaDeviceCreateConsumer(test_cuda_consumer_s *cudaConsumer, CUdevice device)
|
||||
{
|
||||
CUresult status = CUDA_SUCCESS;
|
||||
if (CUDA_SUCCESS != (status = cuInit(0))) {
|
||||
printf("Failed to initialize CUDA\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
int major = 0, minor = 0;
|
||||
char deviceName[256];
|
||||
checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, device));
|
||||
checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, device));
|
||||
checkCudaErrors(cuDeviceGetName(deviceName, 256, device));
|
||||
printf("CUDA Consumer on GPU Device %d: \"%s\" with compute capability "
|
||||
"%d.%d\n\n",
|
||||
device,
|
||||
deviceName,
|
||||
major,
|
||||
minor);
|
||||
|
||||
CUctxCreateParams ctxCreateParams = {};
|
||||
if (CUDA_SUCCESS != (status = cuCtxCreate(&cudaConsumer->context, &ctxCreateParams, 0, device))) {
|
||||
printf("failed to create CUDA context\n");
|
||||
return status;
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaConsumer->context));
|
||||
return status;
|
||||
}
|
||||
|
||||
void cuda_consumer_init(test_cuda_consumer_s *cudaConsumer, TestArgs *args)
|
||||
{
|
||||
cudaConsumer->pitchLinearOutput = args->pitchLinearOutput;
|
||||
cudaConsumer->width = args->inputWidth;
|
||||
cudaConsumer->height = args->inputHeight;
|
||||
cudaConsumer->fileName1 = args->infile1;
|
||||
cudaConsumer->fileName2 = args->infile2;
|
||||
|
||||
cudaConsumer->outFile1 = const_cast<char *>("cuda_out1.yuv");
|
||||
cudaConsumer->outFile2 = const_cast<char *>("cuda_out2.yuv");
|
||||
}
|
||||
|
||||
CUresult cuda_consumer_deinit(test_cuda_consumer_s *cudaConsumer)
|
||||
{
|
||||
return cuEGLStreamConsumerDisconnect(&cudaConsumer->cudaConn);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// DESCRIPTION: CUDA consumer header file
|
||||
//
|
||||
|
||||
#ifndef _CUDA_CONSUMER_H_
|
||||
#define _CUDA_CONSUMER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cudaEGL.h"
|
||||
#include "eglstrm_common.h"
|
||||
|
||||
extern EGLStreamKHR eglStream;
|
||||
extern EGLDisplay g_display;
|
||||
|
||||
typedef struct _test_cuda_consumer_s
|
||||
{
|
||||
CUcontext context;
|
||||
CUeglStreamConnection cudaConn;
|
||||
bool pitchLinearOutput;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
const char *fileName1;
|
||||
const char *fileName2;
|
||||
const char *outFile1;
|
||||
const char *outFile2;
|
||||
unsigned int frameCount;
|
||||
} test_cuda_consumer_s;
|
||||
|
||||
void cuda_consumer_init(test_cuda_consumer_s *cudaConsumer, TestArgs *args);
|
||||
CUresult cuda_consumer_deinit(test_cuda_consumer_s *cudaConsumer);
|
||||
CUresult cudaConsumerTest(test_cuda_consumer_s *data, const char *outFile);
|
||||
CUresult cudaDeviceCreateConsumer(test_cuda_consumer_s *cudaConsumer, CUdevice device);
|
||||
#endif
|
||||
BIN
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/cuda_f_1.yuv
Executable file
BIN
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/cuda_f_1.yuv
Executable file
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,419 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// DESCRIPTION: Simple cuda EGL stream producer app
|
||||
//
|
||||
|
||||
#include "cuda_producer.h"
|
||||
|
||||
#include <helper_cuda_drvapi.h>
|
||||
|
||||
#include "cudaEGL.h"
|
||||
#include "eglstrm_common.h"
|
||||
|
||||
#if defined(EXTENSION_LIST)
|
||||
EXTENSION_LIST(EXTLST_EXTERN)
|
||||
#endif
|
||||
|
||||
static CUresult cudaProducerReadYUVFrame(FILE *file,
|
||||
unsigned int frameNum,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned char *pBuff)
|
||||
{
|
||||
int bOrderUV = 0;
|
||||
unsigned char *pYBuff, *pUBuff, *pVBuff, *pChroma;
|
||||
unsigned int frameSize = (width * height * 3) / 2;
|
||||
CUresult ret = CUDA_SUCCESS;
|
||||
unsigned int i;
|
||||
|
||||
if (!pBuff || !file)
|
||||
return CUDA_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
pYBuff = pBuff;
|
||||
|
||||
// YVU order in the buffer
|
||||
pVBuff = pYBuff + width * height;
|
||||
pUBuff = pVBuff + width * height / 4;
|
||||
|
||||
if (fseek(file, frameNum * frameSize, SEEK_SET)) {
|
||||
printf("ReadYUVFrame: Error seeking file: %p\n", file);
|
||||
ret = CUDA_ERROR_NOT_PERMITTED;
|
||||
goto done;
|
||||
}
|
||||
// read Y U V separately
|
||||
for (i = 0; i < height; i++) {
|
||||
if (fread(pYBuff, width, 1, file) != 1) {
|
||||
printf("ReadYUVFrame: Error reading file: %p\n", file);
|
||||
ret = CUDA_ERROR_NOT_PERMITTED;
|
||||
goto done;
|
||||
}
|
||||
pYBuff += width;
|
||||
}
|
||||
|
||||
pChroma = bOrderUV ? pUBuff : pVBuff;
|
||||
for (i = 0; i < height / 2; i++) {
|
||||
if (fread(pChroma, width / 2, 1, file) != 1) {
|
||||
printf("ReadYUVFrame: Error reading file: %p\n", file);
|
||||
ret = CUDA_ERROR_NOT_PERMITTED;
|
||||
goto done;
|
||||
}
|
||||
pChroma += width / 2;
|
||||
}
|
||||
|
||||
pChroma = bOrderUV ? pVBuff : pUBuff;
|
||||
for (i = 0; i < height / 2; i++) {
|
||||
if (fread(pChroma, width / 2, 1, file) != 1) {
|
||||
printf("ReadYUVFrame: Error reading file: %p\n", file);
|
||||
ret = CUDA_ERROR_NOT_PERMITTED;
|
||||
goto done;
|
||||
}
|
||||
pChroma += width / 2;
|
||||
}
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CUresult cudaProducerReadARGBFrame(FILE *file,
|
||||
unsigned int frameNum,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned char *pBuff)
|
||||
{
|
||||
unsigned int frameSize = width * height * 4;
|
||||
CUresult ret = CUDA_SUCCESS;
|
||||
|
||||
if (!pBuff || !file)
|
||||
return CUDA_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
if (fseek(file, frameNum * frameSize, SEEK_SET)) {
|
||||
printf("ReadYUVFrame: Error seeking file: %p\n", file);
|
||||
ret = CUDA_ERROR_NOT_PERMITTED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// read ARGB data
|
||||
if (fread(pBuff, frameSize, 1, file) != 1) {
|
||||
if (feof(file))
|
||||
printf("ReadARGBFrame: file read to the end\n");
|
||||
else
|
||||
printf("ReadARGBFrame: Error reading file: %p\n", file);
|
||||
ret = CUDA_ERROR_NOT_PERMITTED;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
CUresult cudaProducerTest(test_cuda_producer_s *cudaProducer, char *file)
|
||||
{
|
||||
int framenum = 0;
|
||||
CUarray cudaArr[3] = {0};
|
||||
CUdeviceptr cudaPtr[3] = {0, 0, 0};
|
||||
unsigned int bufferSize;
|
||||
CUresult cuStatus = CUDA_SUCCESS;
|
||||
unsigned int i, surfNum, uvOffset[3] = {0};
|
||||
unsigned int copyWidthInBytes[3] = {0, 0, 0}, copyHeight[3] = {0, 0, 0};
|
||||
CUeglColorFormat eglColorFormat;
|
||||
FILE *file_p;
|
||||
CUeglFrame cudaEgl;
|
||||
CUcontext oldContext;
|
||||
|
||||
file_p = fopen(file, "rb");
|
||||
if (!file_p) {
|
||||
printf("CudaProducer: Error opening file: %s\n", file);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cudaProducer->pitchLinearOutput) {
|
||||
if (cudaProducer->isARGB) {
|
||||
cudaPtr[0] = cudaProducer->cudaPtrARGB[0];
|
||||
}
|
||||
else { // YUV case
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (i == 0) {
|
||||
bufferSize = cudaProducer->width * cudaProducer->height;
|
||||
}
|
||||
else {
|
||||
bufferSize = cudaProducer->width * cudaProducer->height / 4;
|
||||
}
|
||||
|
||||
cudaPtr[i] = cudaProducer->cudaPtrYUV[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cudaProducer->isARGB) {
|
||||
cudaArr[0] = cudaProducer->cudaArrARGB[0];
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < 3; i++) {
|
||||
cudaArr[i] = cudaProducer->cudaArrYUV[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
uvOffset[0] = 0;
|
||||
if (cudaProducer->isARGB) {
|
||||
if (CUDA_SUCCESS
|
||||
!= cudaProducerReadARGBFrame(
|
||||
file_p, framenum, cudaProducer->width, cudaProducer->height, cudaProducer->pBuff)) {
|
||||
printf("cuda producer, read ARGB frame failed\n");
|
||||
goto done;
|
||||
}
|
||||
copyWidthInBytes[0] = cudaProducer->width * 4;
|
||||
copyHeight[0] = cudaProducer->height;
|
||||
surfNum = 1;
|
||||
eglColorFormat = CU_EGL_COLOR_FORMAT_ARGB;
|
||||
}
|
||||
else {
|
||||
if (CUDA_SUCCESS
|
||||
!= cudaProducerReadYUVFrame(
|
||||
file_p, framenum, cudaProducer->width, cudaProducer->height, cudaProducer->pBuff)) {
|
||||
printf("cuda producer, reading YUV frame failed\n");
|
||||
goto done;
|
||||
}
|
||||
surfNum = 3;
|
||||
eglColorFormat = CU_EGL_COLOR_FORMAT_YUV420_PLANAR;
|
||||
copyWidthInBytes[0] = cudaProducer->width;
|
||||
copyHeight[0] = cudaProducer->height;
|
||||
copyWidthInBytes[1] = cudaProducer->width / 2;
|
||||
copyHeight[1] = cudaProducer->height / 2;
|
||||
copyWidthInBytes[2] = cudaProducer->width / 2;
|
||||
copyHeight[2] = cudaProducer->height / 2;
|
||||
uvOffset[1] = cudaProducer->width * cudaProducer->height;
|
||||
uvOffset[2] = uvOffset[1] + cudaProducer->width / 2 * cudaProducer->height / 2;
|
||||
}
|
||||
if (cudaProducer->pitchLinearOutput) {
|
||||
for (i = 0; i < surfNum; i++) {
|
||||
cuStatus = cuMemcpy(
|
||||
cudaPtr[i], (CUdeviceptr)(cudaProducer->pBuff + uvOffset[i]), copyWidthInBytes[i] * copyHeight[i]);
|
||||
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("Cuda producer: cuMemCpy pitchlinear failed, cuStatus =%d\n", cuStatus);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// copy cudaProducer->pBuff to cudaArray
|
||||
CUDA_MEMCPY3D cpdesc;
|
||||
for (i = 0; i < surfNum; i++) {
|
||||
memset(&cpdesc, 0, sizeof(cpdesc));
|
||||
cpdesc.srcXInBytes = cpdesc.srcY = cpdesc.srcZ = cpdesc.srcLOD = 0;
|
||||
cpdesc.srcMemoryType = CU_MEMORYTYPE_HOST;
|
||||
cpdesc.srcHost = (void *)(cudaProducer->pBuff + uvOffset[i]);
|
||||
cpdesc.dstXInBytes = cpdesc.dstY = cpdesc.dstZ = cpdesc.dstLOD = 0;
|
||||
cpdesc.dstMemoryType = CU_MEMORYTYPE_ARRAY;
|
||||
cpdesc.dstArray = cudaArr[i];
|
||||
cpdesc.WidthInBytes = copyWidthInBytes[i];
|
||||
cpdesc.Height = copyHeight[i];
|
||||
cpdesc.Depth = 1;
|
||||
cuStatus = cuMemcpy3D(&cpdesc);
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("Cuda producer: cuMemCpy failed, cuStatus =%d\n", cuStatus);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < surfNum; i++) {
|
||||
if (cudaProducer->pitchLinearOutput)
|
||||
cudaEgl.frame.pPitch[i] = (void *)cudaPtr[i];
|
||||
else
|
||||
cudaEgl.frame.pArray[i] = cudaArr[i];
|
||||
}
|
||||
cudaEgl.width = copyWidthInBytes[0];
|
||||
cudaEgl.depth = 1;
|
||||
cudaEgl.height = copyHeight[0];
|
||||
cudaEgl.pitch = cudaProducer->pitchLinearOutput ? cudaEgl.width : 0;
|
||||
cudaEgl.frameType = cudaProducer->pitchLinearOutput ? CU_EGL_FRAME_TYPE_PITCH : CU_EGL_FRAME_TYPE_ARRAY;
|
||||
cudaEgl.planeCount = surfNum;
|
||||
cudaEgl.numChannels = (eglColorFormat == CU_EGL_COLOR_FORMAT_ARGB) ? 4 : 1;
|
||||
cudaEgl.eglColorFormat = eglColorFormat;
|
||||
cudaEgl.cuFormat = CU_AD_FORMAT_UNSIGNED_INT8;
|
||||
|
||||
static int numFramesPresented = 0;
|
||||
// If there is a frame presented before we check if consumer
|
||||
// is done with it using cuEGLStreamProducerReturnFrame.
|
||||
while (numFramesPresented) {
|
||||
CUeglFrame returnedCudaEgl;
|
||||
cuStatus = cuEGLStreamProducerReturnFrame(&cudaProducer->cudaConn, &returnedCudaEgl, NULL);
|
||||
if (cuStatus == CUDA_ERROR_LAUNCH_TIMEOUT) {
|
||||
continue;
|
||||
}
|
||||
else if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuda Producer return frame FAILED with custatus= %d\n", cuStatus);
|
||||
return cuStatus;
|
||||
}
|
||||
else {
|
||||
numFramesPresented--;
|
||||
}
|
||||
}
|
||||
|
||||
cuStatus = cuEGLStreamProducerPresentFrame(&cudaProducer->cudaConn, cudaEgl, NULL);
|
||||
if (cuStatus != CUDA_SUCCESS) {
|
||||
printf("cuda Producer present frame FAILED with custatus= %d\n", cuStatus);
|
||||
goto done;
|
||||
}
|
||||
numFramesPresented++;
|
||||
|
||||
done:
|
||||
if (file_p) {
|
||||
fclose(file_p);
|
||||
file_p = NULL;
|
||||
}
|
||||
|
||||
return cuStatus;
|
||||
}
|
||||
|
||||
CUresult cudaDeviceCreateProducer(test_cuda_producer_s *cudaProducer, CUdevice device)
|
||||
{
|
||||
CUresult status = CUDA_SUCCESS;
|
||||
if (CUDA_SUCCESS != (status = cuInit(0))) {
|
||||
printf("Failed to initialize CUDA\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
int major = 0, minor = 0;
|
||||
char deviceName[256];
|
||||
checkCudaErrors(cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, device));
|
||||
checkCudaErrors(cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, device));
|
||||
checkCudaErrors(cuDeviceGetName(deviceName, 256, device));
|
||||
printf("CUDA Producer on GPU Device %d: \"%s\" with compute capability "
|
||||
"%d.%d\n\n",
|
||||
device,
|
||||
deviceName,
|
||||
major,
|
||||
minor);
|
||||
|
||||
if (major < 6) {
|
||||
printf("EGLStream_CUDA_Interop requires SM 6.0 or higher arch GPU. "
|
||||
"Exiting...\n");
|
||||
exit(2); // EXIT_WAIVED
|
||||
}
|
||||
|
||||
CUctxCreateParams ctxCreateParams = {};
|
||||
if (CUDA_SUCCESS != (status = cuCtxCreate(&cudaProducer->context, &ctxCreateParams, 0, device))) {
|
||||
printf("failed to create CUDA context\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cuMemAlloc(&cudaProducer->cudaPtrARGB[0], (WIDTH * HEIGHT * 4));
|
||||
if (status != CUDA_SUCCESS) {
|
||||
printf("Create CUDA pointer failed, cuStatus=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cuMemAlloc(&cudaProducer->cudaPtrYUV[0], (WIDTH * HEIGHT));
|
||||
if (status != CUDA_SUCCESS) {
|
||||
printf("Create CUDA pointer failed, cuStatus=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
status = cuMemAlloc(&cudaProducer->cudaPtrYUV[1], (WIDTH * HEIGHT) / 4);
|
||||
if (status != CUDA_SUCCESS) {
|
||||
printf("Create CUDA pointer failed, cuStatus=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
status = cuMemAlloc(&cudaProducer->cudaPtrYUV[2], (WIDTH * HEIGHT) / 4);
|
||||
if (status != CUDA_SUCCESS) {
|
||||
printf("Create CUDA pointer failed, cuStatus=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
CUDA_ARRAY3D_DESCRIPTOR desc = {0};
|
||||
|
||||
desc.Format = CU_AD_FORMAT_UNSIGNED_INT8;
|
||||
desc.Depth = 1;
|
||||
desc.Flags = CUDA_ARRAY3D_SURFACE_LDST;
|
||||
desc.NumChannels = 4;
|
||||
desc.Width = WIDTH * 4;
|
||||
desc.Height = HEIGHT;
|
||||
status = cuArray3DCreate(&cudaProducer->cudaArrARGB[0], &desc);
|
||||
if (status != CUDA_SUCCESS) {
|
||||
printf("Create CUDA array failed, cuStatus=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (i == 0) {
|
||||
desc.NumChannels = 1;
|
||||
desc.Width = WIDTH;
|
||||
desc.Height = HEIGHT;
|
||||
}
|
||||
else { // U/V surface as planar
|
||||
desc.NumChannels = 1;
|
||||
desc.Width = WIDTH / 2;
|
||||
desc.Height = HEIGHT / 2;
|
||||
}
|
||||
status = cuArray3DCreate(&cudaProducer->cudaArrYUV[i], &desc);
|
||||
if (status != CUDA_SUCCESS) {
|
||||
printf("Create CUDA array failed, cuStatus=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
cudaProducer->pBuff = (unsigned char *)malloc((WIDTH * HEIGHT * 4));
|
||||
if (!cudaProducer->pBuff) {
|
||||
printf("CudaProducer: Failed to allocate image buffer\n");
|
||||
}
|
||||
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaProducer->context));
|
||||
return status;
|
||||
}
|
||||
|
||||
void cudaProducerInit(test_cuda_producer_s *cudaProducer, EGLDisplay eglDisplay, EGLStreamKHR eglStream, TestArgs *args)
|
||||
{
|
||||
cudaProducer->fileName1 = args->infile1;
|
||||
cudaProducer->fileName2 = args->infile2;
|
||||
|
||||
cudaProducer->frameCount = 2;
|
||||
cudaProducer->width = args->inputWidth;
|
||||
cudaProducer->height = args->inputHeight;
|
||||
cudaProducer->isARGB = args->isARGB;
|
||||
cudaProducer->pitchLinearOutput = args->pitchLinearOutput;
|
||||
|
||||
// Set cudaProducer default parameters
|
||||
cudaProducer->eglDisplay = eglDisplay;
|
||||
cudaProducer->eglStream = eglStream;
|
||||
}
|
||||
|
||||
CUresult cudaProducerDeinit(test_cuda_producer_s *cudaProducer)
|
||||
{
|
||||
if (cudaProducer->pBuff)
|
||||
free(cudaProducer->pBuff);
|
||||
|
||||
checkCudaErrors(cuMemFree(cudaProducer->cudaPtrARGB[0]));
|
||||
checkCudaErrors(cuMemFree(cudaProducer->cudaPtrYUV[0]));
|
||||
checkCudaErrors(cuMemFree(cudaProducer->cudaPtrYUV[1]));
|
||||
checkCudaErrors(cuMemFree(cudaProducer->cudaPtrYUV[2]));
|
||||
checkCudaErrors(cuArrayDestroy(cudaProducer->cudaArrARGB[0]));
|
||||
checkCudaErrors(cuArrayDestroy(cudaProducer->cudaArrYUV[0]));
|
||||
checkCudaErrors(cuArrayDestroy(cudaProducer->cudaArrYUV[1]));
|
||||
checkCudaErrors(cuArrayDestroy(cudaProducer->cudaArrYUV[2]));
|
||||
|
||||
return cuEGLStreamProducerDisconnect(&cudaProducer->cudaConn);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// DESCRIPTION: Simple cuda producer header file
|
||||
//
|
||||
|
||||
#ifndef _CUDA_PRODUCER_H_
|
||||
#define _CUDA_PRODUCER_H_
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "cudaEGL.h"
|
||||
#include "eglstrm_common.h"
|
||||
|
||||
extern EGLStreamKHR eglStream;
|
||||
extern EGLDisplay g_display;
|
||||
|
||||
typedef struct _test_cuda_producer_s
|
||||
{
|
||||
// Stream params
|
||||
char *fileName1;
|
||||
char *fileName2;
|
||||
unsigned char *pBuff;
|
||||
int frameCount;
|
||||
bool isARGB;
|
||||
bool pitchLinearOutput;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
CUcontext context;
|
||||
CUeglStreamConnection cudaConn;
|
||||
CUdeviceptr cudaPtrARGB[1];
|
||||
CUdeviceptr cudaPtrYUV[3];
|
||||
CUarray cudaArrARGB[1];
|
||||
CUarray cudaArrYUV[3];
|
||||
EGLStreamKHR eglStream;
|
||||
EGLDisplay eglDisplay;
|
||||
} test_cuda_producer_s;
|
||||
|
||||
void cudaProducerInit(test_cuda_producer_s *cudaProducer,
|
||||
EGLDisplay eglDisplay,
|
||||
EGLStreamKHR eglStream,
|
||||
TestArgs *args);
|
||||
CUresult cudaProducerTest(test_cuda_producer_s *parserArg, char *file);
|
||||
CUresult cudaProducerDeinit(test_cuda_producer_s *cudaProducer);
|
||||
CUresult cudaDeviceCreateProducer(test_cuda_producer_s *cudaProducer, CUdevice device);
|
||||
#endif
|
||||
BIN
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/cuda_yuv_f_1.yuv
Executable file
BIN
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/cuda_yuv_f_1.yuv
Executable file
Binary file not shown.
BIN
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/cuda_yuv_f_2.yuv
Executable file
BIN
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/cuda_yuv_f_2.yuv
Executable file
Binary file not shown.
@@ -0,0 +1,134 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// DESCRIPTION: Common egl stream functions
|
||||
//
|
||||
|
||||
#include "eglstrm_common.h"
|
||||
|
||||
EGLStreamKHR eglStream;
|
||||
EGLDisplay g_display;
|
||||
EGLAttrib cudaIndex;
|
||||
|
||||
#if defined(EXTENSION_LIST)
|
||||
EXTENSION_LIST(EXTLST_DECL)
|
||||
typedef void (*extlst_fnptr_t)(void);
|
||||
static struct
|
||||
{
|
||||
extlst_fnptr_t *fnptr;
|
||||
char const *name;
|
||||
} extensionList[] = {EXTENSION_LIST(EXTLST_ENTRY)};
|
||||
|
||||
int eglSetupExtensions(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < (sizeof(extensionList) / sizeof(*extensionList)); i++) {
|
||||
*extensionList[i].fnptr = eglGetProcAddress(extensionList[i].name);
|
||||
if (*extensionList[i].fnptr == NULL) {
|
||||
printf("Couldn't get address of %s()\n", extensionList[i].name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EGLStreamInit(int *cuda_device)
|
||||
{
|
||||
static const EGLint streamAttrMailboxMode[] = {EGL_SUPPORT_REUSE_NV, EGL_FALSE, EGL_NONE};
|
||||
EGLBoolean eglStatus;
|
||||
#define MAX_EGL_DEVICES 4
|
||||
EGLint numDevices = 0;
|
||||
EGLDeviceEXT devices[MAX_EGL_DEVICES];
|
||||
eglStatus = eglQueryDevicesEXT(MAX_EGL_DEVICES, devices, &numDevices);
|
||||
if (eglStatus != EGL_TRUE) {
|
||||
printf("Error querying EGL devices\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (numDevices == 0) {
|
||||
printf("No EGL devices found.. Waiving\n");
|
||||
eglStatus = EGL_FALSE;
|
||||
exit(EXIT_WAIVED);
|
||||
}
|
||||
|
||||
int egl_device_id = 0;
|
||||
for (egl_device_id = 0; egl_device_id < numDevices; egl_device_id++) {
|
||||
eglStatus = eglQueryDeviceAttribEXT(devices[egl_device_id], EGL_CUDA_DEVICE_NV, &cudaIndex);
|
||||
if (eglStatus == EGL_TRUE) {
|
||||
*cuda_device = cudaIndex; // We select first EGL-CUDA Capable device.
|
||||
printf("Found EGL-CUDA Capable device with CUDA Device id = %d\n", (int)cudaIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (egl_device_id >= numDevices) {
|
||||
printf("No CUDA Capable EGL Device found.. Waiving execution\n");
|
||||
exit(EXIT_WAIVED);
|
||||
}
|
||||
|
||||
g_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, (void *)devices[egl_device_id], NULL);
|
||||
if (g_display == EGL_NO_DISPLAY) {
|
||||
printf("Could not get EGL display from device. \n");
|
||||
eglStatus = EGL_FALSE;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
eglStatus = eglInitialize(g_display, 0, 0);
|
||||
if (!eglStatus) {
|
||||
printf("EGL failed to initialize. \n");
|
||||
eglStatus = EGL_FALSE;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
eglStream = eglCreateStreamKHR(g_display, streamAttrMailboxMode);
|
||||
if (eglStream == EGL_NO_STREAM_KHR) {
|
||||
printf("Could not create EGL stream.\n");
|
||||
eglStatus = EGL_FALSE;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Created EGLStream %p\n", eglStream);
|
||||
|
||||
// Set stream attribute
|
||||
if (!eglStreamAttribKHR(g_display, eglStream, EGL_CONSUMER_LATENCY_USEC_KHR, 16000)) {
|
||||
printf("Consumer: eglStreamAttribKHR EGL_CONSUMER_LATENCY_USEC_KHR failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (!eglStreamAttribKHR(g_display, eglStream, EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 16000)) {
|
||||
printf("Consumer: eglStreamAttribKHR EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR "
|
||||
"failed\n");
|
||||
return 0;
|
||||
}
|
||||
printf("EGLStream initialized\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EGLStreamFini(void) { eglDestroyStreamKHR(g_display, eglStream); }
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// DESCRIPTION: Common EGL stream functions header file
|
||||
//
|
||||
|
||||
#ifndef _EGLSTRM_COMMON_H_
|
||||
#define _EGLSTRM_COMMON_H_
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cuda.h"
|
||||
#include "cudaEGL.h"
|
||||
#include "helper_cuda_drvapi.h"
|
||||
|
||||
#define EXTENSION_LIST(T) \
|
||||
T(PFNEGLCREATESTREAMKHRPROC, eglCreateStreamKHR) \
|
||||
T(PFNEGLDESTROYSTREAMKHRPROC, eglDestroyStreamKHR) \
|
||||
T(PFNEGLQUERYSTREAMKHRPROC, eglQueryStreamKHR) \
|
||||
T(PFNEGLQUERYSTREAMU64KHRPROC, eglQueryStreamu64KHR) \
|
||||
T(PFNEGLQUERYSTREAMTIMEKHRPROC, eglQueryStreamTimeKHR) \
|
||||
T(PFNEGLSTREAMATTRIBKHRPROC, eglStreamAttribKHR) \
|
||||
T(PFNEGLSTREAMCONSUMERACQUIREKHRPROC, eglStreamConsumerAcquireKHR) \
|
||||
T(PFNEGLSTREAMCONSUMERRELEASEKHRPROC, eglStreamConsumerReleaseKHR) \
|
||||
T(PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC, eglStreamConsumerGLTextureExternalKHR) \
|
||||
T(PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC, eglGetStreamFileDescriptorKHR) \
|
||||
T(PFNEGLQUERYDEVICESEXTPROC, eglQueryDevicesEXT) \
|
||||
T(PFNEGLGETPLATFORMDISPLAYEXTPROC, eglGetPlatformDisplayEXT) \
|
||||
T(PFNEGLQUERYDEVICEATTRIBEXTPROC, eglQueryDeviceAttribEXT) \
|
||||
T(PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC, eglCreateStreamFromFileDescriptorKHR)
|
||||
|
||||
#define eglCreateStreamKHR my_eglCreateStreamKHR
|
||||
#define eglDestroyStreamKHR my_eglDestroyStreamKHR
|
||||
#define eglQueryStreamKHR my_eglQueryStreamKHR
|
||||
#define eglQueryStreamu64KHR my_eglQueryStreamu64KHR
|
||||
#define eglQueryStreamTimeKHR my_eglQueryStreamTimeKHR
|
||||
#define eglStreamAttribKHR my_eglStreamAttribKHR
|
||||
#define eglStreamConsumerAcquireKHR my_eglStreamConsumerAcquireKHR
|
||||
#define eglStreamConsumerReleaseKHR my_eglStreamConsumerReleaseKHR
|
||||
#define eglStreamConsumerGLTextureExternalKHR my_eglStreamConsumerGLTextureExternalKHR
|
||||
#define eglGetStreamFileDescriptorKHR my_eglGetStreamFileDescriptorKHR
|
||||
#define eglCreateStreamFromFileDescriptorKHR my_eglCreateStreamFromFileDescriptorKHR
|
||||
#define eglQueryDevicesEXT my_eglQueryDevicesEXT
|
||||
#define eglGetPlatformDisplayEXT my_eglGetPlatformDisplayEXT
|
||||
#define eglQueryDeviceAttribEXT my_eglQueryDeviceAttribEXT
|
||||
|
||||
#define EXTLST_DECL(tx, x) tx my_##x = NULL;
|
||||
#define EXTLST_EXTERN(tx, x) extern tx my_##x;
|
||||
#define EXTLST_ENTRY(tx, x) {(extlst_fnptr_t *)&my_##x, #x},
|
||||
|
||||
#define MAX_STRING_SIZE 256
|
||||
#define WIDTH 720
|
||||
#define HEIGHT 480
|
||||
|
||||
typedef struct _TestArgs
|
||||
{
|
||||
char *infile1;
|
||||
char *infile2;
|
||||
bool isARGB;
|
||||
unsigned int inputWidth;
|
||||
unsigned int inputHeight;
|
||||
bool pitchLinearOutput;
|
||||
} TestArgs;
|
||||
|
||||
int eglSetupExtensions(void);
|
||||
int EGLStreamInit(int *dev);
|
||||
void EGLStreamFini(void);
|
||||
#endif
|
||||
232
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/main.cpp
Normal file
232
cpp/2_Concepts_and_Techniques/EGLStream_CUDA_Interop/main.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
//
|
||||
// DESCRIPTION: Simple EGL stream sample app
|
||||
//
|
||||
//
|
||||
|
||||
// #define EGL_EGLEXT_PROTOTYPES
|
||||
|
||||
#include "cudaEGL.h"
|
||||
#include "cuda_consumer.h"
|
||||
#include "cuda_producer.h"
|
||||
#include "eglstrm_common.h"
|
||||
|
||||
/* ------ globals ---------*/
|
||||
|
||||
#if defined(EXTENSION_LIST)
|
||||
EXTENSION_LIST(EXTLST_EXTERN)
|
||||
#endif
|
||||
|
||||
#define NUM_TRAILS 4
|
||||
|
||||
bool signal_stop = 0;
|
||||
|
||||
static void sig_handler(int sig)
|
||||
{
|
||||
signal_stop = 1;
|
||||
printf("Signal: %d\n", sig);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestArgs args;
|
||||
CUresult curesult = CUDA_SUCCESS;
|
||||
unsigned int i, j;
|
||||
EGLint streamState = 0;
|
||||
|
||||
test_cuda_consumer_s cudaConsumer;
|
||||
test_cuda_producer_s cudaProducer;
|
||||
|
||||
memset(&cudaProducer, 0, sizeof(test_cuda_producer_s));
|
||||
memset(&cudaConsumer, 0, sizeof(test_cuda_consumer_s));
|
||||
|
||||
// Hook up Ctrl-C handler
|
||||
signal(SIGINT, sig_handler);
|
||||
if (!eglSetupExtensions()) {
|
||||
printf("SetupExtentions failed \n");
|
||||
curesult = CUDA_ERROR_UNKNOWN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
checkCudaErrors(cuInit(0));
|
||||
|
||||
int count;
|
||||
|
||||
checkCudaErrors(cuDeviceGetCount(&count));
|
||||
printf("Found %d cuda devices\n", count);
|
||||
|
||||
CUdevice devId;
|
||||
|
||||
if (!EGLStreamInit(&devId)) {
|
||||
printf("EGLStream Init failed.\n");
|
||||
curesult = CUDA_ERROR_UNKNOWN;
|
||||
goto done;
|
||||
}
|
||||
curesult = cudaDeviceCreateProducer(&cudaProducer, devId);
|
||||
if (curesult != CUDA_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
curesult = cudaDeviceCreateConsumer(&cudaConsumer, devId);
|
||||
if (curesult != CUDA_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaConsumer.context));
|
||||
if (CUDA_SUCCESS != (curesult = cuEGLStreamConsumerConnect(&(cudaConsumer.cudaConn), eglStream))) {
|
||||
printf("FAILED Connect CUDA consumer with error %d\n", curesult);
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
printf("Connected CUDA consumer, CudaConsumer %p\n", cudaConsumer.cudaConn);
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaConsumer.context));
|
||||
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaProducer.context));
|
||||
if (CUDA_SUCCESS == (curesult = cuEGLStreamProducerConnect(&(cudaProducer.cudaConn), eglStream, WIDTH, HEIGHT))) {
|
||||
printf("Connect CUDA producer Done, CudaProducer %p\n", cudaProducer.cudaConn);
|
||||
}
|
||||
else {
|
||||
printf("Connect CUDA producer FAILED with error %d\n", curesult);
|
||||
goto done;
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaProducer.context));
|
||||
|
||||
// Initialize producer
|
||||
for (i = 0; i < NUM_TRAILS; i++) {
|
||||
if (streamState != EGL_STREAM_STATE_CONNECTING_KHR) {
|
||||
if (!eglQueryStreamKHR(g_display, eglStream, EGL_STREAM_STATE_KHR, &streamState)) {
|
||||
printf("main: eglQueryStreamKHR EGL_STREAM_STATE_KHR failed\n");
|
||||
curesult = CUDA_ERROR_UNKNOWN;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
args.inputWidth = WIDTH;
|
||||
args.inputHeight = HEIGHT;
|
||||
if (i % 2 != 0) {
|
||||
args.isARGB = 1;
|
||||
args.infile1 = sdkFindFilePath("cuda_f_1.yuv", argv[0]);
|
||||
args.infile2 = sdkFindFilePath("cuda_f_2.yuv", argv[0]);
|
||||
}
|
||||
else {
|
||||
args.isARGB = 0;
|
||||
args.infile1 = sdkFindFilePath("cuda_yuv_f_1.yuv", argv[0]);
|
||||
args.infile2 = sdkFindFilePath("cuda_yuv_f_2.yuv", argv[0]);
|
||||
}
|
||||
if ((i % 4) < 2) {
|
||||
args.pitchLinearOutput = 1;
|
||||
}
|
||||
else {
|
||||
args.pitchLinearOutput = 0;
|
||||
}
|
||||
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaProducer.context));
|
||||
cudaProducerInit(&cudaProducer, g_display, eglStream, &args);
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaProducer.context));
|
||||
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaConsumer.context));
|
||||
cuda_consumer_init(&cudaConsumer, &args);
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaConsumer.context));
|
||||
|
||||
printf("main - Cuda Producer and Consumer Initialized.\n");
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
printf("Running for %s frame and %s input\n",
|
||||
args.isARGB ? "ARGB" : "YUV",
|
||||
args.pitchLinearOutput ? "Pitchlinear" : "BlockLinear");
|
||||
if (j == 0) {
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaProducer.context));
|
||||
curesult = cudaProducerTest(&cudaProducer, cudaProducer.fileName1);
|
||||
if (curesult != CUDA_SUCCESS) {
|
||||
printf("Cuda Producer Test failed for frame = %d\n", j + 1);
|
||||
goto done;
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaProducer.context));
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaConsumer.context));
|
||||
curesult = cudaConsumerTest(&cudaConsumer, cudaConsumer.outFile1);
|
||||
if (curesult != CUDA_SUCCESS) {
|
||||
printf("Cuda Consumer Test failed for frame = %d\n", j + 1);
|
||||
goto done;
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaConsumer.context));
|
||||
}
|
||||
else {
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaProducer.context));
|
||||
curesult = cudaProducerTest(&cudaProducer, cudaProducer.fileName2);
|
||||
if (curesult != CUDA_SUCCESS) {
|
||||
printf("Cuda Producer Test failed for frame = %d\n", j + 1);
|
||||
goto done;
|
||||
}
|
||||
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaProducer.context));
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaConsumer.context));
|
||||
curesult = cudaConsumerTest(&cudaConsumer, cudaConsumer.outFile2);
|
||||
if (curesult != CUDA_SUCCESS) {
|
||||
printf("Cuda Consumer Test failed for frame = %d\n", j + 1);
|
||||
goto done;
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaConsumer.context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkCudaErrors(cuCtxPushCurrent(cudaProducer.context));
|
||||
if (CUDA_SUCCESS != (curesult = cudaProducerDeinit(&cudaProducer))) {
|
||||
printf("Producer Disconnect FAILED. \n");
|
||||
goto done;
|
||||
}
|
||||
checkCudaErrors(cuCtxPopCurrent(&cudaProducer.context));
|
||||
|
||||
if (!eglQueryStreamKHR(g_display, eglStream, EGL_STREAM_STATE_KHR, &streamState)) {
|
||||
printf("Cuda consumer, eglQueryStreamKHR EGL_STREAM_STATE_KHR failed\n");
|
||||
curesult = CUDA_ERROR_UNKNOWN;
|
||||
goto done;
|
||||
}
|
||||
if (streamState != EGL_STREAM_STATE_DISCONNECTED_KHR) {
|
||||
if (CUDA_SUCCESS != (curesult = cuda_consumer_deinit(&cudaConsumer))) {
|
||||
printf("Consumer Disconnect FAILED.\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
printf("Producer and Consumer Disconnected \n");
|
||||
|
||||
done:
|
||||
if (!eglQueryStreamKHR(g_display, eglStream, EGL_STREAM_STATE_KHR, &streamState)) {
|
||||
printf("Cuda consumer, eglQueryStreamKHR EGL_STREAM_STATE_KHR failed\n");
|
||||
curesult = CUDA_ERROR_UNKNOWN;
|
||||
}
|
||||
if (streamState != EGL_STREAM_STATE_DISCONNECTED_KHR) {
|
||||
EGLStreamFini();
|
||||
}
|
||||
|
||||
if (curesult == CUDA_SUCCESS) {
|
||||
printf("&&&& EGLStream interop test PASSED\n");
|
||||
}
|
||||
else {
|
||||
printf("&&&& EGLStream interop test FAILED\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user