Files
TheRock/rocm-systems/projects/clr/opencl/amdocl/cl_d3d9.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

284 lines
9.7 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#ifdef _WIN32
#include "top.hpp"
#include "cl_d3d9_amd.hpp"
#include "platform/command.hpp"
#include <cstring>
#include <utility>
RUNTIME_ENTRY(cl_int, clGetDeviceIDsFromDX9MediaAdapterKHR,
(cl_platform_id platform, cl_uint num_media_adapters,
cl_dx9_media_adapter_type_khr* media_adapters_type, void* media_adapters,
cl_dx9_media_adapter_set_khr media_adapter_set, cl_uint num_entries,
cl_device_id* devices, cl_uint* num_devices)) {
cl_int errcode;
// Accept an array of DX9 devices here as the spec mention of array of num_media_adapters size.
IDirect3DDevice9Ex** d3d9_device = static_cast<IDirect3DDevice9Ex**>(media_adapters);
cl_device_id* gpu_devices = NULL;
cl_uint num_gpu_devices = 0;
static const bool VALIDATE_ONLY = true;
if (platform != NULL && platform != AMD_PLATFORM) {
LogWarning("\"platform\" is not a valid AMD platform");
return CL_INVALID_PLATFORM;
}
// check if input parameter are correct
if ((num_media_adapters == 0) || (media_adapters_type == NULL) || (media_adapters == NULL) ||
(media_adapter_set != CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR &&
media_adapter_set != CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR) ||
(num_entries == 0 && devices != NULL)) {
return CL_INVALID_VALUE;
}
// Get GPU devices
errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 0, NULL, &num_gpu_devices);
if (errcode != CL_SUCCESS && errcode != CL_DEVICE_NOT_FOUND) {
return CL_INVALID_VALUE;
}
if (!num_gpu_devices) {
*not_null(num_devices) = 0;
return CL_DEVICE_NOT_FOUND;
}
switch (media_adapter_set) {
case CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR:
case CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR: {
gpu_devices = new cl_device_id[num_gpu_devices];
errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, num_gpu_devices, gpu_devices, NULL);
if (errcode != CL_SUCCESS) {
break;
}
std::vector<amd::Device*> compatible_devices;
for (cl_uint i = 0; i < num_gpu_devices; ++i) {
cl_device_id device = gpu_devices[i];
amd::Context::Flags context_flag;
amd::Context::DeviceFlagIdx devIdx;
switch (media_adapters_type[i]) {
case CL_ADAPTER_D3D9_KHR:
context_flag = amd::Context::Flags::D3D9DeviceKhr;
devIdx = amd::Context::DeviceFlagIdx::D3D9DeviceKhrIdx;
break;
case CL_ADAPTER_D3D9EX_KHR:
context_flag = amd::Context::Flags::D3D9DeviceEXKhr;
devIdx = amd::Context::DeviceFlagIdx::D3D9DeviceEXKhrIdx;
break;
case CL_ADAPTER_DXVA_KHR:
context_flag = amd::Context::Flags::D3D9DeviceVAKhr;
devIdx = amd::Context::DeviceFlagIdx::D3D9DeviceVAKhrIdx;
break;
}
for (cl_uint j = 0; j < num_media_adapters; ++j) {
// Since there can be multiple DX9 adapters passed in the array we need to validate
// interopability with each.
void* external_device[amd::Context::DeviceFlagIdx::LastDeviceFlagIdx] = {};
external_device[devIdx] = d3d9_device[j];
if (is_valid(device) && (media_adapters_type[j] == CL_ADAPTER_D3D9EX_KHR) &&
as_amd(device)->bindExternalDevice(context_flag, external_device, NULL,
VALIDATE_ONLY)) {
compatible_devices.push_back(as_amd(device));
}
}
}
if (compatible_devices.size() == 0) {
*not_null(num_devices) = 0;
errcode = CL_DEVICE_NOT_FOUND;
break;
}
auto it = compatible_devices.cbegin();
cl_uint compatible_count = std::min(num_entries, (cl_uint)compatible_devices.size());
while (compatible_count--) {
*devices++ = as_cl(*it++);
--num_entries;
}
while (num_entries--) {
*devices++ = (cl_device_id)0;
}
*not_null(num_devices) = (cl_uint)compatible_devices.size();
} break;
default:
LogWarning("\"d3d9_device_set\" is invalid");
errcode = CL_INVALID_VALUE;
}
delete[] gpu_devices;
return errcode;
}
RUNTIME_EXIT
RUNTIME_ENTRY_RET(cl_mem, clCreateFromDX9MediaSurfaceKHR,
(cl_context context, cl_mem_flags flags,
cl_dx9_media_adapter_type_khr adapter_type, void* surface_info, cl_uint plane,
cl_int* errcode_ret)) {
cl_mem clMemObj = NULL;
cl_dx9_surface_info_khr* cl_surf_info = NULL;
if (!is_valid(context)) {
*not_null(errcode_ret) = CL_INVALID_CONTEXT;
LogWarning("invalid parameter \"context\"");
return clMemObj;
}
if (!flags) flags = CL_MEM_READ_WRITE;
if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) ||
((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) ||
((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) {
*not_null(errcode_ret) = CL_INVALID_VALUE;
LogWarning("invalid parameter \"flags\"");
return clMemObj;
}
if ((adapter_type != CL_ADAPTER_D3D9_KHR) && (adapter_type != CL_ADAPTER_D3D9EX_KHR) &&
(adapter_type != CL_ADAPTER_DXVA_KHR)) {
*not_null(errcode_ret) = CL_INVALID_VALUE;
return clMemObj;
}
if (!surface_info) {
*not_null(errcode_ret) = CL_INVALID_VALUE;
LogWarning("parameter \"pD3DResource\" is a NULL pointer");
return clMemObj;
}
cl_surf_info = (cl_dx9_surface_info_khr*)surface_info;
IDirect3DSurface9* pD3D9Resource = cl_surf_info->resource;
HANDLE shared_handle = cl_surf_info->shared_handle;
if (!pD3D9Resource) {
*not_null(errcode_ret) = CL_INVALID_VALUE;
LogWarning("parameter \"surface_info\" is a NULL pointer");
return clMemObj;
}
D3DSURFACE_DESC Desc;
pD3D9Resource->GetDesc(&Desc);
if ((Desc.Format != D3DFMT_NV_12) && (Desc.Format != D3DFMT_P010) &&
(Desc.Format != D3DFMT_YV_12) && (plane != 0)) {
*not_null(errcode_ret) = CL_INVALID_VALUE;
LogWarning("The plane has to be Zero if the surface format is non-planar !");
return clMemObj;
}
// Check for image support
const std::vector<amd::Device*>& devices = as_amd(context)->devices();
bool supportPass = false;
bool sizePass = false;
for (const auto& it : devices) {
if (it->info().imageSupport_) {
supportPass = true;
}
}
if (!supportPass) {
*not_null(errcode_ret) = CL_INVALID_OPERATION;
LogWarning("there are no devices in context to support images");
return (cl_mem)0;
}
// Verify the resource is a 2D image
return amd::clCreateImage2DFromD3D9ResourceAMD(*as_amd(context), flags, adapter_type,
cl_surf_info, plane, errcode_ret);
}
RUNTIME_EXIT
RUNTIME_ENTRY(cl_int, clEnqueueAcquireDX9MediaSurfacesKHR,
(cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects,
cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) {
return amd::clDXTranslateErrorCode(amd::clEnqueueAcquireExtObjectsAMD(
command_queue, num_objects, mem_objects, num_events_in_wait_list, event_wait_list, event,
CL_COMMAND_ACQUIRE_DX9_MEDIA_SURFACES_KHR));
}
RUNTIME_EXIT
RUNTIME_ENTRY(cl_int, clEnqueueReleaseDX9MediaSurfacesKHR,
(cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects,
cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) {
return amd::clDXTranslateErrorCode(amd::clEnqueueReleaseExtObjectsAMD(
command_queue, num_objects, mem_objects, num_events_in_wait_list, event_wait_list, event,
CL_COMMAND_RELEASE_DX9_MEDIA_SURFACES_KHR));
}
RUNTIME_EXIT
//
// clCreateImage2DFromD3D9ResourceAMD
//
cl_mem amd::clCreateImage2DFromD3D9ResourceAMD(amd::Context& amdContext, cl_mem_flags flags,
cl_dx9_media_adapter_type_khr adapter_type,
cl_dx9_surface_info_khr* surface_info, cl_uint plane,
int* errcode_ret) {
cl_dx9_surface_info_khr* cl_surf_info = reinterpret_cast<cl_dx9_surface_info_khr*>(surface_info);
IDirect3DSurface9* pD3D9Resource = cl_surf_info->resource;
HANDLE shared_handle = cl_surf_info->shared_handle;
amd::D3D9Object obj;
cl_int errcode =
amd::D3D9Object::initD3D9Object(amdContext, adapter_type, surface_info, plane, obj);
if (CL_SUCCESS != errcode) {
*not_null(errcode_ret) = errcode;
return (cl_mem)0;
}
amd::Image2DD3D9* pImage2DD3D9 = new (amdContext) amd::Image2DD3D9(amdContext, flags, obj);
if (!pImage2DD3D9) {
*not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY;
return (cl_mem)0;
}
if (!pImage2DD3D9->create()) {
*not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE;
pImage2DD3D9->release();
return (cl_mem)0;
}
*not_null(errcode_ret) = CL_SUCCESS;
return as_cl<amd::Memory>(pImage2DD3D9);
}
//
// Helper function SyncD3D9Objects
//
void amd::SyncD3D9Objects(std::vector<amd::Memory*>& memObjects) {
amd::Memory*& mem = memObjects.front();
if (!mem) {
LogWarning("\nNULL memory object\n");
return;
}
amd::InteropObject* interop = mem->getInteropObj();
if (!interop) {
LogWarning("\nNULL interop object\n");
return;
}
amd::D3D9Object* d3d9Obj = interop->asD3D9Object();
if (!d3d9Obj) {
LogWarning("\nNULL D3D9 object\n");
return;
}
IDirect3DQuery9* query = d3d9Obj->getQuery();
if (!query) {
LogWarning("\nNULL IDirect3DQuery9\n");
return;
}
amd::ScopedLock sl(d3d9Obj->getResLock());
query->Issue(D3DISSUE_END);
BOOL data = FALSE;
while (S_OK != query->GetData(&data, sizeof(BOOL), D3DGETDATA_FLUSH)) {
}
}
#endif //_WIN32