Add Chromium-only Blender WebEngine parity work
This commit is contained in:
325
blender-5.2.0/intern/cycles/device/hip/device.cpp
Normal file
325
blender-5.2.0/intern/cycles/device/hip/device.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "device/hip/device.h"
|
||||
#include "device/device.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#ifdef WITH_HIP
|
||||
# include "device/hip/device_impl.h"
|
||||
|
||||
# include "integrator/denoiser_oidn_gpu.h" // IWYU pragma: keep
|
||||
|
||||
# include "util/string.h"
|
||||
# ifdef _WIN32
|
||||
# include "util/windows.h"
|
||||
# endif
|
||||
#endif /* WITH_HIP */
|
||||
|
||||
#ifdef WITH_HIPRT
|
||||
# include "device/hiprt/device_impl.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
bool device_hip_init()
|
||||
{
|
||||
#if !defined(WITH_HIP)
|
||||
return false;
|
||||
#elif defined(WITH_HIP_DYNLOAD)
|
||||
static bool initialized = false;
|
||||
static bool result = false;
|
||||
|
||||
if (initialized) {
|
||||
return result;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
int hipew_result = hipewInit(HIPEW_INIT_HIP);
|
||||
|
||||
if (hipew_result == HIPEW_SUCCESS) {
|
||||
LOG_INFO << "HIPEW initialization succeeded";
|
||||
if (!hipSupportsDriver()) {
|
||||
LOG_WARNING << "Driver version is too old";
|
||||
}
|
||||
else if (HIPDevice::have_precompiled_kernels()) {
|
||||
LOG_INFO << "Found precompiled kernels";
|
||||
result = true;
|
||||
}
|
||||
else if (hipewCompilerPath() != nullptr) {
|
||||
LOG_INFO << "Found HIPCC " << hipewCompilerPath();
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
LOG_INFO << "Neither precompiled kernels nor HIPCC was found,"
|
||||
<< " unable to use HIP";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (hipew_result == HIPEW_ERROR_ATEXIT_FAILED) {
|
||||
LOG_WARNING << "HIPEW initialization failed: Error setting up atexit() handler";
|
||||
}
|
||||
else if (hipew_result == HIPEW_ERROR_OLD_DRIVER) {
|
||||
LOG_WARNING << "HIPEW initialization failed: Driver version too old, requires AMD Adrenalin "
|
||||
"driver 24.9.1 or newer, or AMD Radeon Pro driver 24.Q4 or newer";
|
||||
}
|
||||
else {
|
||||
LOG_WARNING << "HIPEW initialization failed: Error opening HIP dynamic library";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
#else /* WITH_HIP_DYNLOAD */
|
||||
return true;
|
||||
#endif /* WITH_HIP_DYNLOAD */
|
||||
}
|
||||
|
||||
unique_ptr<Device> device_hip_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
const bool headless)
|
||||
{
|
||||
#ifdef WITH_HIPRT
|
||||
if (info.use_hardware_raytracing) {
|
||||
return make_unique<HIPRTDevice>(info, stats, profiler, headless);
|
||||
}
|
||||
return make_unique<HIPDevice>(info, stats, profiler, headless);
|
||||
#elif defined(WITH_HIP)
|
||||
return make_unique<HIPDevice>(info, stats, profiler, headless);
|
||||
#else
|
||||
(void)info;
|
||||
(void)stats;
|
||||
(void)profiler;
|
||||
(void)headless;
|
||||
|
||||
LOG_FATAL << "Request to create HIP device without compiled-in support. Should never happen.";
|
||||
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WITH_HIP
|
||||
static hipError_t device_hip_safe_init()
|
||||
{
|
||||
# ifdef _WIN32
|
||||
__try
|
||||
{
|
||||
return hipInit(0);
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* Ignore crashes inside the HIP driver and hope we can
|
||||
* survive even with corrupted HIP installs. */
|
||||
fprintf(stderr, "Cycles HIP: driver crashed, continuing without HIP.\n");
|
||||
}
|
||||
|
||||
return hipErrorNoDevice;
|
||||
# else
|
||||
return hipInit(0);
|
||||
# endif
|
||||
}
|
||||
#endif /* WITH_HIP */
|
||||
|
||||
void device_hip_info(vector<DeviceInfo> &devices)
|
||||
{
|
||||
#ifdef WITH_HIP
|
||||
hipError_t result = device_hip_safe_init();
|
||||
if (result != hipSuccess) {
|
||||
if (result != hipErrorNoDevice) {
|
||||
LOG_ERROR << "HIP hipInit: " << hipewErrorString(result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
result = hipGetDeviceCount(&count);
|
||||
if (result != hipSuccess) {
|
||||
LOG_ERROR << "HIP hipGetDeviceCount: " << hipewErrorString(result);
|
||||
return;
|
||||
}
|
||||
|
||||
# ifdef WITH_HIPRT
|
||||
const bool has_hardware_raytracing = HIPRTDevice::is_supported();
|
||||
# else
|
||||
const bool has_hardware_raytracing = false;
|
||||
# endif
|
||||
|
||||
vector<DeviceInfo> display_devices;
|
||||
|
||||
for (int num = 0; num < count; num++) {
|
||||
char name[256];
|
||||
|
||||
result = hipDeviceGetName(name, 256, num);
|
||||
if (result != hipSuccess) {
|
||||
LOG_ERROR << "HIP hipDeviceGetName: " << hipewErrorString(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hipSupportsDevice(num)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DeviceInfo info;
|
||||
|
||||
info.type = DEVICE_HIP;
|
||||
info.description = string(name);
|
||||
info.num = num;
|
||||
|
||||
info.has_nanovdb = true;
|
||||
|
||||
info.has_gpu_queue = true;
|
||||
/* Check if the device has P2P access to any other device in the system. */
|
||||
for (int peer_num = 0; peer_num < count && !info.has_peer_memory; peer_num++) {
|
||||
if (num != peer_num) {
|
||||
if (hipSupportsDevice(peer_num)) {
|
||||
int can_access = 0;
|
||||
hipDeviceCanAccessPeer(&can_access, num, peer_num);
|
||||
info.has_peer_memory = (can_access != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable on RDNA1 due to bug rendering curves in HIP-RT 2.5 or HIP SDK 6.3. */
|
||||
info.use_hardware_raytracing = has_hardware_raytracing && hipIsRDNA2OrNewer(num);
|
||||
|
||||
int pci_location[3] = {0, 0, 0};
|
||||
hipDeviceGetAttribute(&pci_location[0], hipDeviceAttributePciDomainID, num);
|
||||
hipDeviceGetAttribute(&pci_location[1], hipDeviceAttributePciBusId, num);
|
||||
hipDeviceGetAttribute(&pci_location[2], hipDeviceAttributePciDeviceId, num);
|
||||
info.id = string_printf("HIP_%s_%04x:%02x:%02x",
|
||||
name,
|
||||
(unsigned int)pci_location[0],
|
||||
(unsigned int)pci_location[1],
|
||||
(unsigned int)pci_location[2]);
|
||||
|
||||
info.denoisers = 0;
|
||||
# if defined(WITH_OPENIMAGEDENOISE)
|
||||
/* Check first if OIDN supports it, not doing so can crash the HIP driver with
|
||||
* "hipErrorNoBinaryForGpu: Unable to find code object for all current devices". */
|
||||
# if OIDN_VERSION >= 20300
|
||||
if (hipSupportsDeviceOIDN(num) && oidnIsHIPDeviceSupported(num)) {
|
||||
# else
|
||||
if (hipSupportsDeviceOIDN(num) && OIDNDenoiserGPU::is_device_supported(info)) {
|
||||
# endif
|
||||
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* If device has a kernel timeout and no compute preemption, we assume
|
||||
* it is connected to a display and will freeze the display while doing
|
||||
* computations. */
|
||||
int timeout_attr = 0;
|
||||
hipDeviceGetAttribute(&timeout_attr, hipDeviceAttributeKernelExecTimeout, num);
|
||||
|
||||
if (timeout_attr) {
|
||||
LOG_INFO << "Device is recognized as display.";
|
||||
info.description += " (Display)";
|
||||
info.display_device = true;
|
||||
display_devices.push_back(info);
|
||||
}
|
||||
else {
|
||||
LOG_INFO << "Device has compute preemption or is not used for display.";
|
||||
devices.push_back(info);
|
||||
}
|
||||
|
||||
LOG_INFO << "Added device \"" << info.description << "\" with id \"" << info.id << "\".";
|
||||
|
||||
if (info.denoisers & DENOISER_OPENIMAGEDENOISE) {
|
||||
LOG_INFO << "Device with id \"" << info.id << "\" supports "
|
||||
<< denoiserTypeToHumanReadable(DENOISER_OPENIMAGEDENOISE) << ".";
|
||||
}
|
||||
}
|
||||
|
||||
if (!display_devices.empty()) {
|
||||
devices.insert(devices.end(), display_devices.begin(), display_devices.end());
|
||||
}
|
||||
#else /* WITH_HIP */
|
||||
(void)devices;
|
||||
#endif /* WITH_HIP */
|
||||
}
|
||||
|
||||
string device_hip_capabilities()
|
||||
{
|
||||
#ifdef WITH_HIP
|
||||
hipError_t result = device_hip_safe_init();
|
||||
if (result != hipSuccess) {
|
||||
if (result != hipErrorNoDevice) {
|
||||
return string("Error initializing HIP: ") + hipewErrorString(result);
|
||||
}
|
||||
return "No HIP device found\n";
|
||||
}
|
||||
|
||||
int count;
|
||||
result = hipGetDeviceCount(&count);
|
||||
if (result != hipSuccess) {
|
||||
return string("Error getting devices: ") + hipewErrorString(result);
|
||||
}
|
||||
|
||||
string capabilities;
|
||||
for (int num = 0; num < count; num++) {
|
||||
char name[256];
|
||||
if (hipDeviceGetName(name, 256, num) != hipSuccess) {
|
||||
continue;
|
||||
}
|
||||
capabilities += string("\t") + name + "\n";
|
||||
int value;
|
||||
# define GET_ATTR(attr) \
|
||||
{ \
|
||||
if (hipDeviceGetAttribute(&value, hipDeviceAttribute##attr, num) == hipSuccess) { \
|
||||
capabilities += string_printf("\t\thipDeviceAttribute" #attr "\t\t\t%d\n", value); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
/* TODO(sergey): Strip all attributes which are not useful for us
|
||||
* or does not depend on the driver.
|
||||
*/
|
||||
GET_ATTR(MaxThreadsPerBlock);
|
||||
GET_ATTR(MaxBlockDimX);
|
||||
GET_ATTR(MaxBlockDimY);
|
||||
GET_ATTR(MaxBlockDimZ);
|
||||
GET_ATTR(MaxGridDimX);
|
||||
GET_ATTR(MaxGridDimY);
|
||||
GET_ATTR(MaxGridDimZ);
|
||||
GET_ATTR(MaxSharedMemoryPerBlock);
|
||||
GET_ATTR(TotalConstantMemory);
|
||||
GET_ATTR(WarpSize);
|
||||
GET_ATTR(MaxPitch);
|
||||
GET_ATTR(MaxRegistersPerBlock);
|
||||
GET_ATTR(ClockRate);
|
||||
GET_ATTR(TextureAlignment);
|
||||
GET_ATTR(MultiprocessorCount);
|
||||
GET_ATTR(KernelExecTimeout);
|
||||
GET_ATTR(Integrated);
|
||||
GET_ATTR(CanMapHostMemory);
|
||||
GET_ATTR(ComputeMode);
|
||||
GET_ATTR(MaxTexture1DWidth);
|
||||
GET_ATTR(MaxTexture2DWidth);
|
||||
GET_ATTR(MaxTexture2DHeight);
|
||||
GET_ATTR(MaxTexture3DWidth);
|
||||
GET_ATTR(MaxTexture3DHeight);
|
||||
GET_ATTR(MaxTexture3DDepth);
|
||||
GET_ATTR(ConcurrentKernels);
|
||||
GET_ATTR(EccEnabled);
|
||||
GET_ATTR(MemoryClockRate);
|
||||
GET_ATTR(MemoryBusWidth);
|
||||
GET_ATTR(L2CacheSize);
|
||||
GET_ATTR(MaxThreadsPerMultiProcessor);
|
||||
GET_ATTR(ComputeCapabilityMajor);
|
||||
GET_ATTR(ComputeCapabilityMinor);
|
||||
GET_ATTR(MaxSharedMemoryPerMultiprocessor);
|
||||
GET_ATTR(ManagedMemory);
|
||||
GET_ATTR(IsMultiGpuBoard);
|
||||
# undef GET_ATTR
|
||||
capabilities += "\n";
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
|
||||
#else /* WITH_HIP */
|
||||
return "";
|
||||
#endif /* WITH_HIP */
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
29
blender-5.2.0/intern/cycles/device/hip/device.h
Normal file
29
blender-5.2.0/intern/cycles/device/hip/device.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Device;
|
||||
class DeviceInfo;
|
||||
class Profiler;
|
||||
class Stats;
|
||||
|
||||
bool device_hip_init();
|
||||
|
||||
unique_ptr<Device> device_hip_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_hip_info(vector<DeviceInfo> &devices);
|
||||
|
||||
string device_hip_capabilities();
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
1027
blender-5.2.0/intern/cycles/device/hip/device_impl.cpp
Normal file
1027
blender-5.2.0/intern/cycles/device/hip/device_impl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
112
blender-5.2.0/intern/cycles/device/hip/device_impl.h
Normal file
112
blender-5.2.0/intern/cycles/device/hip/device_impl.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/device.h"
|
||||
# include "device/hip/kernel.h"
|
||||
# include "device/hip/queue.h"
|
||||
# include "device/hip/util.h"
|
||||
|
||||
# ifdef WITH_HIP_DYNLOAD
|
||||
# include "hipew.h"
|
||||
# endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class DeviceQueue;
|
||||
|
||||
class HIPDevice : public GPUDevice {
|
||||
|
||||
friend class HIPContextScope;
|
||||
|
||||
public:
|
||||
hipDevice_t hipDevice;
|
||||
hipCtx_t hipContext;
|
||||
hipModule_t hipModule;
|
||||
int pitch_alignment;
|
||||
int hipDevId;
|
||||
int hipDevArchitecture;
|
||||
int hipRuntimeVersion;
|
||||
bool first_error;
|
||||
|
||||
HIPDeviceKernels kernels;
|
||||
|
||||
static bool have_precompiled_kernels();
|
||||
|
||||
BVHLayoutMask get_bvh_layout_mask(uint /*kernel_features*/) const override;
|
||||
|
||||
void set_error(const string &error) override;
|
||||
|
||||
HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless);
|
||||
|
||||
~HIPDevice() override;
|
||||
|
||||
bool support_device(const uint /*kernel_features*/);
|
||||
|
||||
bool check_peer_access(Device *peer_device) override;
|
||||
|
||||
bool use_adaptive_compilation();
|
||||
|
||||
string compile_kernel_get_common_cflags(const uint kernel_features);
|
||||
|
||||
string compile_kernel(const uint kernel_features, const char *name, const char *base = "hip");
|
||||
|
||||
bool load_kernels(const uint kernel_features) override;
|
||||
void reserve_local_memory(const uint kernel_features);
|
||||
|
||||
/* All memory types. */
|
||||
void mem_alloc(device_memory &mem) override;
|
||||
void mem_copy_to(device_memory &mem) override;
|
||||
void mem_move_to_host(device_memory &mem) override;
|
||||
void mem_copy_from(
|
||||
device_memory &mem, const size_t y, size_t w, const size_t h, size_t elem) override;
|
||||
void mem_zero(device_memory &mem) override;
|
||||
void mem_free(device_memory &mem) override;
|
||||
|
||||
device_ptr mem_alloc_sub_ptr(device_memory &mem, const size_t offset, size_t /*size*/) override;
|
||||
|
||||
/* Global memory. */
|
||||
void global_alloc(device_memory &mem);
|
||||
void global_copy_to(device_memory &mem);
|
||||
void global_free(device_memory &mem);
|
||||
|
||||
/* Image memory. */
|
||||
void image_alloc(device_image &mem);
|
||||
void image_copy_to(device_image &mem);
|
||||
void image_free(device_image &mem);
|
||||
|
||||
/* Device side memory. */
|
||||
void get_device_memory_info(size_t &total, size_t &free) override;
|
||||
bool alloc_device(void *&device_pointer, const size_t size) override;
|
||||
void free_device(void *device_pointer) override;
|
||||
|
||||
/* Shared memory. */
|
||||
bool shared_alloc(void *&shared_pointer, const size_t size) override;
|
||||
void shared_free(void *shared_pointer) override;
|
||||
void *shared_to_device_pointer(const void *shared_pointer) override;
|
||||
|
||||
/* Memory copy. */
|
||||
void copy_host_to_device(void *device_pointer, void *host_pointer, const size_t size) override;
|
||||
void const_copy_to(const char *name, void *host, const size_t size) override;
|
||||
|
||||
/* Graphics resources interoperability. */
|
||||
bool should_use_graphics_interop(const GraphicsInteropDevice &interop_device,
|
||||
const bool log) override;
|
||||
|
||||
unique_ptr<DeviceQueue> gpu_queue_create() override;
|
||||
|
||||
int get_num_multiprocessors();
|
||||
int get_max_num_threads_per_multiprocessor();
|
||||
|
||||
protected:
|
||||
bool get_device_attribute(hipDeviceAttribute_t attribute, int *value);
|
||||
int get_device_default_attribute(hipDeviceAttribute_t attribute, const int default_value);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
120
blender-5.2.0/intern/cycles/device/hip/graphics_interop.cpp
Normal file
120
blender-5.2.0/intern/cycles/device/hip/graphics_interop.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/hip/graphics_interop.h"
|
||||
|
||||
# include "device/hip/device_impl.h"
|
||||
# include "device/hip/util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
HIPDeviceGraphicsInterop::HIPDeviceGraphicsInterop(HIPDeviceQueue *queue)
|
||||
: queue_(queue), device_(static_cast<HIPDevice *>(queue->device))
|
||||
{
|
||||
}
|
||||
|
||||
HIPDeviceGraphicsInterop::~HIPDeviceGraphicsInterop()
|
||||
{
|
||||
HIPContextScope scope(device_);
|
||||
free();
|
||||
}
|
||||
|
||||
void HIPDeviceGraphicsInterop::set_buffer(GraphicsInteropBuffer &interop_buffer)
|
||||
{
|
||||
HIPContextScope scope(device_);
|
||||
|
||||
if (interop_buffer.is_empty()) {
|
||||
free();
|
||||
return;
|
||||
}
|
||||
|
||||
need_zero_ |= interop_buffer.take_zero();
|
||||
|
||||
if (!interop_buffer.has_new_handle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
free();
|
||||
|
||||
switch (interop_buffer.get_type()) {
|
||||
case GraphicsInteropDevice::OPENGL: {
|
||||
const hipError_t result = hipGraphicsGLRegisterBuffer(
|
||||
&hip_graphics_resource_, interop_buffer.take_handle(), hipGraphicsRegisterFlagsNone);
|
||||
|
||||
if (result != hipSuccess) {
|
||||
LOG_ERROR << "Error registering OpenGL buffer: " << hipewErrorString(result);
|
||||
break;
|
||||
}
|
||||
|
||||
buffer_size_ = interop_buffer.get_size();
|
||||
|
||||
break;
|
||||
}
|
||||
case GraphicsInteropDevice::VULKAN:
|
||||
case GraphicsInteropDevice::METAL:
|
||||
case GraphicsInteropDevice::NONE:
|
||||
/* TODO: implement vulkan support. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
device_ptr HIPDeviceGraphicsInterop::map()
|
||||
{
|
||||
hipDeviceptr_t hip_buffer = 0;
|
||||
|
||||
if (hip_graphics_resource_) {
|
||||
HIPContextScope scope(device_);
|
||||
size_t bytes;
|
||||
|
||||
hip_device_assert(device_,
|
||||
hipGraphicsMapResources(1, &hip_graphics_resource_, queue_->stream()));
|
||||
hip_device_assert(
|
||||
device_, hipGraphicsResourceGetMappedPointer(&hip_buffer, &bytes, hip_graphics_resource_));
|
||||
}
|
||||
else {
|
||||
/* Vulkan buffer is always mapped. */
|
||||
hip_buffer = hip_external_memory_ptr_;
|
||||
}
|
||||
|
||||
if (hip_buffer && need_zero_) {
|
||||
hip_device_assert(device_, hipMemsetD8Async(hip_buffer, 0, buffer_size_, queue_->stream()));
|
||||
|
||||
need_zero_ = false;
|
||||
}
|
||||
|
||||
return static_cast<device_ptr>(hip_buffer);
|
||||
}
|
||||
|
||||
void HIPDeviceGraphicsInterop::unmap()
|
||||
{
|
||||
if (hip_graphics_resource_) {
|
||||
HIPContextScope scope(device_);
|
||||
|
||||
hip_device_assert(device_,
|
||||
hipGraphicsUnmapResources(1, &hip_graphics_resource_, queue_->stream()));
|
||||
}
|
||||
}
|
||||
|
||||
void HIPDeviceGraphicsInterop::free()
|
||||
{
|
||||
if (hip_graphics_resource_) {
|
||||
hip_device_assert(device_, hipGraphicsUnregisterResource(hip_graphics_resource_));
|
||||
hip_graphics_resource_ = nullptr;
|
||||
}
|
||||
|
||||
if (hip_external_memory_ptr_) {
|
||||
hip_device_assert(device_, hipFree(hip_external_memory_ptr_));
|
||||
hip_external_memory_ptr_ = 0;
|
||||
}
|
||||
|
||||
buffer_size_ = 0;
|
||||
|
||||
need_zero_ = false;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
54
blender-5.2.0/intern/cycles/device/hip/graphics_interop.h
Normal file
54
blender-5.2.0/intern/cycles/device/hip/graphics_interop.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/graphics_interop.h"
|
||||
# include "session/display_driver.h"
|
||||
|
||||
# ifdef WITH_HIP_DYNLOAD
|
||||
# include "hipew.h"
|
||||
# endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class HIPDevice;
|
||||
class HIPDeviceQueue;
|
||||
|
||||
class HIPDeviceGraphicsInterop : public DeviceGraphicsInterop {
|
||||
public:
|
||||
explicit HIPDeviceGraphicsInterop(HIPDeviceQueue *queue);
|
||||
|
||||
HIPDeviceGraphicsInterop(const HIPDeviceGraphicsInterop &other) = delete;
|
||||
HIPDeviceGraphicsInterop(HIPDeviceGraphicsInterop &&other) noexcept = delete;
|
||||
|
||||
~HIPDeviceGraphicsInterop() override;
|
||||
|
||||
HIPDeviceGraphicsInterop &operator=(const HIPDeviceGraphicsInterop &other) = delete;
|
||||
HIPDeviceGraphicsInterop &operator=(HIPDeviceGraphicsInterop &&other) = delete;
|
||||
|
||||
void set_buffer(GraphicsInteropBuffer &interop_buffer) override;
|
||||
|
||||
device_ptr map() override;
|
||||
void unmap() override;
|
||||
|
||||
protected:
|
||||
HIPDeviceQueue *queue_ = nullptr;
|
||||
HIPDevice *device_ = nullptr;
|
||||
|
||||
/* Size of the buffer in bytes. */
|
||||
size_t buffer_size_ = 0;
|
||||
|
||||
/* The destination was requested to be cleared. */
|
||||
bool need_zero_ = false;
|
||||
|
||||
hipGraphicsResource hip_graphics_resource_ = nullptr;
|
||||
hipDeviceptr_t hip_external_memory_ptr_ = 0;
|
||||
|
||||
void free();
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
81
blender-5.2.0/intern/cycles/device/hip/kernel.cpp
Normal file
81
blender-5.2.0/intern/cycles/device/hip/kernel.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef WITH_HIP
|
||||
# include "kernel/types.h"
|
||||
|
||||
# include "device/hip/device_impl.h"
|
||||
# include "device/hip/kernel.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
bool HIPDeviceKernels::load_kernel(HIPDevice *device,
|
||||
hipModule_t hip_module,
|
||||
const DeviceKernel kernel)
|
||||
{
|
||||
if (available(kernel)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!device_kernel_has_gpu_function(kernel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HIPDeviceKernel &hip_kernel = kernels_[int(kernel)];
|
||||
|
||||
const std::string function_name = std::string("kernel_gpu_") + device_kernel_as_string(kernel);
|
||||
hip_device_assert(device,
|
||||
hipModuleGetFunction(&hip_kernel.function, hip_module, function_name.c_str()));
|
||||
if (!hip_kernel.function) {
|
||||
LOG_ERROR << "Unable to load kernel " << function_name;
|
||||
return false;
|
||||
}
|
||||
|
||||
hip_device_assert(device, hipFuncSetCacheConfig(hip_kernel.function, hipFuncCachePreferL1));
|
||||
hip_device_assert(
|
||||
device,
|
||||
hipModuleOccupancyMaxPotentialBlockSize(
|
||||
&hip_kernel.min_blocks, &hip_kernel.num_threads_per_block, hip_kernel.function, 0, 0));
|
||||
|
||||
LOG_DEBUG << "Loaded kernel: " << function_name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HIPDeviceKernels::load_all(HIPDevice *device, hipModule_t hip_module)
|
||||
{
|
||||
LOG_DEBUG << "Loading all HIP kernels";
|
||||
|
||||
for (int i = 0; i < (int)DEVICE_KERNEL_NUM; i++) {
|
||||
load_kernel(device, hip_module, DeviceKernel(i));
|
||||
}
|
||||
}
|
||||
|
||||
void HIPDeviceKernels::load_raytrace(HIPDevice *device, hipModule_t hip_module)
|
||||
{
|
||||
LOG_DEBUG << "Loading ray-tracing HIP-RT kernels";
|
||||
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST);
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE);
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_INTERSECT_VOLUME_STACK);
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_INTERSECT_DEDICATED_LIGHT);
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_INTERSECT_MNEE);
|
||||
|
||||
load_kernel(device, hip_module, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE);
|
||||
}
|
||||
|
||||
const HIPDeviceKernel &HIPDeviceKernels::get(DeviceKernel kernel) const
|
||||
{
|
||||
return kernels_[(int)kernel];
|
||||
}
|
||||
|
||||
bool HIPDeviceKernels::available(DeviceKernel kernel) const
|
||||
{
|
||||
return kernels_[(int)kernel].function != nullptr;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_HIP */
|
||||
45
blender-5.2.0/intern/cycles/device/hip/kernel.h
Normal file
45
blender-5.2.0/intern/cycles/device/hip/kernel.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/kernel.h"
|
||||
|
||||
# ifdef WITH_HIP_DYNLOAD
|
||||
# include "hipew.h"
|
||||
# endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class HIPDevice;
|
||||
|
||||
/* HIP kernel and associate occupancy information. */
|
||||
class HIPDeviceKernel {
|
||||
public:
|
||||
hipFunction_t function = nullptr;
|
||||
|
||||
int num_threads_per_block = 0;
|
||||
int min_blocks = 0;
|
||||
};
|
||||
|
||||
/* Cache of HIP kernels for each DeviceKernel. */
|
||||
class HIPDeviceKernels {
|
||||
public:
|
||||
void load_all(HIPDevice *device, hipModule_t hip_module);
|
||||
void load_raytrace(HIPDevice *device, hipModule_t hip_module);
|
||||
|
||||
const HIPDeviceKernel &get(DeviceKernel kernel) const;
|
||||
bool available(DeviceKernel kernel) const;
|
||||
|
||||
protected:
|
||||
bool load_kernel(HIPDevice *device, hipModule_t hip_module, DeviceKernel kernel);
|
||||
|
||||
HIPDeviceKernel kernels_[DEVICE_KERNEL_NUM];
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_HIP */
|
||||
267
blender-5.2.0/intern/cycles/device/hip/queue.cpp
Normal file
267
blender-5.2.0/intern/cycles/device/hip/queue.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/hip/queue.h"
|
||||
|
||||
# include "device/hip/device_impl.h"
|
||||
# include "device/hip/graphics_interop.h"
|
||||
# include "device/hip/kernel.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* HIPDeviceQueue */
|
||||
|
||||
HIPDeviceQueue::HIPDeviceQueue(HIPDevice *device)
|
||||
: DeviceQueue(device), hip_device_(device), hip_stream_(nullptr)
|
||||
{
|
||||
const HIPContextScope scope(hip_device_);
|
||||
hip_device_assert(hip_device_, hipStreamCreateWithFlags(&hip_stream_, hipStreamNonBlocking));
|
||||
}
|
||||
|
||||
HIPDeviceQueue::~HIPDeviceQueue()
|
||||
{
|
||||
const HIPContextScope scope(hip_device_);
|
||||
hipStreamDestroy(hip_stream_);
|
||||
}
|
||||
|
||||
int HIPDeviceQueue::num_concurrent_states(const size_t state_size) const
|
||||
{
|
||||
const int max_num_threads = hip_device_->get_num_multiprocessors() *
|
||||
hip_device_->get_max_num_threads_per_multiprocessor();
|
||||
int num_states = ((max_num_threads == 0) ? 65536 : max_num_threads) * 16;
|
||||
|
||||
const char *factor_str = getenv("CYCLES_CONCURRENT_STATES_FACTOR");
|
||||
if (factor_str) {
|
||||
const float factor = (float)atof(factor_str);
|
||||
if (factor != 0.0f) {
|
||||
num_states = max((int)(num_states * factor), 1024);
|
||||
}
|
||||
else {
|
||||
LOG_TRACE << "CYCLES_CONCURRENT_STATES_FACTOR evaluated to 0";
|
||||
}
|
||||
}
|
||||
|
||||
LOG_TRACE << "GPU queue concurrent states: " << num_states << ", using up to "
|
||||
<< string_human_readable_size(num_states * state_size);
|
||||
|
||||
return num_states;
|
||||
}
|
||||
|
||||
int HIPDeviceQueue::num_concurrent_busy_states(const size_t /*state_size*/) const
|
||||
{
|
||||
const int max_num_threads = hip_device_->get_num_multiprocessors() *
|
||||
hip_device_->get_max_num_threads_per_multiprocessor();
|
||||
|
||||
if (max_num_threads == 0) {
|
||||
return 65536;
|
||||
}
|
||||
|
||||
return 4 * max_num_threads;
|
||||
}
|
||||
|
||||
void HIPDeviceQueue::init_execution()
|
||||
{
|
||||
/* Synchronize all textures and memory copies before executing task. */
|
||||
HIPContextScope scope(hip_device_);
|
||||
hip_device_->load_image_info(nullptr);
|
||||
hip_device_assert(hip_device_, hipDeviceSynchronize());
|
||||
|
||||
debug_init_execution();
|
||||
}
|
||||
|
||||
void HIPDeviceQueue::load_image_info()
|
||||
{
|
||||
HIPContextScope scope(hip_device_);
|
||||
hip_device_->load_image_info(this);
|
||||
}
|
||||
|
||||
bool HIPDeviceQueue::enqueue(DeviceKernel kernel,
|
||||
const int work_size,
|
||||
const DeviceKernelArguments &args)
|
||||
{
|
||||
if (hip_device_->have_error()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
debug_enqueue_begin(kernel, work_size);
|
||||
|
||||
const HIPContextScope scope(hip_device_);
|
||||
|
||||
/* Update image info in case memory moved to host. */
|
||||
if (hip_device_->load_image_info(nullptr)) {
|
||||
hip_device_assert(hip_device_, hipDeviceSynchronize());
|
||||
if (hip_device_->have_error()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute kernel launch parameters. */
|
||||
const HIPDeviceKernel &hip_kernel = hip_device_->kernels.get(kernel);
|
||||
const int num_threads_per_block = hip_kernel.num_threads_per_block;
|
||||
const int num_blocks = divide_up(work_size, num_threads_per_block);
|
||||
|
||||
int shared_mem_bytes = 0;
|
||||
|
||||
switch (kernel) {
|
||||
case DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_QUEUED_SHADOW_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_TERMINATED_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_TERMINATED_SHADOW_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_PATHS_ARRAY:
|
||||
/* See parall_active_index.h for why this amount of shared memory is needed. */
|
||||
shared_mem_bytes = (num_threads_per_block + 1) * sizeof(int);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Launch kernel. */
|
||||
assert_success(hipModuleLaunchKernel(hip_kernel.function,
|
||||
num_blocks,
|
||||
1,
|
||||
1,
|
||||
num_threads_per_block,
|
||||
1,
|
||||
1,
|
||||
shared_mem_bytes,
|
||||
hip_stream_,
|
||||
const_cast<void **>(args.values),
|
||||
nullptr),
|
||||
"enqueue");
|
||||
|
||||
debug_enqueue_end();
|
||||
|
||||
return !(hip_device_->have_error());
|
||||
}
|
||||
|
||||
bool HIPDeviceQueue::synchronize()
|
||||
{
|
||||
if (hip_device_->have_error()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const HIPContextScope scope(hip_device_);
|
||||
assert_success(hipStreamSynchronize(hip_stream_), "synchronize");
|
||||
debug_synchronize();
|
||||
|
||||
return !(hip_device_->have_error());
|
||||
}
|
||||
|
||||
void HIPDeviceQueue::zero_to_device(device_memory &mem)
|
||||
{
|
||||
assert(mem.type != MEM_IMAGE_TEXTURE);
|
||||
|
||||
if (mem.memory_size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate on demand. */
|
||||
if (mem.device_pointer == 0) {
|
||||
if (mem.type == MEM_GLOBAL) {
|
||||
hip_device_->global_alloc(mem);
|
||||
}
|
||||
else {
|
||||
hip_device_->mem_alloc(mem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Zero memory on device. */
|
||||
device_ptr d_ptr = mem.device->mem_device_ptr(mem, hip_device_);
|
||||
assert(d_ptr != 0);
|
||||
|
||||
const HIPContextScope scope(hip_device_);
|
||||
assert_success(hipMemsetD8Async((hipDeviceptr_t)d_ptr, 0, mem.memory_size(), hip_stream_),
|
||||
"zero_to_device");
|
||||
}
|
||||
|
||||
void HIPDeviceQueue::copy_to_device(device_memory &mem)
|
||||
{
|
||||
assert(mem.type != MEM_IMAGE_TEXTURE);
|
||||
|
||||
if (mem.memory_size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate on demand. */
|
||||
if (mem.device_pointer == 0) {
|
||||
if (mem.type == MEM_GLOBAL) {
|
||||
hip_device_->global_alloc(mem);
|
||||
}
|
||||
else {
|
||||
hip_device_->mem_alloc(mem);
|
||||
}
|
||||
}
|
||||
|
||||
device_ptr d_ptr = mem.device->mem_device_ptr(mem, hip_device_);
|
||||
assert(d_ptr != 0);
|
||||
assert(mem.host_pointer != nullptr);
|
||||
|
||||
/* Copy memory to device. */
|
||||
const HIPContextScope scope(hip_device_);
|
||||
assert_success(
|
||||
hipMemcpyHtoDAsync((hipDeviceptr_t)d_ptr, mem.host_pointer, mem.memory_size(), hip_stream_),
|
||||
"copy_to_device");
|
||||
}
|
||||
|
||||
void HIPDeviceQueue::copy_from_device(device_memory &mem)
|
||||
{
|
||||
assert(mem.type != MEM_GLOBAL && mem.type != MEM_IMAGE_TEXTURE);
|
||||
|
||||
if (mem.memory_size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(mem.device_pointer != 0);
|
||||
assert(mem.host_pointer != nullptr);
|
||||
|
||||
/* Copy memory from device. */
|
||||
const HIPContextScope scope(hip_device_);
|
||||
assert_success(
|
||||
hipMemcpyDtoHAsync(
|
||||
mem.host_pointer, (hipDeviceptr_t)mem.device_pointer, mem.memory_size(), hip_stream_),
|
||||
"copy_from_device");
|
||||
}
|
||||
|
||||
void *HIPDeviceQueue::copy_from_device_synchronized(device_memory &mem, vector<uint8_t> &storage)
|
||||
{
|
||||
if (mem.memory_size() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
storage.resize(mem.memory_size());
|
||||
|
||||
device_ptr d_ptr = mem.device->mem_device_ptr(mem, hip_device_);
|
||||
assert(d_ptr != 0);
|
||||
|
||||
const HIPContextScope scope(hip_device_);
|
||||
assert_success(
|
||||
hipMemcpyDtoHAsync(storage.data(), (hipDeviceptr_t)d_ptr, mem.memory_size(), hip_stream_),
|
||||
"copy_from_device_synchronized");
|
||||
|
||||
synchronize();
|
||||
return storage.data();
|
||||
}
|
||||
|
||||
void HIPDeviceQueue::assert_success(hipError_t result, const char *operation)
|
||||
{
|
||||
if (result != hipSuccess) {
|
||||
const char *name = hipewErrorString(result);
|
||||
hip_device_->set_error(
|
||||
string_printf("%s in HIP queue %s (%s)", name, operation, debug_active_kernels().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<DeviceGraphicsInterop> HIPDeviceQueue::graphics_interop_create()
|
||||
{
|
||||
return make_unique<HIPDeviceGraphicsInterop>(this);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_HIP */
|
||||
58
blender-5.2.0/intern/cycles/device/hip/queue.h
Normal file
58
blender-5.2.0/intern/cycles/device/hip/queue.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/memory.h"
|
||||
# include "device/queue.h"
|
||||
|
||||
# include "device/hip/util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class HIPDevice;
|
||||
class device_memory;
|
||||
|
||||
/* Base class for HIP queues. */
|
||||
class HIPDeviceQueue : public DeviceQueue {
|
||||
public:
|
||||
HIPDeviceQueue(HIPDevice *device);
|
||||
~HIPDeviceQueue() override;
|
||||
|
||||
int num_concurrent_states(const size_t state_size) const override;
|
||||
int num_concurrent_busy_states(const size_t state_size) const override;
|
||||
|
||||
void init_execution() override;
|
||||
void load_image_info() override;
|
||||
|
||||
bool enqueue(DeviceKernel kernel,
|
||||
const int work_size,
|
||||
const DeviceKernelArguments &args) override;
|
||||
|
||||
bool synchronize() override;
|
||||
|
||||
void zero_to_device(device_memory &mem) override;
|
||||
void copy_to_device(device_memory &mem) override;
|
||||
void copy_from_device(device_memory &mem) override;
|
||||
void *copy_from_device_synchronized(device_memory &mem, vector<uint8_t> &storage) override;
|
||||
|
||||
virtual hipStream_t stream()
|
||||
{
|
||||
return hip_stream_;
|
||||
}
|
||||
|
||||
unique_ptr<DeviceGraphicsInterop> graphics_interop_create() override;
|
||||
|
||||
protected:
|
||||
HIPDevice *hip_device_;
|
||||
hipStream_t hip_stream_;
|
||||
|
||||
void assert_success(hipError_t result, const char *operation);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_HIP */
|
||||
77
blender-5.2.0/intern/cycles/device/hip/util.cpp
Normal file
77
blender-5.2.0/intern/cycles/device/hip/util.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include "device/hip/util.h"
|
||||
# include "device/hip/device_impl.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
HIPContextScope::HIPContextScope(HIPDevice *device) : device(device)
|
||||
{
|
||||
hip_device_assert(device, hipCtxPushCurrent(device->hipContext));
|
||||
}
|
||||
|
||||
HIPContextScope::~HIPContextScope()
|
||||
{
|
||||
hip_device_assert(device, hipCtxPopCurrent(nullptr));
|
||||
}
|
||||
|
||||
# ifndef WITH_HIP_DYNLOAD
|
||||
const char *hipewErrorString(hipError_t result)
|
||||
{
|
||||
/* We can only give error code here without major code duplication, that
|
||||
* should be enough since dynamic loading is only being disabled by folks
|
||||
* who knows what they're doing anyway.
|
||||
*
|
||||
* NOTE: Avoid call from several threads.
|
||||
*/
|
||||
static string error;
|
||||
error = string_printf("%d", result);
|
||||
return error.c_str();
|
||||
}
|
||||
|
||||
const char *hipewCompilerPath()
|
||||
{
|
||||
return CYCLES_HIP_HIPCC_EXECUTABLE;
|
||||
}
|
||||
|
||||
int hipewCompilerVersion()
|
||||
{
|
||||
return (HIP_VERSION / 100) + (HIP_VERSION % 100 / 10);
|
||||
}
|
||||
# endif /* !WITH_HIP_DYNLOAD */
|
||||
|
||||
bool hipSupportsDriver()
|
||||
{
|
||||
int hip_driver_version = 0;
|
||||
hipError_t result = hipDriverGetVersion(&hip_driver_version);
|
||||
if (result != hipSuccess) {
|
||||
LOG_WARNING << "Error getting driver version: " << hipewErrorString(result);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_TRACE << "Detected HIP driver version: " << hip_driver_version;
|
||||
|
||||
# ifdef _WIN32
|
||||
if (hip_driver_version < 60241512) {
|
||||
/* Users get error messages about being unable to find GPU binaries on older GPU drivers.
|
||||
* 60241512 corresponds to Adrenalin 24.9.1. */
|
||||
return false;
|
||||
}
|
||||
# else /* Linux */
|
||||
if (hip_driver_version < 60342131) {
|
||||
/* Users get error messages about being unable to load GPU kernels on older ROCm versions.
|
||||
* 60342131 corresponds to ROCm 6.3.0 */
|
||||
return false;
|
||||
}
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_HIP */
|
||||
92
blender-5.2.0/intern/cycles/device/hip/util.h
Normal file
92
blender-5.2.0/intern/cycles/device/hip/util.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WITH_HIP
|
||||
|
||||
# include <cstring>
|
||||
# include <string>
|
||||
|
||||
# ifdef WITH_HIP_DYNLOAD
|
||||
# include "hipew.h"
|
||||
# endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class HIPDevice;
|
||||
|
||||
/* Utility to push/pop HIP context. */
|
||||
class HIPContextScope {
|
||||
public:
|
||||
HIPContextScope(HIPDevice *device);
|
||||
~HIPContextScope();
|
||||
|
||||
private:
|
||||
HIPDevice *device;
|
||||
};
|
||||
|
||||
/* Utility for checking return values of HIP function calls. */
|
||||
# define hip_device_assert(hip_device, stmt) \
|
||||
{ \
|
||||
hipError_t result = stmt; \
|
||||
if (result != hipSuccess) { \
|
||||
const char *name = hipewErrorString(result); \
|
||||
hip_device->set_error( \
|
||||
string_printf("%s in %s (%s:%d)", name, #stmt, __FILE__, __LINE__)); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
# define hip_assert(stmt) hip_device_assert(this, stmt)
|
||||
|
||||
# ifndef WITH_HIP_DYNLOAD
|
||||
/* Transparently implement some functions, so majority of the file does not need
|
||||
* to worry about difference between dynamically loaded and linked HIP at all. */
|
||||
const char *hipewErrorString(hipError_t result);
|
||||
const char *hipewCompilerPath();
|
||||
int hipewCompilerVersion();
|
||||
# endif /* !WITH_HIP_DYNLOAD */
|
||||
|
||||
bool hipSupportsDriver();
|
||||
|
||||
static std::string hipDeviceArch(const int hipDevId)
|
||||
{
|
||||
hipDeviceProp_t props;
|
||||
hipGetDeviceProperties(&props, hipDevId);
|
||||
const char *arch = strtok(props.gcnArchName, ":");
|
||||
return (arch == nullptr) ? props.gcnArchName : arch;
|
||||
}
|
||||
|
||||
static inline bool hipSupportsDevice(const int hipDevId)
|
||||
{
|
||||
int major, minor;
|
||||
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
|
||||
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
|
||||
|
||||
return (major >= 10);
|
||||
}
|
||||
|
||||
static inline bool hipIsRDNA2OrNewer(const int hipDevId)
|
||||
{
|
||||
int major, minor;
|
||||
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
|
||||
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
|
||||
|
||||
return (major > 10 || (major == 10 && minor >= 3));
|
||||
}
|
||||
|
||||
static inline bool hipSupportsDeviceOIDN(const int hipDevId)
|
||||
{
|
||||
/* Matches HIPDevice::getArch in HIP. */
|
||||
const std::string arch = hipDeviceArch(hipDevId);
|
||||
return (arch == "gfx1030" || arch == "gfx1031" || arch == "gfx1032" || arch == "gfx1034" ||
|
||||
arch == "gfx1035" || arch == "gfx1036" || arch == "gfx1100" || arch == "gfx1101" ||
|
||||
arch == "gfx1102" || arch == "gfx1103" || arch == "gfx1150" || arch == "gfx1151" ||
|
||||
arch == "gfx1152" || arch == "gfx1200" || arch == "gfx1201");
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_HIP */
|
||||
Reference in New Issue
Block a user