P4 to Git Change 1398097 by lmoriche@lmoriche_opencl_dev2 on 2017/04/13 13:01:56
SWDEV-102733 - [OCL-LC-ROCm] Cmake build Write CMakeLists.txt to enable building with and without the DK environment - Change the coding convention of the runtime files. Use Google's Style (https://google.github.io/styleguide/cppguide.html). Affected files ... ... //depot/stg/opencl/drivers/opencl/.clang-format#1 add ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_agent_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_command.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_context.cpp#53 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_counter.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_d3d10.cpp#15 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_d3d11.cpp#22 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_d3d9.cpp#32 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_debugger_amd.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_debugger_amd.h#7 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_device.cpp#61 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_event.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_execute.cpp#23 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_gl.cpp#53 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_icd.cpp#27 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_icd_amd.h#18 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_kernel.h#24 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_kernel_info_amd.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_kernel_info_amd.h#4 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_lqdflash_amd.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_lqdflash_amd.h#6 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_memobj.cpp#81 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_object.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_pipe.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_platform_amd.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_platform_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_profile_amd.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_profile_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_program.cpp#41 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_sampler.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_sdi_amd.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_sdi_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_semaphore_amd.h#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_svm.cpp#20 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_thread_trace_amd.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_thread_trace_amd.h#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/appprofile.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/appprofile.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/blit.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/blit.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/blitcl.cpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.cpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubuiltins.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubuiltins.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpucommand.cpp#66 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpucommand.hpp#40 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpudevice.cpp#280 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpudevice.hpp#96 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpufeat.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpukernel.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpumapping.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpumapping.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.cpp#70 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.hpp#14 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpusettings.cpp#33 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpusettings.hpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cputables.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuvirtual.cpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuvirtual.hpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/device.cpp#209 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#284 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuappprofile.cpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuappprofile.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpubinary.cpp#58 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpubinary.hpp#27 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpublit.cpp#126 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpublit.hpp#41 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucompiler.cpp#156 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuconstbuf.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuconstbuf.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucounters.cpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucounters.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugger.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugmanager.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugmanager.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudefs.hpp#147 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.cpp#567 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.hpp#163 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.cpp#318 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.hpp#126 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpumemory.cpp#131 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpumemory.hpp#50 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprintf.cpp#44 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprintf.hpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#232 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.hpp#69 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuresource.cpp#238 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuresource.hpp#87 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpusched.hpp#19 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuschedcl.cpp#35 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuscsi.cpp#37 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpusettings.cpp#350 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpusettings.hpp#98 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputhreadtrace.cpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputhreadtrace.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputimestamp.cpp#27 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputimestamp.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputrap.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#410 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.hpp#140 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/hwdebug.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/hwdebug.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palappprofile.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palappprofile.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palbinary.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palbinary.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palblit.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palblit.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcompiler.cpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palconstbuf.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palconstbuf.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcounters.cpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcounters.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldebugger.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldebugmanager.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldebugmanager.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldefs.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.cpp#45 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldeviced3d10.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldeviced3d11.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldeviced3d9.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevicegl.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.cpp#34 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.hpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palmemory.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palmemory.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprintf.cpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprintf.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#39 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.hpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palresource.cpp#28 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palresource.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palsched.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palschedcl.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palsettings.cpp#24 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palsettings.hpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palthreadtrace.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palthreadtrace.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paltimestamp.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paltimestamp.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paltrap.hpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.cpp#48 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.hpp#21 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palwavelimiter.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palwavelimiter.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/mesa_glinterop.h#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocappprofile.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocappprofile.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocbinary.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompiler.cpp#32 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdefs.hpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#48 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.hpp#20 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.cpp#22 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.cpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprintf.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprintf.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#64 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#23 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocregisters.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.cpp#34 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.hpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/alloc.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/alloc.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os.hpp#30 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os_posix.cpp#42 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os_win32.cpp#47 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/agent.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/agent.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/command.cpp#78 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/command.hpp#83 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/commandqueue.cpp#23 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/commandqueue.hpp#18 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/context.cpp#42 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/context.hpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/counter.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/interop.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/kernel.cpp#23 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/kernel.hpp#18 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.cpp#127 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.hpp#100 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/ndrange.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/ndrange.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/object.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/object.hpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/perfctr.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/program.cpp#86 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/program.hpp#41 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/runtime.cpp#35 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/runtime.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/sampler.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/threadtrace.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/atomic.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/monitor.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/monitor.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/semaphore.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/semaphore.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/thread.cpp#14 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/thread.hpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/top.hpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/concurrent.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/debug.cpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/debug.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.cpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#271 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/macros.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/util.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/versions.hpp#2150 edit
Šī revīzija ir iekļauta:
1 vecāks
a615e4fbb6
revīzija
465c1c0287
188 files changed
+68131
-78046
No files matched your search
@@ -10,16 +10,11 @@
|
||||
namespace gpu {
|
||||
|
||||
AppProfile::AppProfile()
|
||||
: amd::AppProfile()
|
||||
, enableHighPerformanceState_(true)
|
||||
, reportAsOCL12Device_(false)
|
||||
{
|
||||
propertyDataMap_.insert(DataMap::value_type("HighPerfState",
|
||||
PropertyData(DataType_Boolean, &enableHighPerformanceState_)));
|
||||
: amd::AppProfile(), enableHighPerformanceState_(true), reportAsOCL12Device_(false) {
|
||||
propertyDataMap_.insert(DataMap::value_type(
|
||||
"HighPerfState", PropertyData(DataType_Boolean, &enableHighPerformanceState_)));
|
||||
|
||||
propertyDataMap_.insert(DataMap::value_type("OCL12Device",
|
||||
PropertyData(DataType_Boolean, &reportAsOCL12Device_)));
|
||||
propertyDataMap_.insert(
|
||||
DataMap::value_type("OCL12Device", PropertyData(DataType_Boolean, &reportAsOCL12Device_)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,21 +10,18 @@
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class AppProfile : public amd::AppProfile
|
||||
{
|
||||
public:
|
||||
AppProfile();
|
||||
class AppProfile : public amd::AppProfile {
|
||||
public:
|
||||
AppProfile();
|
||||
|
||||
//! return the value of enableHighPerformanceState_
|
||||
bool enableHighPerformanceState() const { return enableHighPerformanceState_; }
|
||||
bool reportAsOCL12Device() const { return reportAsOCL12Device_; }
|
||||
//! return the value of enableHighPerformanceState_
|
||||
bool enableHighPerformanceState() const { return enableHighPerformanceState_; }
|
||||
bool reportAsOCL12Device() const { return reportAsOCL12Device_; }
|
||||
|
||||
private:
|
||||
|
||||
bool enableHighPerformanceState_;
|
||||
bool reportAsOCL12Device_;
|
||||
private:
|
||||
bool enableHighPerformanceState_;
|
||||
bool reportAsOCL12Device_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,537 +12,496 @@
|
||||
|
||||
namespace {
|
||||
|
||||
enum {
|
||||
NDX_KERNEL = 0,
|
||||
NDX_METADATA = 1,
|
||||
NDX_HEADER = 2,
|
||||
NDX_AMDIL = 3,
|
||||
NDX_LAST
|
||||
};
|
||||
enum { NDX_KERNEL = 0, NDX_METADATA = 1, NDX_HEADER = 2, NDX_AMDIL = 3, NDX_LAST };
|
||||
typedef struct {
|
||||
bool IsKernel; // whether the entry is for kernel
|
||||
bool IsKernel; // whether the entry is for kernel
|
||||
|
||||
/*
|
||||
SymInfo[NDX_KERNEL] : SymbolInfo for kernel isa (cal image)
|
||||
SymInfo[NDX_METADATA] : SymbolInfo for kernel metadata
|
||||
SymInfo[NDX_HEADER] : SymbolInfo for kernel header
|
||||
SymInfo[NDX_AMDIL] : SymbolInfo for kernel's amdil
|
||||
*/
|
||||
amd::OclElf::SymbolInfo SymInfo[NDX_LAST];
|
||||
/*
|
||||
SymInfo[NDX_KERNEL] : SymbolInfo for kernel isa (cal image)
|
||||
SymInfo[NDX_METADATA] : SymbolInfo for kernel metadata
|
||||
SymInfo[NDX_HEADER] : SymbolInfo for kernel header
|
||||
SymInfo[NDX_AMDIL] : SymbolInfo for kernel's amdil
|
||||
*/
|
||||
amd::OclElf::SymbolInfo SymInfo[NDX_LAST];
|
||||
} ElfSymbol_t;
|
||||
|
||||
}
|
||||
|
||||
namespace gpu {
|
||||
|
||||
bool
|
||||
ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled)
|
||||
{
|
||||
const char __OpenCL_[] = "__OpenCL_";
|
||||
const char _kernel[] = "_kernel";
|
||||
const char _data[] = "_metadata"; // metadata for kernel function
|
||||
const char _fdata[] = "_fmetadata"; // metadata for non-kernel function
|
||||
const char _header[] = "_header";
|
||||
const char _amdil[] = "_amdil";
|
||||
bool ClBinary::loadKernels(NullProgram& program, bool* hasRecompiled) {
|
||||
const char __OpenCL_[] = "__OpenCL_";
|
||||
const char _kernel[] = "_kernel";
|
||||
const char _data[] = "_metadata"; // metadata for kernel function
|
||||
const char _fdata[] = "_fmetadata"; // metadata for non-kernel function
|
||||
const char _header[] = "_header";
|
||||
const char _amdil[] = "_amdil";
|
||||
|
||||
*hasRecompiled = false;
|
||||
*hasRecompiled = false;
|
||||
|
||||
// TODO : jugu
|
||||
// Target should be 15 bit maximum. Should check this somewhere.
|
||||
uint32_t target = static_cast<uint32_t>(dev().calTarget());
|
||||
uint16_t elf_target;
|
||||
amd::OclElf::oclElfPlatform platform;
|
||||
if (!elfIn()->getTarget(elf_target, platform)) {
|
||||
LogError("The OCL binary image loading failed: incorrect format");
|
||||
return false;
|
||||
// TODO : jugu
|
||||
// Target should be 15 bit maximum. Should check this somewhere.
|
||||
uint32_t target = static_cast<uint32_t>(dev().calTarget());
|
||||
uint16_t elf_target;
|
||||
amd::OclElf::oclElfPlatform platform;
|
||||
if (!elfIn()->getTarget(elf_target, platform)) {
|
||||
LogError("The OCL binary image loading failed: incorrect format");
|
||||
return false;
|
||||
}
|
||||
if (platform == amd::OclElf::COMPLIB_PLATFORM) {
|
||||
// BIF 3.0
|
||||
uint32_t flag;
|
||||
aclTargetInfo tgtInfo = aclGetTargetInfo("amdil", dev().hwInfo()->targetName_, NULL);
|
||||
if (!elfIn()->getFlags(flag)) {
|
||||
LogError("The OCL binary image loading failed: incorrect format");
|
||||
return false;
|
||||
}
|
||||
if (platform == amd::OclElf::COMPLIB_PLATFORM) {
|
||||
// BIF 3.0
|
||||
uint32_t flag;
|
||||
aclTargetInfo tgtInfo = aclGetTargetInfo("amdil", dev().hwInfo()->targetName_, NULL);
|
||||
if (!elfIn()->getFlags(flag)){
|
||||
LogError("The OCL binary image loading failed: incorrect format");
|
||||
return false;
|
||||
}
|
||||
if ((elf_target != EM_AMDIL) ||
|
||||
(tgtInfo.chip_id != flag)) {
|
||||
LogError("The OCL binary image loading failed: different target");
|
||||
return false;
|
||||
}
|
||||
if ((elf_target != EM_AMDIL) || (tgtInfo.chip_id != flag)) {
|
||||
LogError("The OCL binary image loading failed: different target");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (((platform != amd::OclElf::CAL_PLATFORM) ||
|
||||
((uint32_t)target != elf_target))) {
|
||||
LogError("The OCL binary image loading failed: different target");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (((platform != amd::OclElf::CAL_PLATFORM) || ((uint32_t)target != elf_target))) {
|
||||
LogError("The OCL binary image loading failed: different target");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Using class so that dtor() can be invoked to do clean-up */
|
||||
class TempWrapper {
|
||||
public:
|
||||
/*
|
||||
functionNameMap[] maps from a function name (linkage name in the generated code)
|
||||
to ElfSymbol_t, which is defined as above.
|
||||
*/
|
||||
std::map<std::string, ElfSymbol_t*> functionNameMap;
|
||||
|
||||
// Keep all kernel ILs if -use-debugil is present (gpu debugging)
|
||||
std::map<std::string, std::string> kernelILs;
|
||||
|
||||
~TempWrapper () {
|
||||
std::map<std::string, ElfSymbol_t*>::iterator
|
||||
I, IB = functionNameMap.begin(), IE = functionNameMap.end();
|
||||
for (I = IB; I != IE; ++I) {
|
||||
delete [] (*I).second;
|
||||
}
|
||||
|
||||
kernelILs.clear();
|
||||
}
|
||||
} tempObj;
|
||||
|
||||
/* Using class so that dtor() can be invoked to do clean-up */
|
||||
class TempWrapper {
|
||||
public:
|
||||
/*
|
||||
If usedebugil is true, we will load IL from .debugil section. We will ignore
|
||||
_kernel, _amdil, _header in the binary.
|
||||
functionNameMap[] maps from a function name (linkage name in the generated code)
|
||||
to ElfSymbol_t, which is defined as above.
|
||||
*/
|
||||
bool usedebugil = program.getCompilerOptions()->oVariables->UseDebugIL;
|
||||
std::map<std::string, ElfSymbol_t*> functionNameMap;
|
||||
|
||||
for (amd::Sym_Handle sym = elfIn()->nextSymbol(NULL);
|
||||
sym != NULL;
|
||||
sym = elfIn()->nextSymbol(sym)) {
|
||||
amd::OclElf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(sym, &symInfo)) {
|
||||
LogError("LoadKernelFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
// Keep all kernel ILs if -use-debugil is present (gpu debugging)
|
||||
std::map<std::string, std::string> kernelILs;
|
||||
|
||||
std::string elfSymName(symInfo.sym_name);
|
||||
const size_t offset = sizeof(__OpenCL_) - 1;
|
||||
if (elfSymName.compare(0, offset, __OpenCL_) != 0) {
|
||||
continue;
|
||||
}
|
||||
~TempWrapper() {
|
||||
std::map<std::string, ElfSymbol_t *>::iterator I, IB = functionNameMap.begin(),
|
||||
IE = functionNameMap.end();
|
||||
for (I = IB; I != IE; ++I) {
|
||||
delete[](*I).second;
|
||||
}
|
||||
|
||||
// Assume this elfSymName is associated with a kernel name. The following code will adjust
|
||||
// it if it isn't.
|
||||
const size_t suffixPos = elfSymName.rfind('_');
|
||||
bool isKernel = true; // assume it is a kernel
|
||||
std::string FName = elfSymName.substr(0, suffixPos);
|
||||
FName.append("_kernel"); // make the kernel's linkage name
|
||||
kernelILs.clear();
|
||||
}
|
||||
} tempObj;
|
||||
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[FName];
|
||||
amd::OclElf::SymbolInfo* sinfo = (elfsymbol != NULL) ? &(elfsymbol->SymInfo[0]) : NULL;
|
||||
/*
|
||||
If usedebugil is true, we will load IL from .debugil section. We will ignore
|
||||
_kernel, _amdil, _header in the binary.
|
||||
*/
|
||||
bool usedebugil = program.getCompilerOptions()->oVariables->UseDebugIL;
|
||||
|
||||
// Add info for this elf symbol into tempobj's functionNameMap[]
|
||||
int index = -1;
|
||||
if (!usedebugil &&
|
||||
(elfSymName.compare(suffixPos, sizeof(_kernel) - 1, _kernel) == 0)) {
|
||||
index = NDX_KERNEL;
|
||||
assert (((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one kernel symbol for the same kernel");
|
||||
}
|
||||
else if (!usedebugil &&
|
||||
(elfSymName.compare(suffixPos, sizeof(_header) - 1, _header) == 0)) {
|
||||
index = NDX_HEADER;
|
||||
assert (((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one header symbol for a kernel");
|
||||
}
|
||||
else if (!usedebugil &&
|
||||
(elfSymName.compare(suffixPos, sizeof(_amdil) - 1, _amdil) == 0)) {
|
||||
index = NDX_AMDIL;
|
||||
assert (((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one amdil symbol for a kernel");
|
||||
}
|
||||
else if (elfSymName.compare(suffixPos, sizeof(_data) - 1, _data) == 0) {
|
||||
index = NDX_METADATA;
|
||||
assert (((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one metadata symbol for the same kernel");
|
||||
}
|
||||
else if (elfSymName.compare(suffixPos, sizeof(_fdata) - 1, _fdata) == 0) {
|
||||
index = NDX_METADATA;
|
||||
isKernel = false;
|
||||
|
||||
FName = elfSymName.substr(offset, suffixPos - offset);
|
||||
|
||||
elfsymbol = tempObj.functionNameMap[FName];
|
||||
sinfo = (elfsymbol != NULL) ? &(elfsymbol->SymInfo[0]) : NULL;
|
||||
|
||||
assert (((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one metadata symbol for a non-kernel function");
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
sinfo = &(elfsymbol->SymInfo[0]);
|
||||
::memset(sinfo, 0, NDX_LAST * sizeof(amd::OclElf::SymbolInfo));
|
||||
tempObj.functionNameMap[FName] = elfsymbol;
|
||||
|
||||
elfsymbol->IsKernel = isKernel;
|
||||
}
|
||||
sinfo[index] = symInfo;
|
||||
}
|
||||
for (amd::Sym_Handle sym = elfIn()->nextSymbol(NULL); sym != NULL;
|
||||
sym = elfIn()->nextSymbol(sym)) {
|
||||
amd::OclElf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(sym, &symInfo)) {
|
||||
LogError("LoadKernelFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string programil;
|
||||
if (usedebugil) {
|
||||
char *section;
|
||||
size_t sz;
|
||||
|
||||
if (elfIn_->getSection(amd::OclElf::ILDEBUG, §ion, &sz)) {
|
||||
// Get debugIL
|
||||
programil.append(section, sz);
|
||||
}
|
||||
else {
|
||||
LogError("LoadKernelFromElf(): reading .debugil failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Append all function metadata to debugIL
|
||||
std::map<std::string, ElfSymbol_t*>::iterator
|
||||
I, IB = tempObj.functionNameMap.begin(), IE = tempObj.functionNameMap.end();
|
||||
for (I = IB; I != IE; ++I) {
|
||||
ElfSymbol_t* elfsymbol = (*I).second;
|
||||
if (elfsymbol == NULL) {
|
||||
// Not valid, skip
|
||||
continue;
|
||||
}
|
||||
if ( (elfsymbol->SymInfo[NDX_METADATA].address != 0) &&
|
||||
(elfsymbol->SymInfo[NDX_METADATA].size > 0) ) {
|
||||
std::string mdString = std::string(elfsymbol->SymInfo[NDX_METADATA].address,
|
||||
elfsymbol->SymInfo[NDX_METADATA].size);
|
||||
assert ((mdString.find_first_of('\0') == std::string::npos) &&
|
||||
"Metadata string has NULL inside !");
|
||||
programil.append(mdString);
|
||||
}
|
||||
}
|
||||
|
||||
const char* ilKernelName =
|
||||
program.getCompilerOptions()->oVariables->JustKernel;
|
||||
if (!program.getAllKernelILs(tempObj.kernelILs, programil, ilKernelName)) {
|
||||
LogError("LoadKernelFromElf(): MDParser failed generating kernel ILs");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, patch the IL from debugIL into functionNameMap[]
|
||||
std::map<std::string, std::string>::iterator
|
||||
KI, KIB = tempObj.kernelILs.begin(), KIE = tempObj.kernelILs.end();
|
||||
for (KI = KIB; KI != KIE; ++KI) {
|
||||
const std::string& kn = (*KI).first;
|
||||
const std::string& ilstr = (*KI).second;
|
||||
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[kn];
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
::memset(elfsymbol->SymInfo, 0, NDX_LAST * sizeof(amd::OclElf::SymbolInfo));
|
||||
tempObj.functionNameMap[kn] = elfsymbol;
|
||||
}
|
||||
amd::OclElf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
|
||||
elfsymbol->IsKernel = true;
|
||||
sinfo[NDX_AMDIL].address = const_cast<char*>(ilstr.data());
|
||||
sinfo[NDX_AMDIL].size = ilstr.size();
|
||||
// All the other fields in SymInfo is unused
|
||||
}
|
||||
std::string elfSymName(symInfo.sym_name);
|
||||
const size_t offset = sizeof(__OpenCL_) - 1;
|
||||
if (elfSymName.compare(0, offset, __OpenCL_) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool recompiled = false;
|
||||
bool hasKernels = false;
|
||||
std::map<std::string, ElfSymbol_t*>::iterator
|
||||
I, IB = tempObj.functionNameMap.begin(), IE = tempObj.functionNameMap.end();
|
||||
// Assume this elfSymName is associated with a kernel name. The following code will adjust
|
||||
// it if it isn't.
|
||||
const size_t suffixPos = elfSymName.rfind('_');
|
||||
bool isKernel = true; // assume it is a kernel
|
||||
std::string FName = elfSymName.substr(0, suffixPos);
|
||||
FName.append("_kernel"); // make the kernel's linkage name
|
||||
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[FName];
|
||||
amd::OclElf::SymbolInfo* sinfo = (elfsymbol != NULL) ? &(elfsymbol->SymInfo[0]) : NULL;
|
||||
|
||||
// Add info for this elf symbol into tempobj's functionNameMap[]
|
||||
int index = -1;
|
||||
if (!usedebugil && (elfSymName.compare(suffixPos, sizeof(_kernel) - 1, _kernel) == 0)) {
|
||||
index = NDX_KERNEL;
|
||||
assert(((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one kernel symbol for the same kernel");
|
||||
} else if (!usedebugil && (elfSymName.compare(suffixPos, sizeof(_header) - 1, _header) == 0)) {
|
||||
index = NDX_HEADER;
|
||||
assert(((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one header symbol for a kernel");
|
||||
} else if (!usedebugil && (elfSymName.compare(suffixPos, sizeof(_amdil) - 1, _amdil) == 0)) {
|
||||
index = NDX_AMDIL;
|
||||
assert(((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one amdil symbol for a kernel");
|
||||
} else if (elfSymName.compare(suffixPos, sizeof(_data) - 1, _data) == 0) {
|
||||
index = NDX_METADATA;
|
||||
assert(((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one metadata symbol for the same kernel");
|
||||
} else if (elfSymName.compare(suffixPos, sizeof(_fdata) - 1, _fdata) == 0) {
|
||||
index = NDX_METADATA;
|
||||
isKernel = false;
|
||||
|
||||
FName = elfSymName.substr(offset, suffixPos - offset);
|
||||
|
||||
elfsymbol = tempObj.functionNameMap[FName];
|
||||
sinfo = (elfsymbol != NULL) ? &(elfsymbol->SymInfo[0]) : NULL;
|
||||
|
||||
assert(((sinfo == NULL) || (sinfo[index].size == 0)) &&
|
||||
"More than one metadata symbol for a non-kernel function");
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
sinfo = &(elfsymbol->SymInfo[0]);
|
||||
::memset(sinfo, 0, NDX_LAST * sizeof(amd::OclElf::SymbolInfo));
|
||||
tempObj.functionNameMap[FName] = elfsymbol;
|
||||
|
||||
elfsymbol->IsKernel = isKernel;
|
||||
}
|
||||
sinfo[index] = symInfo;
|
||||
}
|
||||
}
|
||||
|
||||
std::string programil;
|
||||
if (usedebugil) {
|
||||
char* section;
|
||||
size_t sz;
|
||||
|
||||
if (elfIn_->getSection(amd::OclElf::ILDEBUG, §ion, &sz)) {
|
||||
// Get debugIL
|
||||
programil.append(section, sz);
|
||||
} else {
|
||||
LogError("LoadKernelFromElf(): reading .debugil failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Append all function metadata to debugIL
|
||||
std::map<std::string, ElfSymbol_t *>::iterator I, IB = tempObj.functionNameMap.begin(),
|
||||
IE = tempObj.functionNameMap.end();
|
||||
for (I = IB; I != IE; ++I) {
|
||||
ElfSymbol_t* elfsymbol = (*I).second;
|
||||
if (elfsymbol == NULL) {
|
||||
// Not valid, skip
|
||||
continue;
|
||||
}
|
||||
else if (!elfsymbol->IsKernel) {
|
||||
// Not a kernel. Add its metadata to the OCL binary in case recompilation happens
|
||||
// and the new binary is needed.
|
||||
if (saveAMDIL()&&
|
||||
(elfsymbol->SymInfo[NDX_METADATA].size > 0)) {
|
||||
std::string fmetadata = "__OpenCL_";
|
||||
fmetadata.append((*I).first);
|
||||
fmetadata.append("_fmetadata");
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, fmetadata.c_str(),
|
||||
elfsymbol->SymInfo[NDX_METADATA].address,
|
||||
elfsymbol->SymInfo[NDX_METADATA].size)) {
|
||||
LogError ("AddSymbol() failed to add fmetadata");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
amd::OclElf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
std::string FName = (*I).first;
|
||||
|
||||
// For this kernel, get the demangled kernel name, which is used to identify each kernel.
|
||||
const size_t name_sz = FName.size() - (sizeof(_kernel) - 1) - (sizeof(__OpenCL_) - 1);
|
||||
std::string demangledKName = FName.substr(sizeof(__OpenCL_) - 1, name_sz);
|
||||
|
||||
// Check if the current entry is valid
|
||||
if (((sinfo[NDX_HEADER].size <= 0) || (sinfo[NDX_KERNEL].size <= 0)) &&
|
||||
(sinfo[NDX_AMDIL].size <= 0)) {
|
||||
std::string tlog = "Warning: both IL and CAL Image are not available for kernel " +
|
||||
demangledKName;
|
||||
LogWarning (tlog.c_str());
|
||||
continue;
|
||||
}
|
||||
hasKernels = true;
|
||||
|
||||
Kernel::InitData initData = {0};
|
||||
std::string ilSource(sinfo[NDX_AMDIL].address, sinfo[NDX_AMDIL].size);
|
||||
std::string metadata(sinfo[NDX_METADATA].address, sinfo[NDX_METADATA].size);
|
||||
if ((sinfo[NDX_HEADER].size <= 0) || (sinfo[NDX_KERNEL].size <= 0)) {
|
||||
// IL recompilation
|
||||
// TODO: global data recompilation as well.
|
||||
// 1) parse IL; 2) parse metadata to set up kernel header
|
||||
size_t pos;
|
||||
if (!program.findAllILFuncs((programil.size() ? programil : ilSource), pos)) {
|
||||
program.freeAllILFuncs();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFailed = false;
|
||||
for (uint32_t i=0; i < program.funcs_.size(); ++i) {
|
||||
ILFunc *func = program.funcs_[i];
|
||||
ElfSymbol_t *sym = tempObj.functionNameMap[func->name_];
|
||||
if (sym == NULL) {
|
||||
// No metadata for this function.
|
||||
continue;
|
||||
}
|
||||
|
||||
assert ((func->metadata_.end_ == 0) && "ILFunc init failed");
|
||||
amd::OclElf::SymbolInfo* si = &(sym->SymInfo[0]);
|
||||
if (si[NDX_METADATA].size > 0) {
|
||||
std::string meta(si[NDX_METADATA].address, si[NDX_METADATA].size);
|
||||
if (!program.parseFuncMetadata(meta, 0, std::string::npos)) {
|
||||
isFailed = true;
|
||||
break;
|
||||
}
|
||||
if (func->metadata_.end_ != std::string::npos) {
|
||||
assert( false && "ILFunc name and index does not match");
|
||||
isFailed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Accumulate all emulated local, region and private sizes,
|
||||
// necessary for the kernel execution
|
||||
initData.localSize_ += func->localSize_;
|
||||
initData.privateSize_ += func->privateSize_;
|
||||
|
||||
// Accumulate all HW local, region and private sizes,
|
||||
// necessary for the kernel execution
|
||||
initData.hwLocalSize_ += func->hwLocalSize_;
|
||||
initData.hwPrivateSize_ += func->hwPrivateSize_;
|
||||
initData.flags_ |= func->flags_;
|
||||
}
|
||||
}
|
||||
|
||||
program.freeAllILFuncs();
|
||||
if (isFailed) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
KernelHeaderSymbol kHeader = {0};
|
||||
::memcpy(&kHeader, sinfo[NDX_HEADER].address,
|
||||
(sizeof(kHeader) < sinfo[NDX_HEADER].size)
|
||||
? sizeof(kHeader)
|
||||
: sinfo[NDX_HEADER].size);
|
||||
|
||||
if (kHeader.version_ > VERSION_CURRENT) {
|
||||
LogError("LoadKernelFromElf: cannot handle the newer version of the binary");
|
||||
return false;
|
||||
}
|
||||
|
||||
// VERSION_0
|
||||
initData.localSize_ = kHeader.localSize_;
|
||||
initData.hwLocalSize_ = kHeader.hwLocalSize_;
|
||||
initData.privateSize_ = kHeader.privateSize_;
|
||||
initData.hwPrivateSize_ = kHeader.hwPrivateSize_;
|
||||
initData.flags_ = kHeader.flags_;
|
||||
}
|
||||
|
||||
bool created;
|
||||
NullKernel* gpuKernel = program.createKernel(demangledKName, &initData, ilSource, metadata,
|
||||
&created, sinfo[NDX_KERNEL].address, sinfo[NDX_KERNEL].size);
|
||||
if (!created) {
|
||||
std::string tlog = "Error: Creating kernel during loading OCL binary " +
|
||||
demangledKName + " failed!";
|
||||
LogError(tlog.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
recompiled = recompiled || (sinfo[NDX_KERNEL].size == 0);
|
||||
|
||||
// Add the current kernel to the OCL binary in case recompilation happens and
|
||||
// the new binary is needed.
|
||||
if (!storeKernel(demangledKName, gpuKernel, &initData, metadata, ilSource)) {
|
||||
return false;
|
||||
}
|
||||
ElfSymbol_t* elfsymbol = (*I).second;
|
||||
if (elfsymbol == NULL) {
|
||||
// Not valid, skip
|
||||
continue;
|
||||
}
|
||||
if ((elfsymbol->SymInfo[NDX_METADATA].address != 0) &&
|
||||
(elfsymbol->SymInfo[NDX_METADATA].size > 0)) {
|
||||
std::string mdString = std::string(elfsymbol->SymInfo[NDX_METADATA].address,
|
||||
elfsymbol->SymInfo[NDX_METADATA].size);
|
||||
assert((mdString.find_first_of('\0') == std::string::npos) &&
|
||||
"Metadata string has NULL inside !");
|
||||
programil.append(mdString);
|
||||
}
|
||||
}
|
||||
|
||||
*hasRecompiled = recompiled;
|
||||
return hasKernels;
|
||||
}
|
||||
|
||||
bool
|
||||
ClBinary::storeKernel(
|
||||
const std::string& name,
|
||||
const NullKernel* nullKernel,
|
||||
Kernel::InitData* initData,
|
||||
const std::string& metadata,
|
||||
const std::string& ilSource)
|
||||
{
|
||||
if (!saveISA() && !saveAMDIL()) {
|
||||
return true;
|
||||
const char* ilKernelName = program.getCompilerOptions()->oVariables->JustKernel;
|
||||
if (!program.getAllKernelILs(tempObj.kernelILs, programil, ilKernelName)) {
|
||||
LogError("LoadKernelFromElf(): MDParser failed generating kernel ILs");
|
||||
return false;
|
||||
}
|
||||
|
||||
// should we save kernel metadata only under saveAMDIL()?
|
||||
bool kernelMetaStored = false;
|
||||
// Now, patch the IL from debugIL into functionNameMap[]
|
||||
std::map<std::string, std::string>::iterator KI, KIB = tempObj.kernelILs.begin(),
|
||||
KIE = tempObj.kernelILs.end();
|
||||
for (KI = KIB; KI != KIE; ++KI) {
|
||||
const std::string& kn = (*KI).first;
|
||||
const std::string& ilstr = (*KI).second;
|
||||
|
||||
if (saveAMDIL() && (ilSource.size() > 0)) {
|
||||
// Save IL (this is the per-kernel IL)
|
||||
std::string ilName = "__OpenCL_" + name + "_amdil";
|
||||
if (!elfOut()->addSymbol(amd::OclElf::ILTEXT, ilName.c_str(),
|
||||
ilSource.data(), ilSource.size())) {
|
||||
LogError ("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[kn];
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
::memset(elfsymbol->SymInfo, 0, NDX_LAST * sizeof(amd::OclElf::SymbolInfo));
|
||||
tempObj.functionNameMap[kn] = elfsymbol;
|
||||
}
|
||||
amd::OclElf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
|
||||
std::string metaName = "__OpenCL_" + name + "_metadata";
|
||||
// Save metadata symbols in .rodata
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(),
|
||||
metadata.data(), metadata.size())) {
|
||||
LogError ("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
kernelMetaStored = true;
|
||||
elfsymbol->IsKernel = true;
|
||||
sinfo[NDX_AMDIL].address = const_cast<char*>(ilstr.data());
|
||||
sinfo[NDX_AMDIL].size = ilstr.size();
|
||||
// All the other fields in SymInfo is unused
|
||||
}
|
||||
}
|
||||
|
||||
if (!saveISA()) {
|
||||
return true;
|
||||
bool recompiled = false;
|
||||
bool hasKernels = false;
|
||||
std::map<std::string, ElfSymbol_t *>::iterator I, IB = tempObj.functionNameMap.begin(),
|
||||
IE = tempObj.functionNameMap.end();
|
||||
for (I = IB; I != IE; ++I) {
|
||||
ElfSymbol_t* elfsymbol = (*I).second;
|
||||
if (elfsymbol == NULL) {
|
||||
// Not valid, skip
|
||||
continue;
|
||||
} else if (!elfsymbol->IsKernel) {
|
||||
// Not a kernel. Add its metadata to the OCL binary in case recompilation happens
|
||||
// and the new binary is needed.
|
||||
if (saveAMDIL() && (elfsymbol->SymInfo[NDX_METADATA].size > 0)) {
|
||||
std::string fmetadata = "__OpenCL_";
|
||||
fmetadata.append((*I).first);
|
||||
fmetadata.append("_fmetadata");
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, fmetadata.c_str(),
|
||||
elfsymbol->SymInfo[NDX_METADATA].address,
|
||||
elfsymbol->SymInfo[NDX_METADATA].size)) {
|
||||
LogError("AddSymbol() failed to add fmetadata");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
amd::OclElf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
std::string FName = (*I).first;
|
||||
|
||||
size_t binarySize = (nullKernel != NULL) ? nullKernel->getCalBinarySize() : 0;
|
||||
if (binarySize != 0) {
|
||||
if (!kernelMetaStored) {
|
||||
std::string metaName = "__OpenCL_" + name + "_metadata";
|
||||
// Save metadata symbols in .rodata
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(),
|
||||
metadata.data(), metadata.size())) {
|
||||
LogError ("AddSymbol failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Save kernel symbol that is associated with GPU ISA
|
||||
std::string kernelName = "__OpenCL_" + name + "_kernel";
|
||||
uint8_t* isacode = new uint8_t[binarySize];
|
||||
if (!nullKernel->getCalBinary(
|
||||
reinterpret_cast<void*>(isacode), binarySize)) {
|
||||
LogError("Failed to read GPU kernel isa");
|
||||
delete [] isacode;
|
||||
return false;
|
||||
}
|
||||
if (!elfOut()->addSymbol(amd::OclElf::CAL, kernelName.c_str(),
|
||||
isacode, binarySize)) {
|
||||
LogError ("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
delete [] isacode;
|
||||
// For this kernel, get the demangled kernel name, which is used to identify each kernel.
|
||||
const size_t name_sz = FName.size() - (sizeof(_kernel) - 1) - (sizeof(__OpenCL_) - 1);
|
||||
std::string demangledKName = FName.substr(sizeof(__OpenCL_) - 1, name_sz);
|
||||
|
||||
// Save kernel header information into a pseudo symbol
|
||||
// __OpenCL_<kernelName>_header
|
||||
// for example, given a kernel foo, this pseudo symbol
|
||||
// would be __OpenCL_foo_header
|
||||
std::string headerName = "__OpenCL_" + name + "_header";
|
||||
KernelHeaderSymbol kHeader;
|
||||
// VERSION_0
|
||||
kHeader.privateSize_ = initData->privateSize_;
|
||||
kHeader.localSize_ = initData->localSize_;
|
||||
kHeader.regionSize_ = 0;
|
||||
kHeader.hwPrivateSize_ = initData->hwPrivateSize_;
|
||||
kHeader.hwLocalSize_ = initData->hwLocalSize_;
|
||||
kHeader.hwRegionSize_ = 0;
|
||||
kHeader.flags_ = initData->flags_;
|
||||
|
||||
// VERSION_1
|
||||
kHeader.version_ = VERSION_CURRENT;
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, headerName.c_str(),
|
||||
&kHeader, sizeof(kHeader))) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
// Check if the current entry is valid
|
||||
if (((sinfo[NDX_HEADER].size <= 0) || (sinfo[NDX_KERNEL].size <= 0)) &&
|
||||
(sinfo[NDX_AMDIL].size <= 0)) {
|
||||
std::string tlog =
|
||||
"Warning: both IL and CAL Image are not available for kernel " + demangledKName;
|
||||
LogWarning(tlog.c_str());
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
hasKernels = true;
|
||||
|
||||
bool
|
||||
ClBinary::loadGlobalData(Program& program)
|
||||
{
|
||||
const char __OpenCL_[] = "__OpenCL_";
|
||||
const char _global[] = "_global";
|
||||
|
||||
for (amd::Sym_Handle sym = elfIn()->nextSymbol(NULL);
|
||||
sym != NULL;
|
||||
sym = elfIn()->nextSymbol(sym)) {
|
||||
amd::OclElf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(sym, &symInfo)) {
|
||||
LogError("LoadGlobalDataFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string globalName(symInfo.sym_name);
|
||||
const size_t offset = sizeof(__OpenCL_) - 1;
|
||||
if (globalName.compare(0, offset, __OpenCL_) != 0) {
|
||||
continue;
|
||||
}
|
||||
const size_t suffixPos = globalName.rfind('_');
|
||||
if (globalName.compare(suffixPos, sizeof(_global) - 1, _global) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get index for this global
|
||||
std::string indexString = globalName.substr(offset, suffixPos - offset);
|
||||
uint index = ::atoi(indexString.c_str());
|
||||
|
||||
if (!program.allocGlobalData(symInfo.address, symInfo.size, index)) {
|
||||
LogError("Couldn't load global data");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ClBinary::storeGlobalData(const void* globalData, size_t dataSize, uint index)
|
||||
{
|
||||
// For each global, use "__OpenCL_<globalname>" as its name
|
||||
// Since there is no name in amdil, just use "__OpenCL_<index>_global" for now.
|
||||
std::stringstream glbName;
|
||||
glbName << "__OpenCL_" << index << "_global";
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, glbName.str().c_str(),
|
||||
globalData, dataSize)) {
|
||||
LogError("addSymbol() failed");
|
||||
Kernel::InitData initData = {0};
|
||||
std::string ilSource(sinfo[NDX_AMDIL].address, sinfo[NDX_AMDIL].size);
|
||||
std::string metadata(sinfo[NDX_METADATA].address, sinfo[NDX_METADATA].size);
|
||||
if ((sinfo[NDX_HEADER].size <= 0) || (sinfo[NDX_KERNEL].size <= 0)) {
|
||||
// IL recompilation
|
||||
// TODO: global data recompilation as well.
|
||||
// 1) parse IL; 2) parse metadata to set up kernel header
|
||||
size_t pos;
|
||||
if (!program.findAllILFuncs((programil.size() ? programil : ilSource), pos)) {
|
||||
program.freeAllILFuncs();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ClBinary::clearElfOut()
|
||||
{
|
||||
// Recreate libelf elf object
|
||||
if (!elfOut()->Clear()) {
|
||||
bool isFailed = false;
|
||||
for (uint32_t i = 0; i < program.funcs_.size(); ++i) {
|
||||
ILFunc* func = program.funcs_[i];
|
||||
ElfSymbol_t* sym = tempObj.functionNameMap[func->name_];
|
||||
if (sym == NULL) {
|
||||
// No metadata for this function.
|
||||
continue;
|
||||
}
|
||||
|
||||
assert((func->metadata_.end_ == 0) && "ILFunc init failed");
|
||||
amd::OclElf::SymbolInfo* si = &(sym->SymInfo[0]);
|
||||
if (si[NDX_METADATA].size > 0) {
|
||||
std::string meta(si[NDX_METADATA].address, si[NDX_METADATA].size);
|
||||
if (!program.parseFuncMetadata(meta, 0, std::string::npos)) {
|
||||
isFailed = true;
|
||||
break;
|
||||
}
|
||||
if (func->metadata_.end_ != std::string::npos) {
|
||||
assert(false && "ILFunc name and index does not match");
|
||||
isFailed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Accumulate all emulated local, region and private sizes,
|
||||
// necessary for the kernel execution
|
||||
initData.localSize_ += func->localSize_;
|
||||
initData.privateSize_ += func->privateSize_;
|
||||
|
||||
// Accumulate all HW local, region and private sizes,
|
||||
// necessary for the kernel execution
|
||||
initData.hwLocalSize_ += func->hwLocalSize_;
|
||||
initData.hwPrivateSize_ += func->hwPrivateSize_;
|
||||
initData.flags_ |= func->flags_;
|
||||
}
|
||||
}
|
||||
|
||||
program.freeAllILFuncs();
|
||||
if (isFailed) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
KernelHeaderSymbol kHeader = {0};
|
||||
::memcpy(&kHeader, sinfo[NDX_HEADER].address, (sizeof(kHeader) < sinfo[NDX_HEADER].size)
|
||||
? sizeof(kHeader)
|
||||
: sinfo[NDX_HEADER].size);
|
||||
|
||||
if (kHeader.version_ > VERSION_CURRENT) {
|
||||
LogError("LoadKernelFromElf: cannot handle the newer version of the binary");
|
||||
return false;
|
||||
}
|
||||
|
||||
// VERSION_0
|
||||
initData.localSize_ = kHeader.localSize_;
|
||||
initData.hwLocalSize_ = kHeader.hwLocalSize_;
|
||||
initData.privateSize_ = kHeader.privateSize_;
|
||||
initData.hwPrivateSize_ = kHeader.hwPrivateSize_;
|
||||
initData.flags_ = kHeader.flags_;
|
||||
}
|
||||
|
||||
// Need to re-setup target
|
||||
return setElfTarget();
|
||||
bool created;
|
||||
NullKernel* gpuKernel =
|
||||
program.createKernel(demangledKName, &initData, ilSource, metadata, &created,
|
||||
sinfo[NDX_KERNEL].address, sinfo[NDX_KERNEL].size);
|
||||
if (!created) {
|
||||
std::string tlog =
|
||||
"Error: Creating kernel during loading OCL binary " + demangledKName + " failed!";
|
||||
LogError(tlog.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
recompiled = recompiled || (sinfo[NDX_KERNEL].size == 0);
|
||||
|
||||
// Add the current kernel to the OCL binary in case recompilation happens and
|
||||
// the new binary is needed.
|
||||
if (!storeKernel(demangledKName, gpuKernel, &initData, metadata, ilSource)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*hasRecompiled = recompiled;
|
||||
return hasKernels;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
bool ClBinary::storeKernel(const std::string& name, const NullKernel* nullKernel,
|
||||
Kernel::InitData* initData, const std::string& metadata,
|
||||
const std::string& ilSource) {
|
||||
if (!saveISA() && !saveAMDIL()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// should we save kernel metadata only under saveAMDIL()?
|
||||
bool kernelMetaStored = false;
|
||||
|
||||
if (saveAMDIL() && (ilSource.size() > 0)) {
|
||||
// Save IL (this is the per-kernel IL)
|
||||
std::string ilName = "__OpenCL_" + name + "_amdil";
|
||||
if (!elfOut()->addSymbol(amd::OclElf::ILTEXT, ilName.c_str(), ilSource.data(),
|
||||
ilSource.size())) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string metaName = "__OpenCL_" + name + "_metadata";
|
||||
// Save metadata symbols in .rodata
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(), metadata.data(),
|
||||
metadata.size())) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
kernelMetaStored = true;
|
||||
}
|
||||
|
||||
if (!saveISA()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t binarySize = (nullKernel != NULL) ? nullKernel->getCalBinarySize() : 0;
|
||||
if (binarySize != 0) {
|
||||
if (!kernelMetaStored) {
|
||||
std::string metaName = "__OpenCL_" + name + "_metadata";
|
||||
// Save metadata symbols in .rodata
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, metaName.c_str(), metadata.data(),
|
||||
metadata.size())) {
|
||||
LogError("AddSymbol failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Save kernel symbol that is associated with GPU ISA
|
||||
std::string kernelName = "__OpenCL_" + name + "_kernel";
|
||||
uint8_t* isacode = new uint8_t[binarySize];
|
||||
if (!nullKernel->getCalBinary(reinterpret_cast<void*>(isacode), binarySize)) {
|
||||
LogError("Failed to read GPU kernel isa");
|
||||
delete[] isacode;
|
||||
return false;
|
||||
}
|
||||
if (!elfOut()->addSymbol(amd::OclElf::CAL, kernelName.c_str(), isacode, binarySize)) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
delete[] isacode;
|
||||
|
||||
// Save kernel header information into a pseudo symbol
|
||||
// __OpenCL_<kernelName>_header
|
||||
// for example, given a kernel foo, this pseudo symbol
|
||||
// would be __OpenCL_foo_header
|
||||
std::string headerName = "__OpenCL_" + name + "_header";
|
||||
KernelHeaderSymbol kHeader;
|
||||
// VERSION_0
|
||||
kHeader.privateSize_ = initData->privateSize_;
|
||||
kHeader.localSize_ = initData->localSize_;
|
||||
kHeader.regionSize_ = 0;
|
||||
kHeader.hwPrivateSize_ = initData->hwPrivateSize_;
|
||||
kHeader.hwLocalSize_ = initData->hwLocalSize_;
|
||||
kHeader.hwRegionSize_ = 0;
|
||||
kHeader.flags_ = initData->flags_;
|
||||
|
||||
// VERSION_1
|
||||
kHeader.version_ = VERSION_CURRENT;
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, headerName.c_str(), &kHeader, sizeof(kHeader))) {
|
||||
LogError("AddElfSymbol failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClBinary::loadGlobalData(Program& program) {
|
||||
const char __OpenCL_[] = "__OpenCL_";
|
||||
const char _global[] = "_global";
|
||||
|
||||
for (amd::Sym_Handle sym = elfIn()->nextSymbol(NULL); sym != NULL;
|
||||
sym = elfIn()->nextSymbol(sym)) {
|
||||
amd::OclElf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(sym, &symInfo)) {
|
||||
LogError("LoadGlobalDataFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string globalName(symInfo.sym_name);
|
||||
const size_t offset = sizeof(__OpenCL_) - 1;
|
||||
if (globalName.compare(0, offset, __OpenCL_) != 0) {
|
||||
continue;
|
||||
}
|
||||
const size_t suffixPos = globalName.rfind('_');
|
||||
if (globalName.compare(suffixPos, sizeof(_global) - 1, _global) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get index for this global
|
||||
std::string indexString = globalName.substr(offset, suffixPos - offset);
|
||||
uint index = ::atoi(indexString.c_str());
|
||||
|
||||
if (!program.allocGlobalData(symInfo.address, symInfo.size, index)) {
|
||||
LogError("Couldn't load global data");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClBinary::storeGlobalData(const void* globalData, size_t dataSize, uint index) {
|
||||
// For each global, use "__OpenCL_<globalname>" as its name
|
||||
// Since there is no name in amdil, just use "__OpenCL_<index>_global" for now.
|
||||
std::stringstream glbName;
|
||||
glbName << "__OpenCL_" << index << "_global";
|
||||
|
||||
if (!elfOut()->addSymbol(amd::OclElf::RODATA, glbName.str().c_str(), globalData, dataSize)) {
|
||||
LogError("addSymbol() failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClBinary::clearElfOut() {
|
||||
// Recreate libelf elf object
|
||||
if (!elfOut()->Clear()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Need to re-setup target
|
||||
return setElfTarget();
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -10,134 +10,117 @@
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class ClBinary : public device::ClBinary
|
||||
{
|
||||
public:
|
||||
|
||||
class ClBinary : public device::ClBinary {
|
||||
public:
|
||||
#pragma pack(push, 8)
|
||||
// Kernel version in the ELF header symbol
|
||||
enum KernelVersions {
|
||||
VERSION_0 = 0,
|
||||
VERSION_1,
|
||||
VERSION_CURRENT = VERSION_1
|
||||
};
|
||||
// Kernel version in the ELF header symbol
|
||||
enum KernelVersions { VERSION_0 = 0, VERSION_1, VERSION_CURRENT = VERSION_1 };
|
||||
|
||||
/* This is the ELF header symbol */
|
||||
struct KernelHeaderSymbol {
|
||||
/* VERSION_0
|
||||
Version 0 has 8 uint32_t (32 bytes), top 5 are used, the rest zero'ed.
|
||||
In Version_0, KernelHeaderSymbol is the same as KernelHeader
|
||||
*/
|
||||
uint32_t privateSize_; //!< Emulated private memory size
|
||||
uint32_t localSize_; //!< Emulated local memory size
|
||||
uint32_t hwPrivateSize_; //!< HW private memory size
|
||||
uint32_t hwLocalSize_; //!< HW local memory size
|
||||
uint32_t flags_; //!< Kernel's flags
|
||||
/* This is the ELF header symbol */
|
||||
struct KernelHeaderSymbol {
|
||||
/* VERSION_0
|
||||
Version 0 has 8 uint32_t (32 bytes), top 5 are used, the rest zero'ed.
|
||||
In Version_0, KernelHeaderSymbol is the same as KernelHeader
|
||||
*/
|
||||
uint32_t privateSize_; //!< Emulated private memory size
|
||||
uint32_t localSize_; //!< Emulated local memory size
|
||||
uint32_t hwPrivateSize_; //!< HW private memory size
|
||||
uint32_t hwLocalSize_; //!< HW local memory size
|
||||
uint32_t flags_; //!< Kernel's flags
|
||||
|
||||
/* VERSION_1
|
||||
VERSION_1 has 6 uint32_t.
|
||||
*/
|
||||
uint32_t version_; //!< Kernel's version
|
||||
uint32_t regionSize_; //!< Region memory size
|
||||
uint32_t hwRegionSize_; //!< HW region memory size
|
||||
/* VERSION_1
|
||||
VERSION_1 has 6 uint32_t.
|
||||
*/
|
||||
uint32_t version_; //!< Kernel's version
|
||||
uint32_t regionSize_; //!< Region memory size
|
||||
uint32_t hwRegionSize_; //!< HW region memory size
|
||||
|
||||
/* New entries can be added here, do not change the previous entries */
|
||||
};
|
||||
/* New entries can be added here, do not change the previous entries */
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//! Constructor
|
||||
ClBinary(const NullDevice& dev)
|
||||
: device::ClBinary(dev)
|
||||
{}
|
||||
//! Constructor
|
||||
ClBinary(const NullDevice& dev) : device::ClBinary(dev) {}
|
||||
|
||||
//! Destructor
|
||||
~ClBinary() {}
|
||||
//! Destructor
|
||||
~ClBinary() {}
|
||||
|
||||
//! Creates and loads kernels from the OCL ELF binary file into the program
|
||||
bool loadKernels(
|
||||
NullProgram& program, //!< Program object with the binary
|
||||
bool* hasRecompiled //!< Recompile amdil to isa.
|
||||
);
|
||||
//! Creates and loads kernels from the OCL ELF binary file into the program
|
||||
bool loadKernels(NullProgram& program, //!< Program object with the binary
|
||||
bool* hasRecompiled //!< Recompile amdil to isa.
|
||||
);
|
||||
|
||||
//! Stores compiled kernel into the OCL ELF binary file
|
||||
bool storeKernel(
|
||||
const std::string& name, //!< Kernel's name
|
||||
const NullKernel* nullKernel, //!< The kernel to add
|
||||
Kernel::InitData* initData, //!< Kernel init data
|
||||
const std::string& metadata, //!< Kernel's metadata
|
||||
const std::string& ilSource //!< IL source text
|
||||
);
|
||||
//! Stores compiled kernel into the OCL ELF binary file
|
||||
bool storeKernel(const std::string& name, //!< Kernel's name
|
||||
const NullKernel* nullKernel, //!< The kernel to add
|
||||
Kernel::InitData* initData, //!< Kernel init data
|
||||
const std::string& metadata, //!< Kernel's metadata
|
||||
const std::string& ilSource //!< IL source text
|
||||
);
|
||||
|
||||
//! Loads the program's global data
|
||||
bool loadGlobalData(
|
||||
Program& program //!< The program object for the global data load
|
||||
);
|
||||
//! Loads the program's global data
|
||||
bool loadGlobalData(Program& program //!< The program object for the global data load
|
||||
);
|
||||
|
||||
//! Stores the program's global data
|
||||
bool storeGlobalData(
|
||||
const void* globalData, //!< The program global data
|
||||
size_t dataSize, //!< The program global data size
|
||||
uint index //!< The global data storage index
|
||||
);
|
||||
//! Stores the program's global data
|
||||
bool storeGlobalData(const void* globalData, //!< The program global data
|
||||
size_t dataSize, //!< The program global data size
|
||||
uint index //!< The global data storage index
|
||||
);
|
||||
|
||||
//! Set elf header information for GPU target
|
||||
bool setElfTarget() {
|
||||
uint32_t target = static_cast<uint32_t>(dev().calTarget());
|
||||
assert (((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
|
||||
uint16_t elf_target = (uint16_t)(0x7FFF & target);
|
||||
return elfOut()->setTarget(elf_target, amd::OclElf::CAL_PLATFORM);
|
||||
}
|
||||
//! Set elf header information for GPU target
|
||||
bool setElfTarget() {
|
||||
uint32_t target = static_cast<uint32_t>(dev().calTarget());
|
||||
assert(((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
|
||||
uint16_t elf_target = (uint16_t)(0x7FFF & target);
|
||||
return elfOut()->setTarget(elf_target, amd::OclElf::CAL_PLATFORM);
|
||||
}
|
||||
|
||||
//! Clear elf out.
|
||||
bool clearElfOut();
|
||||
//! Clear elf out.
|
||||
bool clearElfOut();
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
ClBinary(const ClBinary&);
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
ClBinary(const ClBinary&);
|
||||
|
||||
//! Disable default operator=
|
||||
ClBinary& operator=(const ClBinary&);
|
||||
|
||||
//! Returns the GPU device for this object
|
||||
const NullDevice& dev() const { return static_cast<const NullDevice&>(dev_); }
|
||||
//! Disable default operator=
|
||||
ClBinary& operator=(const ClBinary&);
|
||||
|
||||
//! Returns the GPU device for this object
|
||||
const NullDevice& dev() const { return static_cast<const NullDevice&>(dev_); }
|
||||
};
|
||||
|
||||
class ClBinaryHsa : public device::ClBinary
|
||||
{
|
||||
public:
|
||||
ClBinaryHsa(const Device& dev, BinaryImageFormat bifVer = BIF_VERSION3)
|
||||
: device::ClBinary(dev, bifVer)
|
||||
{}
|
||||
class ClBinaryHsa : public device::ClBinary {
|
||||
public:
|
||||
ClBinaryHsa(const Device& dev, BinaryImageFormat bifVer = BIF_VERSION3)
|
||||
: device::ClBinary(dev, bifVer) {}
|
||||
|
||||
//! Destructor
|
||||
~ClBinaryHsa() {}
|
||||
//! Destructor
|
||||
~ClBinaryHsa() {}
|
||||
|
||||
|
||||
protected:
|
||||
bool setElfTarget() {
|
||||
uint32_t target = static_cast<uint32_t>(21);//dev().calTarget());
|
||||
assert (((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
|
||||
uint16_t elf_target = (uint16_t)(0x7FFF & target);
|
||||
return elfOut()->setTarget(elf_target, amd::OclElf::CAL_PLATFORM);
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
bool setElfTarget() {
|
||||
uint32_t target = static_cast<uint32_t>(21); // dev().calTarget());
|
||||
assert(((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
|
||||
uint16_t elf_target = (uint16_t)(0x7FFF & target);
|
||||
return elfOut()->setTarget(elf_target, amd::OclElf::CAL_PLATFORM);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
ClBinaryHsa(const ClBinaryHsa&);
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
ClBinaryHsa(const ClBinaryHsa&);
|
||||
|
||||
//! Disable default operator=
|
||||
ClBinaryHsa& operator=(const ClBinaryHsa&);
|
||||
|
||||
//! Returns the HSA device for this object
|
||||
const Device& dev() const { return static_cast<const Device&>(dev_); }
|
||||
//! Disable default operator=
|
||||
ClBinaryHsa& operator=(const ClBinaryHsa&);
|
||||
|
||||
//! Returns the HSA device for this object
|
||||
const Device& dev() const { return static_cast<const Device&>(dev_); }
|
||||
};
|
||||
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUBINARY_HPP_
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUBINARY_HPP_
|
||||
+2201
-2590
File diff suppressed because it is too large.
Load diff
@@ -24,429 +24,385 @@ class Memory;
|
||||
class VirtualGPU;
|
||||
|
||||
//! DMA Blit Manager
|
||||
class DmaBlitManager : public device::HostBlitManager
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
DmaBlitManager(
|
||||
VirtualGPU& gpu, //!< Virtual GPU to be used for blits
|
||||
Setup setup = Setup() //!< Specifies HW accelerated blits
|
||||
);
|
||||
class DmaBlitManager : public device::HostBlitManager {
|
||||
public:
|
||||
//! Constructor
|
||||
DmaBlitManager(VirtualGPU& gpu, //!< Virtual GPU to be used for blits
|
||||
Setup setup = Setup() //!< Specifies HW accelerated blits
|
||||
);
|
||||
|
||||
//! Destructor
|
||||
virtual ~DmaBlitManager() {}
|
||||
//! Destructor
|
||||
virtual ~DmaBlitManager() {}
|
||||
|
||||
//! Creates DmaBlitManager object
|
||||
virtual bool create(amd::Device& device) { return true; }
|
||||
//! Creates DmaBlitManager object
|
||||
virtual bool create(amd::Device& device) { return true; }
|
||||
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBuffer(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBuffer(device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBufferRect(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destinaiton host memory
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBufferRect(device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destinaiton host memory
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies an image object to system memory
|
||||
virtual bool readImage(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies an image object to system memory
|
||||
virtual bool readImage(device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBuffer(
|
||||
const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBuffer(const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBufferRect(
|
||||
const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBufferRect(const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies system memory to an image object
|
||||
virtual bool writeImage(
|
||||
const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies system memory to an image object
|
||||
virtual bool writeImage(const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to another buffer object
|
||||
virtual bool copyBuffer(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to another buffer object
|
||||
virtual bool copyBuffer(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to another buffer object
|
||||
virtual bool copyBufferRect(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& srcRect, //!< Source rectangle
|
||||
const amd::BufferRect& dstRect, //!< Destination rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to another buffer object
|
||||
virtual bool copyBufferRect(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& srcRect, //!< Source rectangle
|
||||
const amd::BufferRect& dstRect, //!< Destination rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies an image object to a buffer object
|
||||
virtual bool copyImageToBuffer(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
//! Copies an image object to a buffer object
|
||||
virtual bool copyImageToBuffer(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to an image object
|
||||
virtual bool copyBufferToImage(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
//! Copies a buffer object to an image object
|
||||
virtual bool copyBufferToImage(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
|
||||
//! Copies an image object to another image object
|
||||
virtual bool copyImage(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies an image object to another image object
|
||||
virtual bool copyImage(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
protected:
|
||||
const static uint MaxPinnedBuffers = 4;
|
||||
protected:
|
||||
const static uint MaxPinnedBuffers = 4;
|
||||
|
||||
//! Synchronizes the blit operations if necessary
|
||||
inline void synchronize() const;
|
||||
//! Synchronizes the blit operations if necessary
|
||||
inline void synchronize() const;
|
||||
|
||||
//! Returns the virtual GPU object
|
||||
VirtualGPU& gpu() const { return static_cast<VirtualGPU&>(vDev_); }
|
||||
//! Returns the virtual GPU object
|
||||
VirtualGPU& gpu() const { return static_cast<VirtualGPU&>(vDev_); }
|
||||
|
||||
//! Returns the GPU device object
|
||||
const Device& dev() const { return static_cast<const Device&>(dev_); };
|
||||
//! Returns the GPU device object
|
||||
const Device& dev() const { return static_cast<const Device&>(dev_); };
|
||||
|
||||
inline Memory& gpuMem(device::Memory& mem) const;
|
||||
inline Memory& gpuMem(device::Memory& mem) const;
|
||||
|
||||
//! Pins host memory for GPU access
|
||||
amd::Memory* pinHostMemory(
|
||||
const void* hostMem, //!< Host memory pointer
|
||||
size_t pinSize, //!< Host memory size
|
||||
size_t& partial //!< Extra offset for memory alignment
|
||||
) const;
|
||||
//! Pins host memory for GPU access
|
||||
amd::Memory* pinHostMemory(const void* hostMem, //!< Host memory pointer
|
||||
size_t pinSize, //!< Host memory size
|
||||
size_t& partial //!< Extra offset for memory alignment
|
||||
) const;
|
||||
|
||||
const size_t MinSizeForPinnedTransfer;
|
||||
bool completeOperation_; //!< DMA blit manager must complete operation
|
||||
amd::Context* context_; //!< A dummy context
|
||||
const size_t MinSizeForPinnedTransfer;
|
||||
bool completeOperation_; //!< DMA blit manager must complete operation
|
||||
amd::Context* context_; //!< A dummy context
|
||||
|
||||
private:
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
DmaBlitManager(const DmaBlitManager&);
|
||||
|
||||
//! Disable copy constructor
|
||||
DmaBlitManager(const DmaBlitManager&);
|
||||
//! Disable operator=
|
||||
DmaBlitManager& operator=(const DmaBlitManager&);
|
||||
|
||||
//! Disable operator=
|
||||
DmaBlitManager& operator=(const DmaBlitManager&);
|
||||
//! Reads video memory, using a staged buffer
|
||||
bool readMemoryStaged(Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
Memory** xferBuf, //!< Staged buffer for read
|
||||
size_t origin, //!< Original offset in the source memory
|
||||
size_t& offset, //!< Offset for the current copy pointer
|
||||
size_t& totalSize, //!< Total size for copy region
|
||||
size_t xferSize //!< Transfer size
|
||||
) const;
|
||||
|
||||
//! Reads video memory, using a staged buffer
|
||||
bool readMemoryStaged(
|
||||
Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
Memory** xferBuf, //!< Staged buffer for read
|
||||
size_t origin, //!< Original offset in the source memory
|
||||
size_t& offset, //!< Offset for the current copy pointer
|
||||
size_t& totalSize, //!< Total size for copy region
|
||||
size_t xferSize //!< Transfer size
|
||||
) const;
|
||||
|
||||
//! Write into video memory, using a staged buffer
|
||||
bool writeMemoryStaged(
|
||||
const void* srcHost, //!< Source host memory
|
||||
Memory& dstMemory, //!< Destination memory object
|
||||
Memory& xferBuf, //!< Staged buffer for write
|
||||
size_t origin, //!< Original offset in the destination memory
|
||||
size_t& offset, //!< Offset for the current copy pointer
|
||||
size_t& totalSize, //!< Total size for the copy region
|
||||
size_t xferSize //!< Transfer size
|
||||
) const;
|
||||
//! Write into video memory, using a staged buffer
|
||||
bool writeMemoryStaged(const void* srcHost, //!< Source host memory
|
||||
Memory& dstMemory, //!< Destination memory object
|
||||
Memory& xferBuf, //!< Staged buffer for write
|
||||
size_t origin, //!< Original offset in the destination memory
|
||||
size_t& offset, //!< Offset for the current copy pointer
|
||||
size_t& totalSize, //!< Total size for the copy region
|
||||
size_t xferSize //!< Transfer size
|
||||
) const;
|
||||
};
|
||||
|
||||
//! Kernel Blit Manager
|
||||
class KernelBlitManager : public DmaBlitManager
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
BlitCopyImage = 0,
|
||||
BlitCopyImage1DA,
|
||||
BlitCopyImageToBuffer,
|
||||
BlitCopyBufferToImage,
|
||||
BlitCopyBufferRect,
|
||||
BlitCopyBufferRectAligned,
|
||||
BlitCopyBuffer,
|
||||
BlitCopyBufferAligned,
|
||||
FillBuffer,
|
||||
FillImage,
|
||||
Scheduler,
|
||||
BlitTotal
|
||||
};
|
||||
class KernelBlitManager : public DmaBlitManager {
|
||||
public:
|
||||
enum {
|
||||
BlitCopyImage = 0,
|
||||
BlitCopyImage1DA,
|
||||
BlitCopyImageToBuffer,
|
||||
BlitCopyBufferToImage,
|
||||
BlitCopyBufferRect,
|
||||
BlitCopyBufferRectAligned,
|
||||
BlitCopyBuffer,
|
||||
BlitCopyBufferAligned,
|
||||
FillBuffer,
|
||||
FillImage,
|
||||
Scheduler,
|
||||
BlitTotal
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
KernelBlitManager(
|
||||
VirtualGPU& gpu, //!< Virtual GPU to be used for blits
|
||||
Setup setup = Setup() //!< Specifies HW accelerated blits
|
||||
);
|
||||
//! Constructor
|
||||
KernelBlitManager(VirtualGPU& gpu, //!< Virtual GPU to be used for blits
|
||||
Setup setup = Setup() //!< Specifies HW accelerated blits
|
||||
);
|
||||
|
||||
//! Destructor
|
||||
virtual ~KernelBlitManager();
|
||||
//! Destructor
|
||||
virtual ~KernelBlitManager();
|
||||
|
||||
//! Creates DmaBlitManager object
|
||||
virtual bool create(amd::Device& device);
|
||||
//! Creates DmaBlitManager object
|
||||
virtual bool create(amd::Device& device);
|
||||
|
||||
//! Copies a buffer object to another buffer object
|
||||
virtual bool copyBufferRect(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& srcRectIn, //!< Source rectangle
|
||||
const amd::BufferRect& dstRectIn, //!< Destination rectangle
|
||||
const amd::Coord3D& sizeIn, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to another buffer object
|
||||
virtual bool copyBufferRect(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& srcRectIn, //!< Source rectangle
|
||||
const amd::BufferRect& dstRectIn, //!< Destination rectangle
|
||||
const amd::Coord3D& sizeIn, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBuffer(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBuffer(device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBufferRect(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destinaiton host memory
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to system memory
|
||||
virtual bool readBufferRect(device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destinaiton host memory
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBuffer(
|
||||
const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBuffer(const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBufferRect(
|
||||
const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies system memory to a buffer object
|
||||
virtual bool writeBufferRect(const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::BufferRect& hostRect, //!< Destination rectangle
|
||||
const amd::BufferRect& bufRect, //!< Source rectangle
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to an image object
|
||||
virtual bool copyBuffer(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies a buffer object to an image object
|
||||
virtual bool copyBuffer(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies a buffer object to an image object
|
||||
virtual bool copyBufferToImage(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
//! Copies a buffer object to an image object
|
||||
virtual bool copyBufferToImage(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
|
||||
//! Copies an image object to a buffer object
|
||||
virtual bool copyImageToBuffer(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
//! Copies an image object to a buffer object
|
||||
virtual bool copyImageToBuffer(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
|
||||
//! Copies an image object to another image object
|
||||
virtual bool copyImage(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies an image object to another image object
|
||||
virtual bool copyImage(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies an image object to system memory
|
||||
virtual bool readImage(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies an image object to system memory
|
||||
virtual bool readImage(device::Memory& srcMemory, //!< Source memory object
|
||||
void* dstHost, //!< Destination host memory
|
||||
const amd::Coord3D& origin, //!< Source origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Copies system memory to an image object
|
||||
virtual bool writeImage(
|
||||
const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Copies system memory to an image object
|
||||
virtual bool writeImage(const void* srcHost, //!< Source host memory
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
size_t rowPitch, //!< Row pitch for host memory
|
||||
size_t slicePitch, //!< Slice pitch for host memory
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Fills a buffer memory with a pattern data
|
||||
virtual bool fillBuffer(
|
||||
device::Memory& memory, //!< Memory object to fill with pattern
|
||||
const void* pattern, //!< Pattern data
|
||||
size_t patternSize, //!< Pattern size
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Fills a buffer memory with a pattern data
|
||||
virtual bool fillBuffer(device::Memory& memory, //!< Memory object to fill with pattern
|
||||
const void* pattern, //!< Pattern data
|
||||
size_t patternSize, //!< Pattern size
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Fills an image memory with a pattern data
|
||||
virtual bool fillImage(
|
||||
device::Memory& dstMemory, //!< Memory object to fill with pattern
|
||||
const void* pattern, //!< Pattern data
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
//! Fills an image memory with a pattern data
|
||||
virtual bool fillImage(device::Memory& dstMemory, //!< Memory object to fill with pattern
|
||||
const void* pattern, //!< Pattern data
|
||||
const amd::Coord3D& origin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false //!< Entire buffer will be updated
|
||||
) const;
|
||||
|
||||
//! Fills an image memory with a pattern data
|
||||
virtual bool runScheduler(
|
||||
device::Memory& vqueue, //!< Memory object for virtual queue
|
||||
device::Memory& params, //!< Extra arguments for the scheduler
|
||||
uint paramIdx, //!< Parameter index
|
||||
uint threads //!< Number of scheduling threads
|
||||
) const;
|
||||
//! Fills an image memory with a pattern data
|
||||
virtual bool runScheduler(device::Memory& vqueue, //!< Memory object for virtual queue
|
||||
device::Memory& params, //!< Extra arguments for the scheduler
|
||||
uint paramIdx, //!< Parameter index
|
||||
uint threads //!< Number of scheduling threads
|
||||
) const;
|
||||
|
||||
private:
|
||||
static const size_t MaxXferBuffers = 2;
|
||||
static const uint TransferSplitSize = 3;
|
||||
private:
|
||||
static const size_t MaxXferBuffers = 2;
|
||||
static const uint TransferSplitSize = 3;
|
||||
|
||||
//! Copies a buffer object to an image object
|
||||
bool copyBufferToImageKernel(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
//! Copies a buffer object to an image object
|
||||
bool copyBufferToImageKernel(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
|
||||
//! Copies an image object to a buffer object
|
||||
bool copyImageToBufferKernel(
|
||||
device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
//! Copies an image object to a buffer object
|
||||
bool copyImageToBufferKernel(device::Memory& srcMemory, //!< Source memory object
|
||||
device::Memory& dstMemory, //!< Destination memory object
|
||||
const amd::Coord3D& srcOrigin, //!< Source origin
|
||||
const amd::Coord3D& dstOrigin, //!< Destination origin
|
||||
const amd::Coord3D& size, //!< Size of the copy region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
size_t rowPitch = 0, //!< Pitch for buffer
|
||||
size_t slicePitch = 0 //!< Slice for buffer
|
||||
) const;
|
||||
|
||||
//! Creates a program for all blit operations
|
||||
bool createProgram(
|
||||
Device& device //!< Device object
|
||||
);
|
||||
//! Creates a program for all blit operations
|
||||
bool createProgram(Device& device //!< Device object
|
||||
);
|
||||
|
||||
//! Creates a view memory object
|
||||
Memory* createView(
|
||||
const Memory& parent, //!< Parent memory object
|
||||
const CalFormat& format //!< The new format for a view
|
||||
) const;
|
||||
//! Creates a view memory object
|
||||
Memory* createView(const Memory& parent, //!< Parent memory object
|
||||
const CalFormat& format //!< The new format for a view
|
||||
) const;
|
||||
|
||||
//! Disable copy constructor
|
||||
KernelBlitManager(const KernelBlitManager&);
|
||||
//! Disable copy constructor
|
||||
KernelBlitManager(const KernelBlitManager&);
|
||||
|
||||
//! Disable operator=
|
||||
KernelBlitManager& operator=(const KernelBlitManager&);
|
||||
//! Disable operator=
|
||||
KernelBlitManager& operator=(const KernelBlitManager&);
|
||||
|
||||
amd::Program* program_; //!< GPU program obejct
|
||||
amd::Kernel* kernels_[BlitTotal]; //!< GPU kernels for blit
|
||||
amd::Memory* constantBuffer_; //!< An internal CB for blits
|
||||
amd::Memory* xferBuffers_[MaxXferBuffers]; //!< Transfer buffers for images
|
||||
size_t xferBufferSize_; //!< Transfer buffer size
|
||||
amd::Monitor* lockXferOps_; //!< Lock transfer operation
|
||||
amd::Program* program_; //!< GPU program obejct
|
||||
amd::Kernel* kernels_[BlitTotal]; //!< GPU kernels for blit
|
||||
amd::Memory* constantBuffer_; //!< An internal CB for blits
|
||||
amd::Memory* xferBuffers_[MaxXferBuffers]; //!< Transfer buffers for images
|
||||
size_t xferBufferSize_; //!< Transfer buffer size
|
||||
amd::Monitor* lockXferOps_; //!< Lock transfer operation
|
||||
};
|
||||
|
||||
static const char* BlitName[KernelBlitManager::BlitTotal] = {
|
||||
"copyImage",
|
||||
"copyImage1DA",
|
||||
"copyImageToBuffer",
|
||||
"copyBufferToImage",
|
||||
"copyBufferRect",
|
||||
"copyBufferRectAligned",
|
||||
"copyBuffer",
|
||||
"copyBufferAligned",
|
||||
"fillBuffer",
|
||||
"fillImage",
|
||||
"scheduler",
|
||||
};
|
||||
"copyImage", "copyImage1DA", "copyImageToBuffer",
|
||||
"copyBufferToImage", "copyBufferRect", "copyBufferRectAligned",
|
||||
"copyBuffer", "copyBufferAligned", "fillBuffer",
|
||||
"fillImage", "scheduler",
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
|
||||
@@ -14,444 +14,427 @@
|
||||
#include "utils/options.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
//CLC_IN_PROCESS_CHANGE
|
||||
// CLC_IN_PROCESS_CHANGE
|
||||
extern int openclFrontEnd(const char* cmdline, std::string*, std::string* typeInfo = NULL);
|
||||
|
||||
namespace gpu {
|
||||
|
||||
static int programsCount = 0;
|
||||
|
||||
bool
|
||||
NullProgram::compileImpl(const std::string& src,
|
||||
const std::vector<const std::string*>& headers,
|
||||
const char** headerIncludeNames,
|
||||
amd::option::Options* options)
|
||||
{
|
||||
std::string sourceCode = src;
|
||||
bool NullProgram::compileImpl(const std::string& src,
|
||||
const std::vector<const std::string*>& headers,
|
||||
const char** headerIncludeNames, amd::option::Options* options) {
|
||||
std::string sourceCode = src;
|
||||
|
||||
if (dev().settings().debugFlags_ & Settings::CheckForILSource) {
|
||||
size_t inc = sourceCode.find("il_cs_", 0);
|
||||
if (inc != std::string::npos) {
|
||||
// CL program is an IL program
|
||||
ilProgram_ = sourceCode;
|
||||
return true;
|
||||
}
|
||||
if (dev().settings().debugFlags_ & Settings::CheckForILSource) {
|
||||
size_t inc = sourceCode.find("il_cs_", 0);
|
||||
if (inc != std::string::npos) {
|
||||
// CL program is an IL program
|
||||
ilProgram_ = sourceCode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string tempFolder = amd::Os::getTempPath();
|
||||
std::string tempFileName = amd::Os::getTempFileName();
|
||||
std::string tempFolder = amd::Os::getTempPath();
|
||||
std::string tempFileName = amd::Os::getTempFileName();
|
||||
|
||||
if (dev().settings().debugFlags_ & Settings::StubCLPrograms) {
|
||||
std::stringstream fileName;
|
||||
std::fstream stubRead;
|
||||
// Dump the IL function
|
||||
fileName << "program_" << programsCount++ << ".cl";
|
||||
stubRead.open(fileName.str().c_str(), (std::fstream::in | std::fstream::binary));
|
||||
// Check if we have OpenCL program
|
||||
if (stubRead.is_open()) {
|
||||
// Find the stream size
|
||||
stubRead.seekg(0, std::fstream::end);
|
||||
size_t size = stubRead.tellg();
|
||||
stubRead.seekg(0, std::ios::beg);
|
||||
if (dev().settings().debugFlags_ & Settings::StubCLPrograms) {
|
||||
std::stringstream fileName;
|
||||
std::fstream stubRead;
|
||||
// Dump the IL function
|
||||
fileName << "program_" << programsCount++ << ".cl";
|
||||
stubRead.open(fileName.str().c_str(), (std::fstream::in | std::fstream::binary));
|
||||
// Check if we have OpenCL program
|
||||
if (stubRead.is_open()) {
|
||||
// Find the stream size
|
||||
stubRead.seekg(0, std::fstream::end);
|
||||
size_t size = stubRead.tellg();
|
||||
stubRead.seekg(0, std::ios::beg);
|
||||
|
||||
char* data = new char[size];
|
||||
stubRead.read(data, size);
|
||||
stubRead.close();
|
||||
char* data = new char[size];
|
||||
stubRead.read(data, size);
|
||||
stubRead.close();
|
||||
|
||||
sourceCode.assign(data, size);
|
||||
delete[] data;
|
||||
}
|
||||
else {
|
||||
std::fstream stubWrite;
|
||||
stubWrite.open(fileName.str().c_str(),
|
||||
(std::fstream::out | std::fstream::binary));
|
||||
stubWrite << sourceCode;
|
||||
stubWrite.close();
|
||||
}
|
||||
sourceCode.assign(data, size);
|
||||
delete[] data;
|
||||
} else {
|
||||
std::fstream stubWrite;
|
||||
stubWrite.open(fileName.str().c_str(), (std::fstream::out | std::fstream::binary));
|
||||
stubWrite << sourceCode;
|
||||
stubWrite.close();
|
||||
}
|
||||
}
|
||||
|
||||
std::fstream f;
|
||||
std::vector<std::string> headerFileNames(headers.size());
|
||||
std::vector<std::string> newDirs;
|
||||
for (size_t i = 0; i < headers.size(); ++i) {
|
||||
std::string headerPath = tempFolder;
|
||||
std::string headerIncludeName(headerIncludeNames[i]);
|
||||
// replace / in path with current os's file separator
|
||||
if ( amd::Os::fileSeparator() != '/') {
|
||||
for (std::string::iterator it = headerIncludeName.begin(),
|
||||
end = headerIncludeName.end();
|
||||
it != end;
|
||||
++it) {
|
||||
if (*it == '/') *it = amd::Os::fileSeparator();
|
||||
}
|
||||
}
|
||||
size_t pos = headerIncludeName.rfind(amd::Os::fileSeparator());
|
||||
if (pos != std::string::npos) {
|
||||
headerPath += amd::Os::fileSeparator();
|
||||
headerPath += headerIncludeName.substr(0, pos);
|
||||
headerIncludeName = headerIncludeName.substr(pos+1);
|
||||
}
|
||||
if (!amd::Os::pathExists(headerPath)) {
|
||||
bool ret = amd::Os::createPath(headerPath);
|
||||
assert(ret && "failed creating path!");
|
||||
newDirs.push_back(headerPath);
|
||||
}
|
||||
std::string headerFullName
|
||||
= headerPath + amd::Os::fileSeparator() + headerIncludeName;
|
||||
headerFileNames[i] = headerFullName;
|
||||
f.open(headerFullName.c_str(), std::fstream::out);
|
||||
assert(!f.fail() && "failed creating header file!");
|
||||
f.write(headers[i]->c_str(), headers[i]->length());
|
||||
f.close();
|
||||
std::fstream f;
|
||||
std::vector<std::string> headerFileNames(headers.size());
|
||||
std::vector<std::string> newDirs;
|
||||
for (size_t i = 0; i < headers.size(); ++i) {
|
||||
std::string headerPath = tempFolder;
|
||||
std::string headerIncludeName(headerIncludeNames[i]);
|
||||
// replace / in path with current os's file separator
|
||||
if (amd::Os::fileSeparator() != '/') {
|
||||
for (std::string::iterator it = headerIncludeName.begin(), end = headerIncludeName.end();
|
||||
it != end; ++it) {
|
||||
if (*it == '/') *it = amd::Os::fileSeparator();
|
||||
}
|
||||
}
|
||||
|
||||
acl_error err;
|
||||
const aclTargetInfo& targInfo = info();
|
||||
|
||||
aclBinaryOptions binOpts = {0};
|
||||
binOpts.struct_size = sizeof(binOpts);
|
||||
binOpts.elfclass = targInfo.arch_id == aclAMDIL64 ? ELFCLASS64 : ELFCLASS32;
|
||||
binOpts.bitness = ELFDATA2LSB;
|
||||
binOpts.alloc = &::malloc;
|
||||
binOpts.dealloc = &::free;
|
||||
|
||||
aclBinary* bin
|
||||
= aclBinaryInit(sizeof(aclBinary), &targInfo, &binOpts, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return false;
|
||||
size_t pos = headerIncludeName.rfind(amd::Os::fileSeparator());
|
||||
if (pos != std::string::npos) {
|
||||
headerPath += amd::Os::fileSeparator();
|
||||
headerPath += headerIncludeName.substr(0, pos);
|
||||
headerIncludeName = headerIncludeName.substr(pos + 1);
|
||||
}
|
||||
|
||||
if (ACL_SUCCESS != aclInsertSection(dev().compiler(), bin,
|
||||
sourceCode.c_str(), sourceCode.size(), aclSOURCE)) {
|
||||
LogWarning("aclInsertSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
if (!amd::Os::pathExists(headerPath)) {
|
||||
bool ret = amd::Os::createPath(headerPath);
|
||||
assert(ret && "failed creating path!");
|
||||
newDirs.push_back(headerPath);
|
||||
}
|
||||
std::string headerFullName = headerPath + amd::Os::fileSeparator() + headerIncludeName;
|
||||
headerFileNames[i] = headerFullName;
|
||||
f.open(headerFullName.c_str(), std::fstream::out);
|
||||
assert(!f.fail() && "failed creating header file!");
|
||||
f.write(headers[i]->c_str(), headers[i]->length());
|
||||
f.close();
|
||||
}
|
||||
|
||||
// temporary solution to synchronize buildNo between runtime and complib
|
||||
// until we move runtime inside complib
|
||||
((amd::option::Options*)bin->options)->setBuildNo(options->getBuildNo());
|
||||
acl_error err;
|
||||
const aclTargetInfo& targInfo = info();
|
||||
|
||||
std::stringstream opts;
|
||||
std::string token;
|
||||
opts << options->origOptionStr.c_str();
|
||||
aclBinaryOptions binOpts = {0};
|
||||
binOpts.struct_size = sizeof(binOpts);
|
||||
binOpts.elfclass = targInfo.arch_id == aclAMDIL64 ? ELFCLASS64 : ELFCLASS32;
|
||||
binOpts.bitness = ELFDATA2LSB;
|
||||
binOpts.alloc = &::malloc;
|
||||
binOpts.dealloc = &::free;
|
||||
|
||||
if (options->origOptionStr.find("-cl-std=CL") == std::string::npos) {
|
||||
switch(dev().settings().oclVersion_) {
|
||||
case OpenCL10: opts << " -cl-std=CL1.0"; break;
|
||||
case OpenCL11: opts << " -cl-std=CL1.1"; break;
|
||||
case OpenCL20: default:
|
||||
case OpenCL12: opts << " -cl-std=CL1.2"; break;
|
||||
}
|
||||
}
|
||||
aclBinary* bin = aclBinaryInit(sizeof(aclBinary), &targInfo, &binOpts, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Should we prefix everything with -Wf,?
|
||||
std::istringstream iss(options->clcOptions);
|
||||
while (getline(iss, token, ' ')) {
|
||||
if (!token.empty()) {
|
||||
// Check if this is a -D option
|
||||
if (token.compare("-D") == 0) {
|
||||
// It is, skip payload
|
||||
getline(iss, token, ' ');
|
||||
continue;
|
||||
}
|
||||
opts << " -Wf," << token;
|
||||
}
|
||||
}
|
||||
|
||||
if (!headers.empty()) {
|
||||
opts << " -I" << tempFolder;
|
||||
}
|
||||
|
||||
if (!dev().settings().imageSupport_) {
|
||||
opts << " -fno-image-support";
|
||||
}
|
||||
|
||||
if (dev().settings().reportFMAF_) {
|
||||
opts << " -mfast-fmaf";
|
||||
}
|
||||
|
||||
if (dev().settings().reportFMA_) {
|
||||
opts << " -mfast-fma";
|
||||
}
|
||||
|
||||
iss.clear();
|
||||
iss.str(device().info().extensions_);
|
||||
while (getline(iss, token, ' ')) {
|
||||
if (!token.empty()) {
|
||||
opts << " -D" << token << "=1";
|
||||
}
|
||||
}
|
||||
|
||||
std::string newOpt = opts.str();
|
||||
size_t pos = newOpt.find("-fno-bin-llvmir");
|
||||
while (pos != std::string::npos) {
|
||||
newOpt.erase(pos, 15);
|
||||
pos = newOpt.find("-fno-bin-llvmir");
|
||||
}
|
||||
|
||||
err = aclCompile(dev().compiler(), bin, newOpt.c_str(),
|
||||
ACL_TYPE_OPENCL, ACL_TYPE_LLVMIR_BINARY, NULL);
|
||||
|
||||
buildLog_ += aclGetCompilerLog(dev().compiler());
|
||||
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
const void* ir = aclExtractSection(dev().compiler(), bin,
|
||||
&len, aclLLVMIR, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclExtractSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
llvmBinary_.assign(reinterpret_cast<const char*>(ir), len);
|
||||
elfSectionType_ = amd::OclElf::LLVMIR;
|
||||
if (ACL_SUCCESS !=
|
||||
aclInsertSection(dev().compiler(), bin, sourceCode.c_str(), sourceCode.size(), aclSOURCE)) {
|
||||
LogWarning("aclInsertSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < headerFileNames.size(); ++i) {
|
||||
amd::Os::unlink(headerFileNames[i].c_str());
|
||||
// temporary solution to synchronize buildNo between runtime and complib
|
||||
// until we move runtime inside complib
|
||||
((amd::option::Options*)bin->options)->setBuildNo(options->getBuildNo());
|
||||
|
||||
std::stringstream opts;
|
||||
std::string token;
|
||||
opts << options->origOptionStr.c_str();
|
||||
|
||||
if (options->origOptionStr.find("-cl-std=CL") == std::string::npos) {
|
||||
switch (dev().settings().oclVersion_) {
|
||||
case OpenCL10:
|
||||
opts << " -cl-std=CL1.0";
|
||||
break;
|
||||
case OpenCL11:
|
||||
opts << " -cl-std=CL1.1";
|
||||
break;
|
||||
case OpenCL20:
|
||||
default:
|
||||
case OpenCL12:
|
||||
opts << " -cl-std=CL1.2";
|
||||
break;
|
||||
}
|
||||
for (size_t i = 0; i < newDirs.size(); ++i) {
|
||||
amd::Os::removePath(newDirs[i]);
|
||||
}
|
||||
|
||||
// FIXME: Should we prefix everything with -Wf,?
|
||||
std::istringstream iss(options->clcOptions);
|
||||
while (getline(iss, token, ' ')) {
|
||||
if (!token.empty()) {
|
||||
// Check if this is a -D option
|
||||
if (token.compare("-D") == 0) {
|
||||
// It is, skip payload
|
||||
getline(iss, token, ' ');
|
||||
continue;
|
||||
}
|
||||
opts << " -Wf," << token;
|
||||
}
|
||||
}
|
||||
|
||||
if (!headers.empty()) {
|
||||
opts << " -I" << tempFolder;
|
||||
}
|
||||
|
||||
if (!dev().settings().imageSupport_) {
|
||||
opts << " -fno-image-support";
|
||||
}
|
||||
|
||||
if (dev().settings().reportFMAF_) {
|
||||
opts << " -mfast-fmaf";
|
||||
}
|
||||
|
||||
if (dev().settings().reportFMA_) {
|
||||
opts << " -mfast-fma";
|
||||
}
|
||||
|
||||
iss.clear();
|
||||
iss.str(device().info().extensions_);
|
||||
while (getline(iss, token, ' ')) {
|
||||
if (!token.empty()) {
|
||||
opts << " -D" << token << "=1";
|
||||
}
|
||||
}
|
||||
|
||||
std::string newOpt = opts.str();
|
||||
size_t pos = newOpt.find("-fno-bin-llvmir");
|
||||
while (pos != std::string::npos) {
|
||||
newOpt.erase(pos, 15);
|
||||
pos = newOpt.find("-fno-bin-llvmir");
|
||||
}
|
||||
|
||||
err = aclCompile(dev().compiler(), bin, newOpt.c_str(), ACL_TYPE_OPENCL, ACL_TYPE_LLVMIR_BINARY,
|
||||
NULL);
|
||||
|
||||
buildLog_ += aclGetCompilerLog(dev().compiler());
|
||||
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
const void* ir = aclExtractSection(dev().compiler(), bin, &len, aclLLVMIR, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclExtractSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
llvmBinary_.assign(reinterpret_cast<const char*>(ir), len);
|
||||
elfSectionType_ = amd::OclElf::LLVMIR;
|
||||
aclBinaryFini(bin);
|
||||
|
||||
for (size_t i = 0; i < headerFileNames.size(); ++i) {
|
||||
amd::Os::unlink(headerFileNames[i].c_str());
|
||||
}
|
||||
for (size_t i = 0; i < newDirs.size(); ++i) {
|
||||
amd::Os::removePath(newDirs[i]);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
amd::Os::unlink(tempFileName);
|
||||
amd::Os::unlink(tempFileName);
|
||||
#endif
|
||||
|
||||
if (clBinary()->saveSOURCE()) {
|
||||
clBinary()->elfOut()->addSection(
|
||||
amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(
|
||||
amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(), false);
|
||||
// store the original compile options
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
}
|
||||
if (clBinary()->saveSOURCE()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(amd::OclElf::LLVMIR, llvmBinary_.data(), llvmBinary_.size(),
|
||||
false);
|
||||
// store the original compile options
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
NullProgram::compileBinaryToIL(amd::option::Options* options)
|
||||
{
|
||||
acl_error err;
|
||||
const aclTargetInfo& targInfo = info();
|
||||
int NullProgram::compileBinaryToIL(amd::option::Options* options) {
|
||||
acl_error err;
|
||||
const aclTargetInfo& targInfo = info();
|
||||
|
||||
aclBinaryOptions binOpts = {0};
|
||||
binOpts.struct_size = sizeof(binOpts);
|
||||
binOpts.elfclass = targInfo.arch_id == aclAMDIL64 ? ELFCLASS64 : ELFCLASS32;
|
||||
binOpts.bitness = ELFDATA2LSB;
|
||||
binOpts.alloc = &::malloc;
|
||||
binOpts.dealloc = &::free;
|
||||
aclBinaryOptions binOpts = {0};
|
||||
binOpts.struct_size = sizeof(binOpts);
|
||||
binOpts.elfclass = targInfo.arch_id == aclAMDIL64 ? ELFCLASS64 : ELFCLASS32;
|
||||
binOpts.bitness = ELFDATA2LSB;
|
||||
binOpts.alloc = &::malloc;
|
||||
binOpts.dealloc = &::free;
|
||||
|
||||
aclBinary* bin
|
||||
= aclBinaryInit(sizeof(aclBinary), &targInfo, &binOpts, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
aclSections_0_8 spirFlag;
|
||||
_acl_type_enum_0_8 aclTypeBinaryUsed;
|
||||
if (std::string::npos != options->clcOptions.find("--spirv")
|
||||
|| elfSectionType_ == amd::OclElf::SPIRV) {
|
||||
spirFlag = aclSPIRV;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIRV_BINARY;
|
||||
} else if (std::string::npos != options->clcOptions.find("--spir")
|
||||
|| elfSectionType_ == amd::OclElf::SPIR) {
|
||||
spirFlag = aclSPIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIR_BINARY;
|
||||
} else {
|
||||
spirFlag = aclLLVMIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_LLVMIR_BINARY;
|
||||
}
|
||||
aclBinary* bin = aclBinaryInit(sizeof(aclBinary), &targInfo, &binOpts, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
aclSections_0_8 spirFlag;
|
||||
_acl_type_enum_0_8 aclTypeBinaryUsed;
|
||||
if (std::string::npos != options->clcOptions.find("--spirv") ||
|
||||
elfSectionType_ == amd::OclElf::SPIRV) {
|
||||
spirFlag = aclSPIRV;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIRV_BINARY;
|
||||
} else if (std::string::npos != options->clcOptions.find("--spir") ||
|
||||
elfSectionType_ == amd::OclElf::SPIR) {
|
||||
spirFlag = aclSPIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIR_BINARY;
|
||||
} else {
|
||||
spirFlag = aclLLVMIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_LLVMIR_BINARY;
|
||||
}
|
||||
|
||||
if (ACL_SUCCESS != aclInsertSection(dev().compiler(), bin,
|
||||
llvmBinary_.data(), llvmBinary_.size(), spirFlag)) {
|
||||
LogWarning("aclInsertSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
// pass kernel argument alignment info to compiler lib through option str
|
||||
std::string optionStr = options->origOptionStr;
|
||||
if (options->origOptionStr.find("kernel-arg-alignment")
|
||||
== std::string::npos) {
|
||||
char s[256];
|
||||
sprintf(s, " -Wb,-kernel-arg-alignment=%d",
|
||||
dev().info().memBaseAddrAlign_ / 8);
|
||||
optionStr += s;
|
||||
}
|
||||
|
||||
// temporary solution to synchronize buildNo between runtime and complib
|
||||
// until we move runtime inside complib
|
||||
((amd::option::Options*)bin->options)->setBuildNo(options->getBuildNo());
|
||||
|
||||
aclType type = ACL_TYPE_CG ;
|
||||
// If option bin-bif30 is set, generate BIF 3.0 binary
|
||||
if (options->oVariables->BinBIF30) {
|
||||
type = ACL_TYPE_ISA;
|
||||
}
|
||||
|
||||
err = aclCompile(dev().compiler(), bin, optionStr.c_str(),
|
||||
aclTypeBinaryUsed, type, NULL);
|
||||
buildLog_ += aclGetCompilerLog(dev().compiler());
|
||||
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
if (options->oVariables->BinBIF30) {
|
||||
if (!createBIFBinary(bin)) {
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
const void* amdil = aclExtractSection(dev().compiler(), bin,
|
||||
&len, aclCODEGEN, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclExtractSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
ilProgram_.assign(reinterpret_cast<const char*>(amdil), len);
|
||||
if (ACL_SUCCESS !=
|
||||
aclInsertSection(dev().compiler(), bin, llvmBinary_.data(), llvmBinary_.size(), spirFlag)) {
|
||||
LogWarning("aclInsertSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
// pass kernel argument alignment info to compiler lib through option str
|
||||
std::string optionStr = options->origOptionStr;
|
||||
if (options->origOptionStr.find("kernel-arg-alignment") == std::string::npos) {
|
||||
char s[256];
|
||||
sprintf(s, " -Wb,-kernel-arg-alignment=%d", dev().info().memBaseAddrAlign_ / 8);
|
||||
optionStr += s;
|
||||
}
|
||||
|
||||
// temporary solution to synchronize buildNo between runtime and complib
|
||||
// until we move runtime inside complib
|
||||
((amd::option::Options*)bin->options)->setBuildNo(options->getBuildNo());
|
||||
|
||||
aclType type = ACL_TYPE_CG;
|
||||
// If option bin-bif30 is set, generate BIF 3.0 binary
|
||||
if (options->oVariables->BinBIF30) {
|
||||
type = ACL_TYPE_ISA;
|
||||
}
|
||||
|
||||
err = aclCompile(dev().compiler(), bin, optionStr.c_str(), aclTypeBinaryUsed, type, NULL);
|
||||
buildLog_ += aclGetCompilerLog(dev().compiler());
|
||||
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
if (options->oVariables->BinBIF30) {
|
||||
if (!createBIFBinary(bin)) {
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
const void* amdil = aclExtractSection(dev().compiler(), bin, &len, aclCODEGEN, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclExtractSection failed");
|
||||
aclBinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
ilProgram_.assign(reinterpret_cast<const char*>(amdil), len);
|
||||
aclBinaryFini(bin);
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
HSAILProgram::compileImpl(
|
||||
const std::string& sourceCode,
|
||||
const std::vector<const std::string*>& headers,
|
||||
const char** headerIncludeNames,
|
||||
amd::option::Options* options)
|
||||
{
|
||||
acl_error errorCode;
|
||||
aclTargetInfo target;
|
||||
bool HSAILProgram::compileImpl(const std::string& sourceCode,
|
||||
const std::vector<const std::string*>& headers,
|
||||
const char** headerIncludeNames, amd::option::Options* options) {
|
||||
acl_error errorCode;
|
||||
aclTargetInfo target;
|
||||
|
||||
std::string arch = "hsail";
|
||||
if (dev().settings().use64BitPtr_) {
|
||||
arch += "64";
|
||||
std::string arch = "hsail";
|
||||
if (dev().settings().use64BitPtr_) {
|
||||
arch += "64";
|
||||
}
|
||||
target = aclGetTargetInfo(arch.c_str(), dev().hwInfo()->targetName_, &errorCode);
|
||||
|
||||
// end if asic info is ready
|
||||
// We dump the source code for each program (param: headers)
|
||||
// into their filenames (headerIncludeNames) into the TEMP
|
||||
// folder specific to the OS and add the include path while
|
||||
// compiling
|
||||
|
||||
// Find the temp folder for the OS
|
||||
std::string tempFolder = amd::Os::getTempPath();
|
||||
std::string tempFileName = amd::Os::getTempFileName();
|
||||
|
||||
// Iterate through each source code and dump it into tmp
|
||||
std::fstream f;
|
||||
std::vector<std::string> headerFileNames(headers.size());
|
||||
std::vector<std::string> newDirs;
|
||||
for (size_t i = 0; i < headers.size(); ++i) {
|
||||
std::string headerPath = tempFolder;
|
||||
std::string headerIncludeName(headerIncludeNames[i]);
|
||||
// replace / in path with current os's file separator
|
||||
if (amd::Os::fileSeparator() != '/') {
|
||||
for (std::string::iterator it = headerIncludeName.begin(), end = headerIncludeName.end();
|
||||
it != end; ++it) {
|
||||
if (*it == '/') *it = amd::Os::fileSeparator();
|
||||
}
|
||||
}
|
||||
target = aclGetTargetInfo(arch.c_str(),
|
||||
dev().hwInfo()->targetName_, &errorCode);
|
||||
|
||||
// end if asic info is ready
|
||||
// We dump the source code for each program (param: headers)
|
||||
// into their filenames (headerIncludeNames) into the TEMP
|
||||
// folder specific to the OS and add the include path while
|
||||
// compiling
|
||||
|
||||
// Find the temp folder for the OS
|
||||
std::string tempFolder = amd::Os::getTempPath();
|
||||
std::string tempFileName = amd::Os::getTempFileName();
|
||||
|
||||
// Iterate through each source code and dump it into tmp
|
||||
std::fstream f;
|
||||
std::vector<std::string> headerFileNames(headers.size());
|
||||
std::vector<std::string> newDirs;
|
||||
for (size_t i = 0; i < headers.size(); ++i) {
|
||||
std::string headerPath = tempFolder;
|
||||
std::string headerIncludeName(headerIncludeNames[i]);
|
||||
// replace / in path with current os's file separator
|
||||
if (amd::Os::fileSeparator() != '/') {
|
||||
for (std::string::iterator it = headerIncludeName.begin(),
|
||||
end = headerIncludeName.end(); it != end; ++it) {
|
||||
if (*it == '/') *it = amd::Os::fileSeparator();
|
||||
}
|
||||
}
|
||||
size_t pos = headerIncludeName.rfind(amd::Os::fileSeparator());
|
||||
if (pos != std::string::npos) {
|
||||
headerPath += amd::Os::fileSeparator();
|
||||
headerPath += headerIncludeName.substr(0, pos);
|
||||
headerIncludeName = headerIncludeName.substr(pos+1);
|
||||
}
|
||||
if (!amd::Os::pathExists(headerPath)) {
|
||||
bool ret = amd::Os::createPath(headerPath);
|
||||
assert(ret && "failed creating path!");
|
||||
newDirs.push_back(headerPath);
|
||||
}
|
||||
std::string headerFullName =
|
||||
headerPath + amd::Os::fileSeparator() + headerIncludeName;
|
||||
headerFileNames[i] = headerFullName;
|
||||
f.open(headerFullName.c_str(), std::fstream::out);
|
||||
// Should we allow asserts
|
||||
assert(!f.fail() && "failed creating header file!");
|
||||
f.write(headers[i]->c_str(), headers[i]->length());
|
||||
f.close();
|
||||
size_t pos = headerIncludeName.rfind(amd::Os::fileSeparator());
|
||||
if (pos != std::string::npos) {
|
||||
headerPath += amd::Os::fileSeparator();
|
||||
headerPath += headerIncludeName.substr(0, pos);
|
||||
headerIncludeName = headerIncludeName.substr(pos + 1);
|
||||
}
|
||||
|
||||
// Create Binary
|
||||
binaryElf_ = aclBinaryInit(sizeof(aclBinary),
|
||||
&target, &binOpts_, &errorCode);
|
||||
if (errorCode != ACL_SUCCESS) {
|
||||
buildLog_ += "Error: aclBinary init failure\n";
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return false;
|
||||
if (!amd::Os::pathExists(headerPath)) {
|
||||
bool ret = amd::Os::createPath(headerPath);
|
||||
assert(ret && "failed creating path!");
|
||||
newDirs.push_back(headerPath);
|
||||
}
|
||||
std::string headerFullName = headerPath + amd::Os::fileSeparator() + headerIncludeName;
|
||||
headerFileNames[i] = headerFullName;
|
||||
f.open(headerFullName.c_str(), std::fstream::out);
|
||||
// Should we allow asserts
|
||||
assert(!f.fail() && "failed creating header file!");
|
||||
f.write(headers[i]->c_str(), headers[i]->length());
|
||||
f.close();
|
||||
}
|
||||
|
||||
// Insert opencl into binary
|
||||
errorCode = aclInsertSection(dev().hsaCompiler(), binaryElf_,
|
||||
sourceCode.c_str(), strlen(sourceCode.c_str()), aclSOURCE);
|
||||
if (errorCode != ACL_SUCCESS) {
|
||||
buildLog_ += "Error: Inserting openCl Source to binary\n";
|
||||
}
|
||||
// Create Binary
|
||||
binaryElf_ = aclBinaryInit(sizeof(aclBinary), &target, &binOpts_, &errorCode);
|
||||
if (errorCode != ACL_SUCCESS) {
|
||||
buildLog_ += "Error: aclBinary init failure\n";
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the options for the compiler
|
||||
// Set the include path for the temp folder that contains the includes
|
||||
if (!headers.empty()) {
|
||||
compileOptions_.append(" -I");
|
||||
compileOptions_.append(tempFolder);
|
||||
}
|
||||
// Insert opencl into binary
|
||||
errorCode = aclInsertSection(dev().hsaCompiler(), binaryElf_, sourceCode.c_str(),
|
||||
strlen(sourceCode.c_str()), aclSOURCE);
|
||||
if (errorCode != ACL_SUCCESS) {
|
||||
buildLog_ += "Error: Inserting openCl Source to binary\n";
|
||||
}
|
||||
|
||||
//Add only for CL2.0 and above
|
||||
if (options->oVariables->CLStd[2] >= '2') {
|
||||
std::stringstream opts;
|
||||
opts << " -D" << "CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE="
|
||||
<< device().info().maxGlobalVariableSize_;
|
||||
compileOptions_.append(opts.str());
|
||||
}
|
||||
// Set the options for the compiler
|
||||
// Set the include path for the temp folder that contains the includes
|
||||
if (!headers.empty()) {
|
||||
compileOptions_.append(" -I");
|
||||
compileOptions_.append(tempFolder);
|
||||
}
|
||||
|
||||
// Add only for CL2.0 and above
|
||||
if (options->oVariables->CLStd[2] >= '2') {
|
||||
std::stringstream opts;
|
||||
opts << " -D"
|
||||
<< "CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE=" << device().info().maxGlobalVariableSize_;
|
||||
compileOptions_.append(opts.str());
|
||||
}
|
||||
|
||||
#if !defined(_LP64) && defined(ATI_OS_LINUX)
|
||||
if (options->origOptionStr.find("-cl-std=CL2.0") != std::string::npos && !dev().settings().force32BitOcl20_) {
|
||||
errorCode = ACL_UNSUPPORTED;
|
||||
LogWarning("aclCompile failed");
|
||||
return false;
|
||||
}
|
||||
if (options->origOptionStr.find("-cl-std=CL2.0") != std::string::npos &&
|
||||
!dev().settings().force32BitOcl20_) {
|
||||
errorCode = ACL_UNSUPPORTED;
|
||||
LogWarning("aclCompile failed");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compile source to IR
|
||||
compileOptions_.append(hsailOptions());
|
||||
errorCode = aclCompile(dev().hsaCompiler(), binaryElf_, compileOptions_.c_str(),
|
||||
ACL_TYPE_OPENCL, ACL_TYPE_LLVMIR_BINARY, NULL);
|
||||
buildLog_ += aclGetCompilerLog(dev().hsaCompiler());
|
||||
if (errorCode != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
buildLog_ += "Error: Compiling CL to IR\n";
|
||||
return false;
|
||||
}
|
||||
// Compile source to IR
|
||||
compileOptions_.append(hsailOptions());
|
||||
errorCode = aclCompile(dev().hsaCompiler(), binaryElf_, compileOptions_.c_str(), ACL_TYPE_OPENCL,
|
||||
ACL_TYPE_LLVMIR_BINARY, NULL);
|
||||
buildLog_ += aclGetCompilerLog(dev().hsaCompiler());
|
||||
if (errorCode != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
buildLog_ += "Error: Compiling CL to IR\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
|
||||
// Save the binary in the interface class
|
||||
saveBinaryAndSetType(TYPE_COMPILED);
|
||||
// Save the binary in the interface class
|
||||
saveBinaryAndSetType(TYPE_COMPILED);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -9,81 +9,74 @@
|
||||
|
||||
namespace gpu {
|
||||
|
||||
ConstBuffer::ConstBuffer(
|
||||
VirtualGPU& gpu,
|
||||
size_t size)
|
||||
: Memory(const_cast<gpu::Device&>(gpu.dev()), size * VectorSize)
|
||||
, gpu_(gpu)
|
||||
, size_(size * VectorSize)
|
||||
, wrtOffset_(0)
|
||||
, lastWrtSize_(0)
|
||||
, wrtAddress_(NULL)
|
||||
{
|
||||
ConstBuffer::ConstBuffer(VirtualGPU& gpu, size_t size)
|
||||
: Memory(const_cast<gpu::Device&>(gpu.dev()), size * VectorSize),
|
||||
gpu_(gpu),
|
||||
size_(size * VectorSize),
|
||||
wrtOffset_(0),
|
||||
lastWrtSize_(0),
|
||||
wrtAddress_(NULL) {}
|
||||
|
||||
ConstBuffer::~ConstBuffer() {
|
||||
if (wrtAddress_ != NULL) {
|
||||
unmap(&gpu_);
|
||||
}
|
||||
|
||||
amd::AlignedMemory::deallocate(sysMemCopy_);
|
||||
}
|
||||
|
||||
ConstBuffer::~ConstBuffer()
|
||||
{
|
||||
bool ConstBuffer::create() {
|
||||
// Create sysmem copy for the constant buffer
|
||||
sysMemCopy_ = reinterpret_cast<address>(amd::AlignedMemory::allocate(size_, 256));
|
||||
if (sysMemCopy_ == NULL) {
|
||||
LogPrintfError(
|
||||
"We couldn't allocate sysmem copy for constant buffer,\
|
||||
size(%d)!",
|
||||
size_);
|
||||
return false;
|
||||
}
|
||||
memset(sysMemCopy_, 0, size_);
|
||||
|
||||
if (!Memory::create(Resource::RemoteUSWC)) {
|
||||
LogPrintfError("We couldn't create HW constant buffer, size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constant buffer warm-up
|
||||
warmUpRenames(gpu_);
|
||||
|
||||
wrtAddress_ = map(&gpu_, Resource::Discard);
|
||||
if (wrtAddress_ == NULL) {
|
||||
LogPrintfError("We couldn't map HW constant buffer, size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConstBuffer::uploadDataToHw(size_t size) {
|
||||
static const size_t HwCbAlignment = 256;
|
||||
|
||||
// Align copy size on the vector's boundary
|
||||
size_t count = amd::alignUp(size, VectorSize);
|
||||
wrtOffset_ += lastWrtSize_;
|
||||
|
||||
// Check if CB has enough space for copy
|
||||
if ((wrtOffset_ + count) > size_) {
|
||||
if (wrtAddress_ != NULL) {
|
||||
unmap(&gpu_);
|
||||
unmap(&gpu_);
|
||||
}
|
||||
|
||||
amd::AlignedMemory::deallocate(sysMemCopy_);
|
||||
}
|
||||
|
||||
bool
|
||||
ConstBuffer::create()
|
||||
{
|
||||
// Create sysmem copy for the constant buffer
|
||||
sysMemCopy_ = reinterpret_cast<address>(amd::AlignedMemory::allocate(size_, 256));
|
||||
if (sysMemCopy_ == NULL) {
|
||||
LogPrintfError("We couldn't allocate sysmem copy for constant buffer,\
|
||||
size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
memset(sysMemCopy_, 0, size_);
|
||||
|
||||
if (!Memory::create(Resource::RemoteUSWC)) {
|
||||
LogPrintfError("We couldn't create HW constant buffer, size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constant buffer warm-up
|
||||
warmUpRenames(gpu_);
|
||||
|
||||
wrtAddress_ = map(&gpu_, Resource::Discard);
|
||||
if (wrtAddress_ == NULL) {
|
||||
LogPrintfError("We couldn't map HW constant buffer, size(%d)!", size_);
|
||||
return false;
|
||||
}
|
||||
wrtOffset_ = 0;
|
||||
lastWrtSize_ = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
// Update memory with new CB data
|
||||
memcpy((reinterpret_cast<char*>(wrtAddress_) + wrtOffset_), sysMemCopy_, count);
|
||||
|
||||
// Adjust the size by the HW CB buffer alignment
|
||||
lastWrtSize_ = amd::alignUp(size, HwCbAlignment);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ConstBuffer::uploadDataToHw(size_t size)
|
||||
{
|
||||
static const size_t HwCbAlignment = 256;
|
||||
|
||||
// Align copy size on the vector's boundary
|
||||
size_t count = amd::alignUp(size, VectorSize);
|
||||
wrtOffset_ += lastWrtSize_;
|
||||
|
||||
// Check if CB has enough space for copy
|
||||
if ((wrtOffset_ + count) > size_) {
|
||||
if (wrtAddress_ != NULL) {
|
||||
unmap(&gpu_);
|
||||
}
|
||||
wrtAddress_ = map(&gpu_, Resource::Discard);
|
||||
wrtOffset_ = 0;
|
||||
lastWrtSize_ = 0;
|
||||
}
|
||||
|
||||
// Update memory with new CB data
|
||||
memcpy((reinterpret_cast<char*>(wrtAddress_) + wrtOffset_), sysMemCopy_, count);
|
||||
|
||||
// Adjust the size by the HW CB buffer alignment
|
||||
lastWrtSize_ = amd::alignUp(size, HwCbAlignment);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -11,57 +11,54 @@
|
||||
namespace gpu {
|
||||
|
||||
//! Cconstant buffer
|
||||
class ConstBuffer : public Memory
|
||||
{
|
||||
public:
|
||||
//! Vector size of the constant buffer
|
||||
static const size_t VectorSize = 16;
|
||||
class ConstBuffer : public Memory {
|
||||
public:
|
||||
//! Vector size of the constant buffer
|
||||
static const size_t VectorSize = 16;
|
||||
|
||||
//! Constructor for the ConstBuffer class
|
||||
ConstBuffer(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
size_t size //!< size of the constant buffer in vectors
|
||||
);
|
||||
//! Constructor for the ConstBuffer class
|
||||
ConstBuffer(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
size_t size //!< size of the constant buffer in vectors
|
||||
);
|
||||
|
||||
//! Destructor for the ConstBuffer class
|
||||
~ConstBuffer();
|
||||
//! Destructor for the ConstBuffer class
|
||||
~ConstBuffer();
|
||||
|
||||
//! Creates the real HW constant buffer
|
||||
bool create();
|
||||
//! Creates the real HW constant buffer
|
||||
bool create();
|
||||
|
||||
/*! \brief Uploads current constant buffer data from sysMemCopy_ to HW
|
||||
*
|
||||
* \return True if the data upload was succesful
|
||||
*/
|
||||
bool uploadDataToHw(
|
||||
size_t size //!< real data size for upload
|
||||
);
|
||||
/*! \brief Uploads current constant buffer data from sysMemCopy_ to HW
|
||||
*
|
||||
* \return True if the data upload was succesful
|
||||
*/
|
||||
bool uploadDataToHw(size_t size //!< real data size for upload
|
||||
);
|
||||
|
||||
//! Returns a pointer to the system memory copy for CB
|
||||
address sysMemCopy() const { return sysMemCopy_; }
|
||||
//! Returns a pointer to the system memory copy for CB
|
||||
address sysMemCopy() const { return sysMemCopy_; }
|
||||
|
||||
//! Returns CB size
|
||||
size_t size() const { return size_; }
|
||||
//! Returns CB size
|
||||
size_t size() const { return size_; }
|
||||
|
||||
//! Returns current write offset for the constant buffer
|
||||
size_t wrtOffset() const { return wrtOffset_; }
|
||||
//! Returns current write offset for the constant buffer
|
||||
size_t wrtOffset() const { return wrtOffset_; }
|
||||
|
||||
//! Returns last write size for the constant buffer
|
||||
size_t lastWrtSize() const { return lastWrtSize_; }
|
||||
//! Returns last write size for the constant buffer
|
||||
size_t lastWrtSize() const { return lastWrtSize_; }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ConstBuffer(const ConstBuffer&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ConstBuffer(const ConstBuffer&);
|
||||
|
||||
//! Disable operator=
|
||||
ConstBuffer& operator=(const ConstBuffer&);
|
||||
//! Disable operator=
|
||||
ConstBuffer& operator=(const ConstBuffer&);
|
||||
|
||||
VirtualGPU& gpu_; //!< Virtual GPU object
|
||||
address sysMemCopy_; //!< System memory copy
|
||||
size_t size_; //!< Constant buffer size
|
||||
size_t wrtOffset_; //!< Current write offset
|
||||
size_t lastWrtSize_; //!< Last write size
|
||||
void* wrtAddress_; //!< Write address in CB
|
||||
VirtualGPU& gpu_; //!< Virtual GPU object
|
||||
address sysMemCopy_; //!< System memory copy
|
||||
size_t size_; //!< Constant buffer size
|
||||
size_t wrtOffset_; //!< Current write offset
|
||||
size_t lastWrtSize_; //!< Last write size
|
||||
void* wrtAddress_; //!< Write address in CB
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -10,79 +10,72 @@
|
||||
namespace gpu {
|
||||
|
||||
CalCounterReference::~CalCounterReference() {
|
||||
// The counter object is always associated with a particular queue,
|
||||
// so we have to lock just this queue
|
||||
amd::ScopedLock lock(gpu_.execution());
|
||||
// The counter object is always associated with a particular queue,
|
||||
// so we have to lock just this queue
|
||||
amd::ScopedLock lock(gpu_.execution());
|
||||
|
||||
if (0 != counter_) {
|
||||
gpu().cs()->destroyQuery(gslCounter());
|
||||
}
|
||||
if (0 != counter_) {
|
||||
gpu().cs()->destroyQuery(gslCounter());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CalCounterReference::growResultArray(uint index) {
|
||||
if (results_ != NULL) {
|
||||
delete [] results_;
|
||||
}
|
||||
results_ = new uint64_t [index + 1];
|
||||
if (results_ == NULL) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool CalCounterReference::growResultArray(uint index) {
|
||||
if (results_ != NULL) {
|
||||
delete[] results_;
|
||||
}
|
||||
results_ = new uint64_t[index + 1];
|
||||
if (results_ == NULL) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PerfCounter::~PerfCounter()
|
||||
{
|
||||
if (calRef_ == NULL) {
|
||||
return;
|
||||
}
|
||||
PerfCounter::~PerfCounter() {
|
||||
if (calRef_ == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Release the counter reference object
|
||||
calRef_->release();
|
||||
// Release the counter reference object
|
||||
calRef_->release();
|
||||
}
|
||||
|
||||
bool
|
||||
PerfCounter::create(
|
||||
CalCounterReference* calRef)
|
||||
{
|
||||
assert(&gpu() == &calRef->gpu());
|
||||
bool PerfCounter::create(CalCounterReference* calRef) {
|
||||
assert(&gpu() == &calRef->gpu());
|
||||
|
||||
calRef_ = calRef;
|
||||
counter_ = calRef->gslCounter();
|
||||
index_ = calRef->retain() - 2;
|
||||
calRef->growResultArray(index_);
|
||||
calRef_ = calRef;
|
||||
counter_ = calRef->gslCounter();
|
||||
index_ = calRef->retain() - 2;
|
||||
calRef->growResultArray(index_);
|
||||
|
||||
// Initialize the counter
|
||||
gslCounter()->getAsPerformanceQueryObject()->setCounterState(
|
||||
info()->blockIndex_, info()->counterIndex_, info()->eventIndex_);
|
||||
// Initialize the counter
|
||||
gslCounter()->getAsPerformanceQueryObject()->setCounterState(
|
||||
info()->blockIndex_, info()->counterIndex_, info()->eventIndex_);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
PerfCounter::getInfo(uint64_t infoType) const
|
||||
{
|
||||
switch (infoType) {
|
||||
uint64_t PerfCounter::getInfo(uint64_t infoType) const {
|
||||
switch (infoType) {
|
||||
case CL_PERFCOUNTER_GPU_BLOCK_INDEX: {
|
||||
// Return the GPU block index
|
||||
return info()->blockIndex_;
|
||||
// Return the GPU block index
|
||||
return info()->blockIndex_;
|
||||
}
|
||||
case CL_PERFCOUNTER_GPU_COUNTER_INDEX: {
|
||||
// Return the GPU counter index
|
||||
return info()->counterIndex_;
|
||||
// Return the GPU counter index
|
||||
return info()->counterIndex_;
|
||||
}
|
||||
case CL_PERFCOUNTER_GPU_EVENT_INDEX: {
|
||||
// Return the GPU event index
|
||||
return info()->eventIndex_;
|
||||
// Return the GPU event index
|
||||
return info()->eventIndex_;
|
||||
}
|
||||
case CL_PERFCOUNTER_DATA: {
|
||||
gslCounter()->GetResult(gpu().cs(), reinterpret_cast<uint64*>(calRef_->results()));
|
||||
return calRef_->results()[index_];
|
||||
gslCounter()->GetResult(gpu().cs(), reinterpret_cast<uint64*>(calRef_->results()));
|
||||
return calRef_->results()[index_];
|
||||
}
|
||||
default:
|
||||
LogError("Wrong PerfCounter::getInfo parameter");
|
||||
}
|
||||
return 0;
|
||||
LogError("Wrong PerfCounter::getInfo parameter");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -12,129 +12,112 @@ namespace gpu {
|
||||
|
||||
class VirtualGPU;
|
||||
|
||||
class CalCounterReference : public amd::ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
CalCounterReference(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
gslQueryObject gslCounter)
|
||||
: gpu_(gpu)
|
||||
, counter_(gslCounter)
|
||||
, results_(NULL) {}
|
||||
class CalCounterReference : public amd::ReferenceCountedObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
CalCounterReference(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
gslQueryObject gslCounter)
|
||||
: gpu_(gpu), counter_(gslCounter), results_(NULL) {}
|
||||
|
||||
//! Get CAL counter
|
||||
gslQueryObject gslCounter() const { return counter_; }
|
||||
//! Get CAL counter
|
||||
gslQueryObject gslCounter() const { return counter_; }
|
||||
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
//! Increases the results array for this CAL counter(container)
|
||||
bool growResultArray(
|
||||
uint maxIndex //!< the maximum HW counter index in the CAL counter
|
||||
);
|
||||
//! Increases the results array for this CAL counter(container)
|
||||
bool growResultArray(uint maxIndex //!< the maximum HW counter index in the CAL counter
|
||||
);
|
||||
|
||||
//! Returns the CAL counter results
|
||||
uint64_t* results() const { return results_; }
|
||||
//! Returns the CAL counter results
|
||||
uint64_t* results() const { return results_; }
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalCounterReference();
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalCounterReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalCounterReference(const CalCounterReference&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalCounterReference(const CalCounterReference&);
|
||||
|
||||
//! Disable operator=
|
||||
CalCounterReference& operator=(const CalCounterReference&);
|
||||
//! Disable operator=
|
||||
CalCounterReference& operator=(const CalCounterReference&);
|
||||
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
gslQueryObject counter_; //!< GSL object counter
|
||||
uint64_t* results_; //!< CAL counter results
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
gslQueryObject counter_; //!< GSL object counter
|
||||
uint64_t* results_; //!< CAL counter results
|
||||
};
|
||||
|
||||
//! Performance counter implementation on GPU
|
||||
class PerfCounter : public device::PerfCounter
|
||||
{
|
||||
public:
|
||||
//! The performance counter info
|
||||
struct Info : public amd::EmbeddedObject
|
||||
{
|
||||
uint blockIndex_; //!< Index of the block to configure
|
||||
uint counterIndex_; //!< Index of the hardware counter
|
||||
uint eventIndex_; //!< Event you wish to count with the counter
|
||||
};
|
||||
class PerfCounter : public device::PerfCounter {
|
||||
public:
|
||||
//! The performance counter info
|
||||
struct Info : public amd::EmbeddedObject {
|
||||
uint blockIndex_; //!< Index of the block to configure
|
||||
uint counterIndex_; //!< Index of the hardware counter
|
||||
uint eventIndex_; //!< Event you wish to count with the counter
|
||||
};
|
||||
|
||||
//! The PerfCounter flags
|
||||
enum Flags
|
||||
{
|
||||
BeginIssued = 0x00000001,
|
||||
EndIssued = 0x00000002,
|
||||
ResultReady = 0x00000004
|
||||
};
|
||||
//! The PerfCounter flags
|
||||
enum Flags { BeginIssued = 0x00000001, EndIssued = 0x00000002, ResultReady = 0x00000004 };
|
||||
|
||||
//! Constructor for the GPU PerfCounter object
|
||||
PerfCounter(
|
||||
const Device& device, //!< A GPU device object
|
||||
const VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
cl_uint blockIndex, //!< HW block index
|
||||
cl_uint counterIndex, //!< Counter index within the block
|
||||
cl_uint eventIndex) //!< Event index for profiling
|
||||
: gpuDevice_(device)
|
||||
, gpu_(gpu)
|
||||
, calRef_(NULL)
|
||||
, flags_(0)
|
||||
, counter_(0)
|
||||
, index_(0)
|
||||
{
|
||||
info_.blockIndex_ = blockIndex;
|
||||
info_.counterIndex_ = counterIndex;
|
||||
info_.eventIndex_ = eventIndex;
|
||||
}
|
||||
//! Constructor for the GPU PerfCounter object
|
||||
PerfCounter(const Device& device, //!< A GPU device object
|
||||
const VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
cl_uint blockIndex, //!< HW block index
|
||||
cl_uint counterIndex, //!< Counter index within the block
|
||||
cl_uint eventIndex) //!< Event index for profiling
|
||||
: gpuDevice_(device),
|
||||
gpu_(gpu),
|
||||
calRef_(NULL),
|
||||
flags_(0),
|
||||
counter_(0),
|
||||
index_(0) {
|
||||
info_.blockIndex_ = blockIndex;
|
||||
info_.counterIndex_ = counterIndex;
|
||||
info_.eventIndex_ = eventIndex;
|
||||
}
|
||||
|
||||
//! Destructor for the GPU PerfCounter object
|
||||
virtual ~PerfCounter();
|
||||
//! Destructor for the GPU PerfCounter object
|
||||
virtual ~PerfCounter();
|
||||
|
||||
//! Creates the current object
|
||||
bool create(
|
||||
CalCounterReference* calRef //!< Reference counter
|
||||
);
|
||||
//! Creates the current object
|
||||
bool create(CalCounterReference* calRef //!< Reference counter
|
||||
);
|
||||
|
||||
//! Returns the specific information about the counter
|
||||
uint64_t getInfo(
|
||||
uint64_t infoType //!< The type of returned information
|
||||
) const;
|
||||
//! Returns the specific information about the counter
|
||||
uint64_t getInfo(uint64_t infoType //!< The type of returned information
|
||||
) const;
|
||||
|
||||
//! Returns the GPU device, associated with the current object
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
//! Returns the GPU device, associated with the current object
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
//! Returns the CAL performance counter descriptor
|
||||
const Info* info() const { return &info_; }
|
||||
//! Returns the CAL performance counter descriptor
|
||||
const Info* info() const { return &info_; }
|
||||
|
||||
//! Returns the Info structure for performance counter
|
||||
gslQueryObject gslCounter() const { return counter_; }
|
||||
//! Returns the Info structure for performance counter
|
||||
gslQueryObject gslCounter() const { return counter_; }
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
PerfCounter(const PerfCounter&);
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
PerfCounter(const PerfCounter&);
|
||||
|
||||
//! Disable default operator=
|
||||
PerfCounter& operator=(const PerfCounter&);
|
||||
//! Disable default operator=
|
||||
PerfCounter& operator=(const PerfCounter&);
|
||||
|
||||
const Device& gpuDevice_; //!< The backend device
|
||||
const VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
const Device& gpuDevice_; //!< The backend device
|
||||
const VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
|
||||
CalCounterReference* calRef_; //!< Reference counter
|
||||
uint flags_; //!< The perfcounter object state
|
||||
Info info_; //!< The info structure for perfcounter
|
||||
gslQueryObject counter_; //!< GSL counter object
|
||||
uint index_; //!< Counter index in the CAL container
|
||||
CalCounterReference* calRef_; //!< Reference counter
|
||||
uint flags_; //!< The perfcounter object state
|
||||
Info info_; //!< The info structure for perfcounter
|
||||
gslQueryObject counter_; //!< GSL counter object
|
||||
uint index_; //!< Counter index in the CAL container
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUCOUNTERS_HPP_
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUCOUNTERS_HPP_
|
||||
@@ -34,82 +34,77 @@ namespace gpu {
|
||||
*
|
||||
* This structure contains the packet information for kernel dispatch
|
||||
*/
|
||||
struct PacketAmdInfo
|
||||
{
|
||||
uint32_t trapReservedVgprIndex_; //!< reserved VGPR index, -1 when they are not valid
|
||||
uint32_t scratchBufferWaveOffset_; //!< scratch buffer wave offset, -1 when no scratch buffer
|
||||
void* pointerToIsaBuffer_; //!< pointer to the buffer containing ISA
|
||||
size_t sizeOfIsaBuffer_; //!< size of the ISA buffer
|
||||
uint32_t numberOfVgprs_; //!< number of VGPRs used by the kernel
|
||||
uint32_t numberOfSgprs_; //!< number of SGPRs used by the kernel
|
||||
size_t sizeOfStaticGroupMemory_; //!< Static local memory used by the kernel
|
||||
struct PacketAmdInfo {
|
||||
uint32_t trapReservedVgprIndex_; //!< reserved VGPR index, -1 when they are not valid
|
||||
uint32_t scratchBufferWaveOffset_; //!< scratch buffer wave offset, -1 when no scratch buffer
|
||||
void* pointerToIsaBuffer_; //!< pointer to the buffer containing ISA
|
||||
size_t sizeOfIsaBuffer_; //!< size of the ISA buffer
|
||||
uint32_t numberOfVgprs_; //!< number of VGPRs used by the kernel
|
||||
uint32_t numberOfSgprs_; //!< number of SGPRs used by the kernel
|
||||
size_t sizeOfStaticGroupMemory_; //!< Static local memory used by the kernel
|
||||
};
|
||||
|
||||
/*! \brief Cache mask for invalidation
|
||||
*/
|
||||
struct HwDbgGpuCacheMask
|
||||
{
|
||||
HwDbgGpuCacheMask() :ui32All_(0) {}
|
||||
struct HwDbgGpuCacheMask {
|
||||
HwDbgGpuCacheMask() : ui32All_(0) {}
|
||||
|
||||
HwDbgGpuCacheMask(uint32_t mask) :ui32All_(mask) {}
|
||||
HwDbgGpuCacheMask(uint32_t mask) : ui32All_(mask) {}
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t sqICache_ : 1; //!< Instruction cache
|
||||
uint32_t sqKCache_ : 1; //!< Data cache
|
||||
uint32_t tcL1_ : 1; //!< tcL1 cache
|
||||
uint32_t tcL2_ : 1; //!< tcL2 cache
|
||||
uint32_t reserved_ : 28;
|
||||
};
|
||||
uint32_t ui32All_;
|
||||
union {
|
||||
struct {
|
||||
uint32_t sqICache_ : 1; //!< Instruction cache
|
||||
uint32_t sqKCache_ : 1; //!< Data cache
|
||||
uint32_t tcL1_ : 1; //!< tcL1 cache
|
||||
uint32_t tcL2_ : 1; //!< tcL2 cache
|
||||
uint32_t reserved_ : 28;
|
||||
};
|
||||
uint32_t ui32All_;
|
||||
};
|
||||
};
|
||||
|
||||
/*! \brief Address watch information
|
||||
*
|
||||
* Information about each watch point - address, mask, mode and event
|
||||
*/
|
||||
struct HwDbgAddressWatch
|
||||
{
|
||||
void* watchAddress_; //! The address of watch point
|
||||
uint64_t watchMask_; //! The mask for watch point (lower 24 bits)
|
||||
cl_dbg_address_watch_mode_amd watchMode_; //! The watch mode for this watch
|
||||
DebugEvent event_; //! Event of the watch point (not used for now)
|
||||
struct HwDbgAddressWatch {
|
||||
void* watchAddress_; //! The address of watch point
|
||||
uint64_t watchMask_; //! The mask for watch point (lower 24 bits)
|
||||
cl_dbg_address_watch_mode_amd watchMode_; //! The watch mode for this watch
|
||||
DebugEvent event_; //! Event of the watch point (not used for now)
|
||||
};
|
||||
|
||||
/*! \brief Runtime structure used to communicate debug information
|
||||
* between Ocl services and core for a kernel dispatch.
|
||||
*/
|
||||
struct DebugToolInfo
|
||||
{
|
||||
uint64_t scratchAddress_; //! Scratch memory address
|
||||
size_t scratchSize_; //! Scratch memory size
|
||||
uint64_t globalAddress_; //! Global memory address
|
||||
uint32_t cacheDisableMask_; //! Cache mask, indicating caches disabled
|
||||
uint32_t exceptionMask_; //! Exception mask
|
||||
uint32_t reservedCuNum_; //! Number of reserved CUs for display,
|
||||
//! which ranges from 0 to 7 in the current implementation.
|
||||
bool monitorMode_; //! Debug or profiler mode
|
||||
bool gpuSingleStepMode_; //! SQ debug mode
|
||||
amd::Memory* trapHandler_; //! Trap handler address
|
||||
amd::Memory* trapBuffer_; //! Trap buffer address
|
||||
bool sqPerfcounterEnable_; //! whether SQ perf counters are enabled
|
||||
aclBinary* aclBinary_; //! pointer of the kernel ACL binary
|
||||
amd::Event* event_; //! pointer of the kernel event in the enqueue command
|
||||
struct DebugToolInfo {
|
||||
uint64_t scratchAddress_; //! Scratch memory address
|
||||
size_t scratchSize_; //! Scratch memory size
|
||||
uint64_t globalAddress_; //! Global memory address
|
||||
uint32_t cacheDisableMask_; //! Cache mask, indicating caches disabled
|
||||
uint32_t exceptionMask_; //! Exception mask
|
||||
uint32_t reservedCuNum_; //! Number of reserved CUs for display,
|
||||
//! which ranges from 0 to 7 in the current implementation.
|
||||
bool monitorMode_; //! Debug or profiler mode
|
||||
bool gpuSingleStepMode_; //! SQ debug mode
|
||||
amd::Memory* trapHandler_; //! Trap handler address
|
||||
amd::Memory* trapBuffer_; //! Trap buffer address
|
||||
bool sqPerfcounterEnable_; //! whether SQ perf counters are enabled
|
||||
aclBinary* aclBinary_; //! pointer of the kernel ACL binary
|
||||
amd::Event* event_; //! pointer of the kernel event in the enqueue command
|
||||
};
|
||||
|
||||
/*! \brief Message used by the KFD wave control for CI
|
||||
*
|
||||
* Structure indicates the various information used by the wave control function.
|
||||
*/
|
||||
struct HwDebugWaveAddr
|
||||
{
|
||||
uint32_t VMID_ : 4; //! Virtual memory id
|
||||
uint32_t wave_ : 4; //! Wave id
|
||||
uint32_t SIMD_ : 2; //! SIMD id
|
||||
uint32_t CU_ : 4; //! Compute unit
|
||||
uint32_t SH_ : 1; //! Shader array
|
||||
uint32_t SE_ : 1; //! Shader engine
|
||||
struct HwDebugWaveAddr {
|
||||
uint32_t VMID_ : 4; //! Virtual memory id
|
||||
uint32_t wave_ : 4; //! Wave id
|
||||
uint32_t SIMD_ : 2; //! SIMD id
|
||||
uint32_t CU_ : 4; //! Compute unit
|
||||
uint32_t SH_ : 1; //! Shader array
|
||||
uint32_t SE_ : 1; //! Shader engine
|
||||
};
|
||||
|
||||
/*! \brief Kernel code information
|
||||
@@ -117,10 +112,9 @@ struct HwDebugWaveAddr
|
||||
* This structure contains the pointer of mapped kernel code for host access
|
||||
* and its size (in bytes)
|
||||
*/
|
||||
struct AqlCodeInfo
|
||||
{
|
||||
amd_kernel_code_t * aqlCode_; //! pointer of AQL code to allow host access
|
||||
uint32_t aqlCodeSize_; //! size of AQL code
|
||||
struct AqlCodeInfo {
|
||||
amd_kernel_code_t* aqlCode_; //! pointer of AQL code to allow host access
|
||||
uint32_t aqlCodeSize_; //! size of AQL code
|
||||
};
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -33,376 +33,313 @@ class Memory;
|
||||
*/
|
||||
|
||||
GpuDebugManager::GpuDebugManager(amd::Device* device)
|
||||
: HwDebugManager(device)
|
||||
, vGpu_(NULL)
|
||||
, debugMessages_(0)
|
||||
, addressWatch_(NULL)
|
||||
, addressWatchSize_(0)
|
||||
, oclEventHandle_(NULL)
|
||||
{
|
||||
// Initialize the exception info and the kernel execution mode
|
||||
excpPolicy_.exceptionMask = 0x0;
|
||||
excpPolicy_.waveAction = CL_DBG_WAVES_RESUME;
|
||||
excpPolicy_.hostAction = CL_DBG_HOST_IGNORE;
|
||||
excpPolicy_.waveMode = CL_DBG_WAVEMODE_BROADCAST;
|
||||
: HwDebugManager(device),
|
||||
vGpu_(NULL),
|
||||
debugMessages_(0),
|
||||
addressWatch_(NULL),
|
||||
addressWatchSize_(0),
|
||||
oclEventHandle_(NULL) {
|
||||
// Initialize the exception info and the kernel execution mode
|
||||
excpPolicy_.exceptionMask = 0x0;
|
||||
excpPolicy_.waveAction = CL_DBG_WAVES_RESUME;
|
||||
excpPolicy_.hostAction = CL_DBG_HOST_IGNORE;
|
||||
excpPolicy_.waveMode = CL_DBG_WAVEMODE_BROADCAST;
|
||||
|
||||
execMode_.ui32All = 0;
|
||||
execMode_.ui32All = 0;
|
||||
|
||||
rtTrapHandlerInfo_.trap_.trapHandler_ = NULL;
|
||||
rtTrapHandlerInfo_.trap_.trapBuffer_ = NULL;
|
||||
rtTrapHandlerInfo_.trap_.trapHandler_ = NULL;
|
||||
rtTrapHandlerInfo_.trap_.trapBuffer_ = NULL;
|
||||
|
||||
aqlPacket_ = (hsa_kernel_dispatch_packet_t *) NULL;
|
||||
aqlPacket_ = (hsa_kernel_dispatch_packet_t*)NULL;
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
GpuDebugManager::~GpuDebugManager()
|
||||
{
|
||||
if (NULL != addressWatch_) {
|
||||
delete [] addressWatch_;
|
||||
}
|
||||
GpuDebugManager::~GpuDebugManager() {
|
||||
if (NULL != addressWatch_) {
|
||||
delete[] addressWatch_;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::executePreDispatchCallBack(void* aqlPacket,
|
||||
void* toolInfo)
|
||||
{
|
||||
DebugToolInfo* info = reinterpret_cast<DebugToolInfo*>(toolInfo);
|
||||
void GpuDebugManager::executePreDispatchCallBack(void* aqlPacket, void* toolInfo) {
|
||||
DebugToolInfo* info = reinterpret_cast<DebugToolInfo*>(toolInfo);
|
||||
|
||||
aqlPacket_ = reinterpret_cast<hsa_kernel_dispatch_packet_t*>(aqlPacket);
|
||||
aqlPacket_ = reinterpret_cast<hsa_kernel_dispatch_packet_t*>(aqlPacket);
|
||||
|
||||
// Only if the pre-dispatch callback is set, will we update cache
|
||||
// flush configuration and build the memory descriptor.
|
||||
if (NULL != preDispatchCallBackFunc_) {
|
||||
// Build the scratch memory descriptor
|
||||
device()->gslCtx()->BuildScratchBufferResource(debugInfo_.scratchMemoryDescriptor_,
|
||||
info->scratchAddress_,
|
||||
info->scratchSize_);
|
||||
// Only if the pre-dispatch callback is set, will we update cache
|
||||
// flush configuration and build the memory descriptor.
|
||||
if (NULL != preDispatchCallBackFunc_) {
|
||||
// Build the scratch memory descriptor
|
||||
device()->gslCtx()->BuildScratchBufferResource(debugInfo_.scratchMemoryDescriptor_,
|
||||
info->scratchAddress_, info->scratchSize_);
|
||||
|
||||
// Build the global memory descriptor
|
||||
device()->gslCtx()->BuildHeapBufferResource(debugInfo_.globalMemoryDescriptor_,
|
||||
info->globalAddress_);
|
||||
// Build the global memory descriptor
|
||||
device()->gslCtx()->BuildHeapBufferResource(debugInfo_.globalMemoryDescriptor_,
|
||||
info->globalAddress_);
|
||||
|
||||
// // for invalidate cache (BuildEndOfKernelNotifyCommands)
|
||||
// aqlPacket->release_fence_scope = 2;
|
||||
// // for invalidate cache (BuildEndOfKernelNotifyCommands)
|
||||
// aqlPacket->release_fence_scope = 2;
|
||||
|
||||
aclBinary_ = reinterpret_cast<void*>(info->aclBinary_);
|
||||
oclEventHandle_ = reinterpret_cast<void*>(as_cl(info->event_));
|
||||
aclBinary_ = reinterpret_cast<void*>(info->aclBinary_);
|
||||
oclEventHandle_ = reinterpret_cast<void*>(as_cl(info->event_));
|
||||
|
||||
cl_device_id clDeviceId = as_cl(device_);
|
||||
preDispatchCallBackFunc_(clDeviceId,
|
||||
oclEventHandle_,
|
||||
aqlPacket_,
|
||||
aclBinary_,
|
||||
preDispatchCallBackArgs_);
|
||||
}
|
||||
cl_device_id clDeviceId = as_cl(device_);
|
||||
preDispatchCallBackFunc_(clDeviceId, oclEventHandle_, aqlPacket_, aclBinary_,
|
||||
preDispatchCallBackArgs_);
|
||||
}
|
||||
|
||||
// setup the trap handler information only if the debugger has been registered
|
||||
if (isRegistered()) {
|
||||
// Copy the various info set by the debugger/profiler to the tool info structure
|
||||
setupTrapInformation(info);
|
||||
}
|
||||
// setup the trap handler information only if the debugger has been registered
|
||||
if (isRegistered()) {
|
||||
// Copy the various info set by the debugger/profiler to the tool info structure
|
||||
setupTrapInformation(info);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::executePostDispatchCallBack()
|
||||
{
|
||||
if (NULL != postDispatchCallBackFunc_) {
|
||||
cl_device_id clDeviceId = as_cl(device_);
|
||||
postDispatchCallBackFunc_(clDeviceId,
|
||||
aqlPacket_->completion_signal.handle,
|
||||
postDispatchCallBackArgs_);
|
||||
}
|
||||
void GpuDebugManager::executePostDispatchCallBack() {
|
||||
if (NULL != postDispatchCallBackFunc_) {
|
||||
cl_device_id clDeviceId = as_cl(device_);
|
||||
postDispatchCallBackFunc_(clDeviceId, aqlPacket_->completion_signal.handle,
|
||||
postDispatchCallBackArgs_);
|
||||
}
|
||||
}
|
||||
|
||||
//! Map the kernel code for host access
|
||||
void
|
||||
GpuDebugManager::mapKernelCode(void* aqlCodeInfo) const
|
||||
{
|
||||
AqlCodeInfo* codeInfo = reinterpret_cast<AqlCodeInfo*>(aqlCodeInfo);
|
||||
void GpuDebugManager::mapKernelCode(void* aqlCodeInfo) const {
|
||||
AqlCodeInfo* codeInfo = reinterpret_cast<AqlCodeInfo*>(aqlCodeInfo);
|
||||
|
||||
codeInfo->aqlCode_ = reinterpret_cast<amd_kernel_code_t*>(aqlCodeAddr_);
|
||||
codeInfo->aqlCodeSize_ = aqlCodeSize_;
|
||||
codeInfo->aqlCode_ = reinterpret_cast<amd_kernel_code_t*>(aqlCodeAddr_);
|
||||
codeInfo->aqlCodeSize_ = aqlCodeSize_;
|
||||
}
|
||||
|
||||
cl_int
|
||||
GpuDebugManager::registerDebugger(amd::Context* context, uintptr_t messageStorage)
|
||||
cl_int GpuDebugManager::registerDebugger(amd::Context* context, uintptr_t messageStorage) {
|
||||
if (!device()->settings().enableHwDebug_) {
|
||||
LogError("debugmanager: Register debugger error - HW DEBUG is not enable");
|
||||
return CL_DEBUGGER_REGISTER_FAILURE_AMD;
|
||||
}
|
||||
|
||||
// first time register - set the message storage, flush queue and enable hw debug
|
||||
if (!isRegistered()) {
|
||||
debugMessages_ = messageStorage;
|
||||
if (!device()->gslCtx()->registerHwDebugger(debugMessages_)) {
|
||||
LogError("debugmanager: Register debugger failed");
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
isRegistered_ = true;
|
||||
|
||||
if (CL_SUCCESS != createRuntimeTrapHandler()) {
|
||||
LogError("debugmanager: Create runtime trap handler failed");
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
context_ = context;
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
void GpuDebugManager::unregisterDebugger() {
|
||||
if (isRegistered()) {
|
||||
// reset the debugger registration flag
|
||||
isRegistered_ = false;
|
||||
context_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GpuDebugManager::flushCache(uint32_t mask) {
|
||||
HwDbgGpuCacheMask cacheMask(mask);
|
||||
device()->xferQueue()->flushCuCaches(cacheMask);
|
||||
}
|
||||
|
||||
|
||||
void GpuDebugManager::setupTrapInformation(DebugToolInfo* toolInfo) {
|
||||
toolInfo->scratchAddress_ = 0;
|
||||
toolInfo->scratchSize_ = 0;
|
||||
toolInfo->globalAddress_ = 0;
|
||||
toolInfo->sqPerfcounterEnable_ = false;
|
||||
|
||||
// Set up trap related info in the kernel info structure to be
|
||||
// used in the kernel dispatch.
|
||||
toolInfo->exceptionMask_ = excpPolicy_.exceptionMask;
|
||||
toolInfo->gpuSingleStepMode_ = execMode_.gpuSingleStepMode;
|
||||
toolInfo->monitorMode_ = execMode_.monitorMode;
|
||||
|
||||
// The order of these three bits is determined by the definition
|
||||
// of the register COMPUTE_DISPATCH_INITIATOR
|
||||
toolInfo->cacheDisableMask_ = ((execMode_.disableL1Scalar << 2) |
|
||||
(execMode_.disableL2Cache << 1) | (execMode_.disableL1Vector));
|
||||
|
||||
toolInfo->reservedCuNum_ = execMode_.reservedCuNum;
|
||||
|
||||
toolInfo->trapHandler_ = rtTrapInfo_[kDebugTrapHandlerLocation];
|
||||
toolInfo->trapBuffer_ = rtTrapInfo_[kDebugTrapBufferLocation];
|
||||
}
|
||||
|
||||
void GpuDebugManager::getPacketAmdInfo(const void* aqlCodeInfo, void* packetInfo) const
|
||||
|
||||
{
|
||||
if (!device()->settings().enableHwDebug_) {
|
||||
LogError("debugmanager: Register debugger error - HW DEBUG is not enable");
|
||||
return CL_DEBUGGER_REGISTER_FAILURE_AMD;
|
||||
const AqlCodeInfo* codeInfo = reinterpret_cast<const AqlCodeInfo*>(aqlCodeInfo);
|
||||
|
||||
const amd_kernel_code_t* hostAqlCode = codeInfo->aqlCode_;
|
||||
|
||||
PacketAmdInfo* packet = reinterpret_cast<PacketAmdInfo*>(packetInfo);
|
||||
|
||||
const amd_kernel_code_t* akc = hostAqlCode;
|
||||
|
||||
packet->numberOfSgprs_ = akc->wavefront_sgpr_count;
|
||||
packet->numberOfVgprs_ = akc->workitem_vgpr_count;
|
||||
|
||||
// use mapped kernel_object_address for host accessing of ISA buffer
|
||||
packet->pointerToIsaBuffer_ = (char*)(hostAqlCode) + akc->kernel_code_entry_byte_offset;
|
||||
|
||||
packet->scratchBufferWaveOffset_ = akc->debug_wavefront_private_segment_offset_sgpr;
|
||||
|
||||
packet->sizeOfIsaBuffer_ = codeInfo->aqlCodeSize_;
|
||||
|
||||
packet->sizeOfStaticGroupMemory_ = akc->workgroup_group_segment_byte_size;
|
||||
|
||||
// The trap_reserved_vgpr_index will be 4 less the original
|
||||
// This value must be used only by the debugger
|
||||
packet->trapReservedVgprIndex_ = akc->workitem_vgpr_count - NumberReserveVgprs;
|
||||
}
|
||||
|
||||
DebugEvent GpuDebugManager::createDebugEvent(const bool autoReset) {
|
||||
// create the event object
|
||||
osEventHandle shaderEvent = osEventCreate(!autoReset);
|
||||
|
||||
// event object has been created, set the initial state
|
||||
if (shaderEvent != 0) {
|
||||
osEventReset(shaderEvent); // initial state is non-signaled
|
||||
|
||||
if (device()->gslCtx()->exceptionNotification(shaderEvent)) {
|
||||
return shaderEvent;
|
||||
}
|
||||
}
|
||||
|
||||
// first time register - set the message storage, flush queue and enable hw debug
|
||||
if (!isRegistered()) {
|
||||
debugMessages_ = messageStorage;
|
||||
if (!device()->gslCtx()->registerHwDebugger(debugMessages_)) {
|
||||
LogError("debugmanager: Register debugger failed");
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
isRegistered_ = true;
|
||||
|
||||
if (CL_SUCCESS != createRuntimeTrapHandler()) {
|
||||
LogError("debugmanager: Create runtime trap handler failed");
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
context_ = context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cl_int GpuDebugManager::waitDebugEvent(DebugEvent pEvent, uint32_t timeOut) const {
|
||||
if (osEventTimedWait(pEvent, timeOut)) {
|
||||
return CL_SUCCESS;
|
||||
} else {
|
||||
return CL_EVENT_TIMEOUT_AMD;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::unregisterDebugger()
|
||||
{
|
||||
if (isRegistered()) {
|
||||
// reset the debugger registration flag
|
||||
isRegistered_ = false;
|
||||
context_ = NULL;
|
||||
}
|
||||
void GpuDebugManager::destroyDebugEvent(DebugEvent* pEvent) {
|
||||
osEventDestroy(*pEvent);
|
||||
*pEvent = 0;
|
||||
|
||||
device()->gslCtx()->exceptionNotification(0);
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::flushCache(uint32_t mask)
|
||||
{
|
||||
HwDbgGpuCacheMask cacheMask(mask);
|
||||
device()->xferQueue()->flushCuCaches(cacheMask);
|
||||
void GpuDebugManager::wavefrontControl(uint32_t waveAction, uint32_t waveMode, uint32_t trapId,
|
||||
void* waveAddr) const {
|
||||
device()->gslCtx()->executeSqCommand(waveAction, waveMode, trapId, waveAddr);
|
||||
}
|
||||
|
||||
void GpuDebugManager::setAddressWatch(uint32_t numWatchPoints, void** watchAddress,
|
||||
uint64_t* watchMask, uint64_t* watchMode, DebugEvent* event) {
|
||||
size_t requiredSize = numWatchPoints * sizeof(HwDbgAddressWatch);
|
||||
|
||||
void
|
||||
GpuDebugManager::setupTrapInformation(DebugToolInfo* toolInfo)
|
||||
{
|
||||
toolInfo->scratchAddress_ = 0;
|
||||
toolInfo->scratchSize_ = 0;
|
||||
toolInfo->globalAddress_ = 0;
|
||||
toolInfo->sqPerfcounterEnable_ = false;
|
||||
// previously allocated size is not big enough, allocate new memory
|
||||
if (addressWatchSize_ < requiredSize) {
|
||||
if (NULL != addressWatch_) { // free the smaller address watch storage
|
||||
delete[] addressWatch_;
|
||||
}
|
||||
addressWatch_ = new HwDbgAddressWatch[numWatchPoints];
|
||||
addressWatchSize_ = requiredSize;
|
||||
}
|
||||
|
||||
// Set up trap related info in the kernel info structure to be
|
||||
// used in the kernel dispatch.
|
||||
toolInfo->exceptionMask_ = excpPolicy_.exceptionMask;
|
||||
toolInfo->gpuSingleStepMode_ = execMode_.gpuSingleStepMode;
|
||||
toolInfo->monitorMode_ = execMode_.monitorMode;
|
||||
// fill in the address watch structure
|
||||
memset(addressWatch_, 0, addressWatchSize_);
|
||||
|
||||
// The order of these three bits is determined by the definition
|
||||
// of the register COMPUTE_DISPATCH_INITIATOR
|
||||
toolInfo->cacheDisableMask_ = ((execMode_.disableL1Scalar << 2)
|
||||
| (execMode_.disableL2Cache << 1)
|
||||
| (execMode_.disableL1Vector));
|
||||
for (uint32_t i = 0; i < numWatchPoints; i++) {
|
||||
amd::Memory* watchMem = as_amd(reinterpret_cast<cl_mem>(watchAddress[i]));
|
||||
Memory* watchMemAddress = device()->getGpuMemory(watchMem);
|
||||
|
||||
toolInfo->reservedCuNum_ = execMode_.reservedCuNum;
|
||||
addressWatch_[i].watchAddress_ = reinterpret_cast<void*>(watchMemAddress->vmAddress());
|
||||
addressWatch_[i].watchMask_ = watchMask[i];
|
||||
addressWatch_[i].watchMode_ = (cl_dbg_address_watch_mode_amd)watchMode[i];
|
||||
addressWatch_[i].event_ = (0 != event) ? event[i] : 0;
|
||||
}
|
||||
|
||||
toolInfo->trapHandler_ = rtTrapInfo_[kDebugTrapHandlerLocation];
|
||||
toolInfo->trapBuffer_ = rtTrapInfo_[kDebugTrapBufferLocation];
|
||||
// setup the watch addresses
|
||||
device()->gslCtx()->setAddressWatch(numWatchPoints, (void*)addressWatch_);
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::getPacketAmdInfo(
|
||||
const void* aqlCodeInfo,
|
||||
void* packetInfo) const
|
||||
void GpuDebugManager::setGlobalMemory(amd::Memory* memObj, uint32_t offset, void* srcPtr,
|
||||
uint32_t size) {
|
||||
gpu::Memory* globalMem = device()->getGpuMemory(memObj);
|
||||
|
||||
{
|
||||
const AqlCodeInfo* codeInfo =
|
||||
reinterpret_cast<const AqlCodeInfo*>(aqlCodeInfo);
|
||||
address mappedMem = static_cast<address>(globalMem->map(NULL, 0));
|
||||
assert(mappedMem != 0);
|
||||
|
||||
const amd_kernel_code_t* hostAqlCode = codeInfo->aqlCode_;
|
||||
void* dest_ptr = reinterpret_cast<void*>(mappedMem + offset);
|
||||
memcpy(dest_ptr, srcPtr, size);
|
||||
|
||||
PacketAmdInfo* packet =
|
||||
reinterpret_cast<PacketAmdInfo*>(packetInfo);
|
||||
|
||||
const amd_kernel_code_t* akc = hostAqlCode;
|
||||
|
||||
packet->numberOfSgprs_ = akc->wavefront_sgpr_count;
|
||||
packet->numberOfVgprs_ = akc->workitem_vgpr_count;
|
||||
|
||||
// use mapped kernel_object_address for host accessing of ISA buffer
|
||||
packet->pointerToIsaBuffer_ = (char*) (hostAqlCode) +
|
||||
akc->kernel_code_entry_byte_offset;
|
||||
|
||||
packet->scratchBufferWaveOffset_ =
|
||||
akc->debug_wavefront_private_segment_offset_sgpr;
|
||||
|
||||
packet->sizeOfIsaBuffer_ = codeInfo->aqlCodeSize_;
|
||||
|
||||
packet->sizeOfStaticGroupMemory_ = akc->workgroup_group_segment_byte_size;
|
||||
|
||||
// The trap_reserved_vgpr_index will be 4 less the original
|
||||
// This value must be used only by the debugger
|
||||
packet->trapReservedVgprIndex_ = akc->workitem_vgpr_count - NumberReserveVgprs;
|
||||
globalMem->unmap(NULL);
|
||||
}
|
||||
|
||||
DebugEvent
|
||||
GpuDebugManager::createDebugEvent(
|
||||
const bool autoReset)
|
||||
{
|
||||
// create the event object
|
||||
osEventHandle shaderEvent = osEventCreate(!autoReset);
|
||||
cl_int GpuDebugManager::createRuntimeTrapHandler() {
|
||||
size_t codeSize = 0;
|
||||
const uint32_t* rtTrapCode = NULL;
|
||||
|
||||
// event object has been created, set the initial state
|
||||
if (shaderEvent != 0) {
|
||||
if (device()->settings().viPlus_) {
|
||||
codeSize = sizeof(RuntimeTrapCodeVi);
|
||||
rtTrapCode = RuntimeTrapCodeVi;
|
||||
} else {
|
||||
codeSize = sizeof(RuntimeTrapCode);
|
||||
rtTrapCode = RuntimeTrapCode;
|
||||
}
|
||||
|
||||
osEventReset(shaderEvent); // initial state is non-signaled
|
||||
uint32_t numCodes = codeSize / sizeof(uint32_t);
|
||||
|
||||
if (device()->gslCtx()->exceptionNotification(shaderEvent)) {
|
||||
return shaderEvent;
|
||||
}
|
||||
}
|
||||
// Handle TMA corruption hw bug workaround -
|
||||
// The trap handler buffer has extra 256 bytes allocated, the TMA address
|
||||
// is stored in the first two DWORDs and the actual trap handler code
|
||||
// is stored starting at the location of 256 bytes (TbaStartOffset).
|
||||
//
|
||||
// allocate memory for the runtime trap handler (TBA) + TMA address
|
||||
uint32_t allocSize = codeSize + TbaStartOffset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Memory* rtTBA = new Memory(*device(), allocSize);
|
||||
runtimeTBA_ = rtTBA;
|
||||
|
||||
cl_int
|
||||
GpuDebugManager::waitDebugEvent(
|
||||
DebugEvent pEvent,
|
||||
uint32_t timeOut) const
|
||||
{
|
||||
if (osEventTimedWait(pEvent, timeOut)) {
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
return CL_EVENT_TIMEOUT_AMD;
|
||||
}
|
||||
}
|
||||
if ((rtTBA == NULL) || !rtTBA->create(Resource::RemoteUSWC)) {
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
address tbaAddress = reinterpret_cast<address>(rtTBA->map(NULL));
|
||||
|
||||
void
|
||||
GpuDebugManager::destroyDebugEvent(DebugEvent* pEvent)
|
||||
{
|
||||
osEventDestroy(*pEvent);
|
||||
*pEvent = 0;
|
||||
// allocate buffer for the runtime trap handler buffer (TMA)
|
||||
uint32_t tmaSize = 0x100;
|
||||
Memory* rtTMA = new Memory(*device(), tmaSize);
|
||||
runtimeTMA_ = rtTMA;
|
||||
|
||||
device()->gslCtx()->exceptionNotification(0);
|
||||
if ((rtTMA == NULL) || !rtTMA->create(Resource::RemoteUSWC)) {
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
}
|
||||
uint64_t rtTmaAddress = rtTMA->vmAddress();
|
||||
if ((rtTBA->vmAddress() & 0xFF) != 0 || (rtTmaAddress & 0xFF) != 0) {
|
||||
LogError("debugmanager: Trap handler/buffer is not 256-byte aligned");
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::wavefrontControl(
|
||||
uint32_t waveAction,
|
||||
uint32_t waveMode,
|
||||
uint32_t trapId,
|
||||
void* waveAddr) const
|
||||
{
|
||||
device()->gslCtx()->executeSqCommand(waveAction, waveMode, trapId, waveAddr);
|
||||
}
|
||||
// store the TMA address at the beginning of trap handler buffer
|
||||
uint64_t* tbaStorage = reinterpret_cast<uint64_t*>(tbaAddress);
|
||||
tbaStorage[0] = rtTmaAddress;
|
||||
|
||||
void
|
||||
GpuDebugManager::setAddressWatch(
|
||||
uint32_t numWatchPoints,
|
||||
void** watchAddress,
|
||||
uint64_t* watchMask,
|
||||
uint64_t* watchMode,
|
||||
DebugEvent* event)
|
||||
{
|
||||
size_t requiredSize = numWatchPoints * sizeof(HwDbgAddressWatch);
|
||||
// save the trap handler code
|
||||
uint32_t* trapHandlerPtr = (uint32_t*)(tbaAddress + TbaStartOffset);
|
||||
for (uint32_t i = 0; i < numCodes; i++) {
|
||||
trapHandlerPtr[i] = rtTrapCode[i];
|
||||
}
|
||||
|
||||
// previously allocated size is not big enough, allocate new memory
|
||||
if (addressWatchSize_ < requiredSize) {
|
||||
if (NULL != addressWatch_) { // free the smaller address watch storage
|
||||
delete [] addressWatch_;
|
||||
}
|
||||
addressWatch_ = new HwDbgAddressWatch[numWatchPoints];
|
||||
addressWatchSize_ = requiredSize;
|
||||
}
|
||||
rtTBA->unmap(NULL);
|
||||
|
||||
// fill in the address watch structure
|
||||
memset(addressWatch_, 0, addressWatchSize_);
|
||||
|
||||
for (uint32_t i = 0; i < numWatchPoints; i++)
|
||||
{
|
||||
amd::Memory* watchMem = as_amd(reinterpret_cast<cl_mem>(watchAddress[i]));
|
||||
Memory* watchMemAddress = device()->getGpuMemory(watchMem);
|
||||
|
||||
addressWatch_[i].watchAddress_ = reinterpret_cast<void*>(watchMemAddress->vmAddress());
|
||||
addressWatch_[i].watchMask_ = watchMask[i];
|
||||
addressWatch_[i].watchMode_ = (cl_dbg_address_watch_mode_amd) watchMode[i];
|
||||
addressWatch_[i].event_ = (0 != event) ? event[i] : 0;
|
||||
}
|
||||
|
||||
// setup the watch addresses
|
||||
device()->gslCtx()->setAddressWatch(numWatchPoints, (void*) addressWatch_);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
GpuDebugManager::setGlobalMemory(
|
||||
amd::Memory* memObj,
|
||||
uint32_t offset,
|
||||
void* srcPtr,
|
||||
uint32_t size)
|
||||
{
|
||||
gpu::Memory* globalMem = device()->getGpuMemory(memObj);
|
||||
|
||||
address mappedMem = static_cast<address>(globalMem->map(NULL,0));
|
||||
assert(mappedMem != 0);
|
||||
|
||||
void* dest_ptr = reinterpret_cast<void*>(mappedMem + offset);
|
||||
memcpy(dest_ptr, srcPtr, size);
|
||||
|
||||
globalMem->unmap(NULL);
|
||||
}
|
||||
|
||||
cl_int
|
||||
GpuDebugManager::createRuntimeTrapHandler()
|
||||
{
|
||||
size_t codeSize = 0;
|
||||
const uint32_t* rtTrapCode = NULL;
|
||||
|
||||
if (device()->settings().viPlus_) {
|
||||
codeSize = sizeof(RuntimeTrapCodeVi);
|
||||
rtTrapCode = RuntimeTrapCodeVi;
|
||||
}
|
||||
else {
|
||||
codeSize = sizeof(RuntimeTrapCode);
|
||||
rtTrapCode = RuntimeTrapCode;
|
||||
}
|
||||
|
||||
uint32_t numCodes = codeSize / sizeof(uint32_t);
|
||||
|
||||
// Handle TMA corruption hw bug workaround -
|
||||
// The trap handler buffer has extra 256 bytes allocated, the TMA address
|
||||
// is stored in the first two DWORDs and the actual trap handler code
|
||||
// is stored starting at the location of 256 bytes (TbaStartOffset).
|
||||
//
|
||||
// allocate memory for the runtime trap handler (TBA) + TMA address
|
||||
uint32_t allocSize = codeSize + TbaStartOffset;
|
||||
|
||||
Memory* rtTBA = new Memory(*device(), allocSize);
|
||||
runtimeTBA_ = rtTBA;
|
||||
|
||||
if ((rtTBA == NULL) || !rtTBA->create(Resource::RemoteUSWC)) {
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
address tbaAddress = reinterpret_cast<address>(rtTBA->map(NULL));
|
||||
|
||||
// allocate buffer for the runtime trap handler buffer (TMA)
|
||||
uint32_t tmaSize = 0x100;
|
||||
Memory* rtTMA = new Memory(*device(), tmaSize);
|
||||
runtimeTMA_ = rtTMA;
|
||||
|
||||
if ((rtTMA == NULL) || !rtTMA->create(Resource::RemoteUSWC)) {
|
||||
return CL_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
uint64_t rtTmaAddress = rtTMA->vmAddress();
|
||||
if ((rtTBA->vmAddress() & 0xFF) != 0 || (rtTmaAddress & 0xFF) != 0) {
|
||||
LogError("debugmanager: Trap handler/buffer is not 256-byte aligned");
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
// store the TMA address at the beginning of trap handler buffer
|
||||
uint64_t* tbaStorage = reinterpret_cast<uint64_t*>(tbaAddress);
|
||||
tbaStorage[0] = rtTmaAddress;
|
||||
|
||||
// save the trap handler code
|
||||
uint32_t* trapHandlerPtr = (uint32_t*)(tbaAddress + TbaStartOffset);
|
||||
for (uint32_t i = 0; i < numCodes; i++) {
|
||||
trapHandlerPtr[i] = rtTrapCode[i];
|
||||
}
|
||||
|
||||
rtTBA->unmap(NULL);
|
||||
|
||||
return CL_SUCCESS;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -36,96 +36,85 @@ class Memory;
|
||||
*
|
||||
*/
|
||||
class GpuDebugManager : public amd::HwDebugManager {
|
||||
public:
|
||||
public:
|
||||
//! Constructor of the debug manager class
|
||||
GpuDebugManager(amd::Device* device);
|
||||
|
||||
//! Constructor of the debug manager class
|
||||
GpuDebugManager(amd::Device* device);
|
||||
//! Destructor of the debug manager class
|
||||
~GpuDebugManager();
|
||||
|
||||
//! Destructor of the debug manager class
|
||||
~GpuDebugManager();
|
||||
//! Get the single instance of the GpuDebugManager class
|
||||
static GpuDebugManager* getDefaultInstance();
|
||||
|
||||
//! Get the single instance of the GpuDebugManager class
|
||||
static GpuDebugManager* getDefaultInstance();
|
||||
//! Destroy the GpuDebugManager class object
|
||||
static void destroyInstances();
|
||||
|
||||
//! Destroy the GpuDebugManager class object
|
||||
static void destroyInstances();
|
||||
//! Flush cache
|
||||
void flushCache(uint32_t mask);
|
||||
|
||||
//! Flush cache
|
||||
void flushCache(uint32_t mask);
|
||||
//! Create the debug event
|
||||
DebugEvent createDebugEvent(const bool autoReset);
|
||||
|
||||
//! Create the debug event
|
||||
DebugEvent createDebugEvent(const bool autoReset);
|
||||
//! Wait for the debug event
|
||||
cl_int waitDebugEvent(DebugEvent pEvent, uint32_t timeOut) const;
|
||||
|
||||
//! Wait for the debug event
|
||||
cl_int waitDebugEvent(DebugEvent pEvent, uint32_t timeOut) const;
|
||||
//! Destroy the debug event
|
||||
void destroyDebugEvent(DebugEvent* pEvent);
|
||||
|
||||
//! Destroy the debug event
|
||||
void destroyDebugEvent(DebugEvent* pEvent);
|
||||
//! Register the debugger
|
||||
cl_int registerDebugger(amd::Context* context, uintptr_t messageStorage);
|
||||
|
||||
//! Register the debugger
|
||||
cl_int registerDebugger(amd::Context*context, uintptr_t messageStorage);
|
||||
//! Unregister the debugger
|
||||
void unregisterDebugger();
|
||||
|
||||
//! Unregister the debugger
|
||||
void unregisterDebugger();
|
||||
//! Send the wavefront control cmmand
|
||||
void wavefrontControl(uint32_t waveAction, uint32_t waveMode, uint32_t trapId,
|
||||
void* waveAddr) const;
|
||||
|
||||
//! Send the wavefront control cmmand
|
||||
void wavefrontControl(uint32_t waveAction,
|
||||
uint32_t waveMode,
|
||||
uint32_t trapId,
|
||||
void* waveAddr) const;
|
||||
//! Set address watching point
|
||||
void setAddressWatch(uint32_t numWatchPoints, void** watchAddress, uint64_t* watchMask,
|
||||
uint64_t* watchMode, DebugEvent* pEvent);
|
||||
|
||||
//! Set address watching point
|
||||
void setAddressWatch(uint32_t numWatchPoints,
|
||||
void** watchAddress,
|
||||
uint64_t* watchMask,
|
||||
uint64_t* watchMode,
|
||||
DebugEvent* pEvent);
|
||||
//! Map the kernel code for host access
|
||||
void mapKernelCode(void* aqlCodeInfo) const;
|
||||
|
||||
//! Map the kernel code for host access
|
||||
void mapKernelCode(void* aqlCodeInfo) const;
|
||||
//! Get the packet information for dispatch
|
||||
void getPacketAmdInfo(const void* aqlCodeInfo, void* packetInfo) const;
|
||||
|
||||
//! Get the packet information for dispatch
|
||||
void getPacketAmdInfo(const void* aqlCodeInfo, void* packetInfo) const;
|
||||
//! Set global memory values
|
||||
void setGlobalMemory(amd::Memory* memObj, uint32_t offset, void* srcPtr, uint32_t size);
|
||||
|
||||
//! Set global memory values
|
||||
void setGlobalMemory(amd::Memory* memObj, uint32_t offset, void* srcPtr, uint32_t size);
|
||||
//! Execute the post-dispatch callback function
|
||||
void executePostDispatchCallBack();
|
||||
|
||||
//! Execute the post-dispatch callback function
|
||||
void executePostDispatchCallBack();
|
||||
//! Execute the pre-dispatch callback function
|
||||
void executePreDispatchCallBack(void* aqlPacket, void* toolInfo);
|
||||
|
||||
//! Execute the pre-dispatch callback function
|
||||
void executePreDispatchCallBack(void* aqlPacket,
|
||||
void* toolInfo);
|
||||
private:
|
||||
//! Setup trap handler info for kernel execution
|
||||
void setupTrapInformation(DebugToolInfo* toolInfo);
|
||||
|
||||
private:
|
||||
//! Create runtime trap handler
|
||||
cl_int createRuntimeTrapHandler();
|
||||
|
||||
//! Setup trap handler info for kernel execution
|
||||
void setupTrapInformation(DebugToolInfo* toolInfo);
|
||||
protected:
|
||||
const VirtualGPU* vGpu() const { return vGpu_; }
|
||||
|
||||
//! Create runtime trap handler
|
||||
cl_int createRuntimeTrapHandler();
|
||||
private:
|
||||
const gpu::Device* device() const { return reinterpret_cast<const gpu::Device*>(device_); }
|
||||
|
||||
protected:
|
||||
VirtualGPU* vGpu_; //!< the virtual GPU
|
||||
|
||||
const VirtualGPU* vGpu() const { return vGpu_; }
|
||||
uintptr_t debugMessages_; //!< Pointer to a SHARED_DEBUG_MESSAGES pass to the KMD
|
||||
|
||||
private:
|
||||
HwDbgAddressWatch* addressWatch_; //!< Address watch data
|
||||
size_t addressWatchSize_; //!< Size of address watch data
|
||||
|
||||
const gpu::Device* device() const {
|
||||
return reinterpret_cast<const gpu::Device *>(device_); }
|
||||
|
||||
VirtualGPU* vGpu_; //!< the virtual GPU
|
||||
|
||||
uintptr_t debugMessages_; //!< Pointer to a SHARED_DEBUG_MESSAGES pass to the KMD
|
||||
|
||||
HwDbgAddressWatch* addressWatch_; //!< Address watch data
|
||||
size_t addressWatchSize_; //!< Size of address watch data
|
||||
|
||||
//! Arguments used by the callback function
|
||||
void* oclEventHandle_; //!< event handler
|
||||
const hsa_kernel_dispatch_packet_t* aqlPacket_; //!< AQL packet
|
||||
//! Arguments used by the callback function
|
||||
void* oclEventHandle_; //!< event handler
|
||||
const hsa_kernel_dispatch_packet_t* aqlPacket_; //!< AQL packet
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // HWDBG_DEBUGMANAGER_H__
|
||||
#endif // HWDBG_DEBUGMANAGER_H__
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "GSLDevice.h"
|
||||
#include "GSLContext.h"
|
||||
|
||||
extern bool getFuncInfoFromImage(CALimage image, CALfuncInfo *pFuncInfo);
|
||||
extern bool getFuncInfoFromImage(CALimage image, CALfuncInfo* pFuncInfo);
|
||||
|
||||
/*! \addtogroup GPU
|
||||
* @{
|
||||
@@ -26,9 +26,9 @@ namespace gpu {
|
||||
//! Maximum number of the supported global atomic counters
|
||||
const static uint MaxAtomicCounters = 8;
|
||||
//! Maximum number of the supported samplers
|
||||
const static uint MaxSamplers = 16;
|
||||
const static uint MaxSamplers = 16;
|
||||
//! Maximum number of supported read images
|
||||
const static uint MaxReadImage = 128;
|
||||
const static uint MaxReadImage = 128;
|
||||
//! Maximum number of supported write images
|
||||
const static uint MaxWriteImage = 8;
|
||||
//! Maximum number of supported read/write images for OCL20
|
||||
@@ -64,84 +64,111 @@ const static uint HsaSamplerObjectAlignment = 16;
|
||||
const static uint DeviceQueueMaskSize = 32;
|
||||
|
||||
//! Defines all supported ASIC families
|
||||
enum AsicFamilies {
|
||||
Family7xx,
|
||||
Family8xx,
|
||||
FamilyTotal
|
||||
};
|
||||
enum AsicFamilies { Family7xx, Family8xx, FamilyTotal };
|
||||
|
||||
struct AMDDeviceInfo {
|
||||
uint machine_; //!< Machine target ID
|
||||
const char* targetName_; //!< Target name
|
||||
const char* machineTarget_; //!< Machine target
|
||||
uint simdPerCU_; //!< Number of SIMDs per CU
|
||||
uint simdWidth_; //!< Number of workitems processed per SIMD
|
||||
uint simdInstructionWidth_; //!< Number of instructions processed per SIMD
|
||||
uint memChannelBankWidth_; //!< Memory channel bank width
|
||||
uint localMemSizePerCU_; //!< Local memory size per CU
|
||||
uint localMemBanks_; //!< Number of banks of local memory
|
||||
uint gfxipVersion_; //!< The core engine GFXIP version
|
||||
uint machine_; //!< Machine target ID
|
||||
const char* targetName_; //!< Target name
|
||||
const char* machineTarget_; //!< Machine target
|
||||
uint simdPerCU_; //!< Number of SIMDs per CU
|
||||
uint simdWidth_; //!< Number of workitems processed per SIMD
|
||||
uint simdInstructionWidth_; //!< Number of instructions processed per SIMD
|
||||
uint memChannelBankWidth_; //!< Memory channel bank width
|
||||
uint localMemSizePerCU_; //!< Local memory size per CU
|
||||
uint localMemBanks_; //!< Number of banks of local memory
|
||||
uint gfxipVersion_; //!< The core engine GFXIP version
|
||||
};
|
||||
|
||||
|
||||
static const AMDDeviceInfo DeviceInfo[] = {
|
||||
// Machine targetName machineTarget
|
||||
/* CAL_TARGET_600 */ { ED_ATI_CAL_MACHINE_R600_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_610 */ { ED_ATI_CAL_MACHINE_R610_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_630 */ { ED_ATI_CAL_MACHINE_R630_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_670 */ { ED_ATI_CAL_MACHINE_R670_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_7XX */ { ED_ATI_CAL_MACHINE_R770_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_770 */ { ED_ATI_CAL_MACHINE_R770_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_710 */ { ED_ATI_CAL_MACHINE_R710_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_730 */ { ED_ATI_CAL_MACHINE_R730_ISA, "", "", 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* CAL_TARGET_CYPRESS */ { ED_ATI_CAL_MACHINE_CYPRESS_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400 },
|
||||
/* CAL_TARGET_JUNIPER */ { ED_ATI_CAL_MACHINE_JUNIPER_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400 },
|
||||
/* CAL_TARGET_REDWOOD */ { ED_ATI_CAL_MACHINE_REDWOOD_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 16, 400 },
|
||||
/* CAL_TARGET_CEDAR */ { ED_ATI_CAL_MACHINE_CEDAR_ISA, "", "", 1, 8, 5, 256, 32 * Ki, 16, 400 },
|
||||
/* CAL_TARGET_SUMO */ { ED_ATI_CAL_MACHINE_SUMO_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 16, 400 },
|
||||
/* CAL_TARGET_SUPERSUMO*/ { ED_ATI_CAL_MACHINE_SUPERSUMO_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 16, 400 },
|
||||
/* CAL_TARGET_WRESTLER*/ { ED_ATI_CAL_MACHINE_WRESTLER_ISA, "", "", 1, 8, 5, 256, 32 * Ki, 16, 400 },
|
||||
/* CAL_TARGET_CAYMAN */ { ED_ATI_CAL_MACHINE_CAYMAN_ISA, "", "", 1, 16, 4, 256, 32 * Ki, 32, 500 },
|
||||
/* CAL_TARGET_KAUAI */ { ED_ATI_CAL_MACHINE_KAUAI_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400 },
|
||||
/* CAL_TARGET_BARTS */ { ED_ATI_CAL_MACHINE_BARTS_ISA , "", "", 1, 16, 5, 256, 32 * Ki, 32, 400 },
|
||||
/* CAL_TARGET_TURKS */ { ED_ATI_CAL_MACHINE_TURKS_ISA , "", "", 1, 16, 5, 256, 32 * Ki, 32, 400 },
|
||||
/* CAL_TARGET_CAICOS */ { ED_ATI_CAL_MACHINE_CAICOS_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400 },
|
||||
/* CAL_TARGET_TAHITI */ { ED_ATI_CAL_MACHINE_TAHITI_ISA, "Tahiti", "tahiti", 4, 16, 1, 256, 64 * Ki, 32, 600 },
|
||||
/* CAL_TARGET_PITCAIRN */ { ED_ATI_CAL_MACHINE_PITCAIRN_ISA, "Pitcairn", "pitcairn", 4, 16, 1, 256, 64 * Ki, 32, 600 },
|
||||
/* CAL_TARGET_CAPEVERDE */ { ED_ATI_CAL_MACHINE_CAPEVERDE_ISA, "Capeverde", "capeverde", 4, 16, 1, 256, 64 * Ki, 32, 600 },
|
||||
/* CAL_TARGET_DEVASTATOR */ { ED_ATI_CAL_MACHINE_DEVASTATOR_ISA,"", "", 1, 16, 4, 256, 32 * Ki, 32, 500 },
|
||||
/* CAL_TARGET_SCRAPPER */ { ED_ATI_CAL_MACHINE_SCRAPPER_ISA, "", "", 1, 16, 4, 256, 32 * Ki, 32, 500 },
|
||||
/* CAL_TARGET_OLAND */ { ED_ATI_CAL_MACHINE_OLAND_ISA, "Oland", "oland", 4, 16, 1, 256, 64 * Ki, 32, 600 },
|
||||
/* CAL_TARGET_BONAIRE */ { ED_ATI_CAL_MACHINE_BONAIRE_ISA, "Bonaire", "bonaire", 4, 16, 1, 256, 64 * Ki, 32, 702 },
|
||||
/* CAL_TARGET_SPECTRE */ { ED_ATI_CAL_MACHINE_SPECTRE_ISA, "Spectre", "spectre", 4, 16, 1, 256, 64 * Ki, 32, 701 },
|
||||
/* CAL_TARGET_SPOOKY */ { ED_ATI_CAL_MACHINE_SPOOKY_ISA, "Spooky", "spooky", 4, 16, 1, 256, 64 * Ki, 32, 701 },
|
||||
/* CAL_TARGET_KALINDI */ { ED_ATI_CAL_MACHINE_KALINDI_ISA, "Kalindi", "kalindi", 4, 16, 1, 256, 64 * Ki, 32, 702 },
|
||||
/* CAL_TARGET_HAINAN */ { ED_ATI_CAL_MACHINE_HAINAN_ISA, "Hainan", "hainan", 4, 16, 1, 256, 64 * Ki, 32, 600 },
|
||||
/* CAL_TARGET_HAWAII */ { ED_ATI_CAL_MACHINE_HAWAII_ISA, "Hawaii", "hawaii", 4, 16, 1, 256, 64 * Ki, 32, 702 },
|
||||
/* CAL_TARGET_ICELAND */ { ED_ATI_CAL_MACHINE_ICELAND_ISA, "Iceland", "iceland", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_TONGA */ { ED_ATI_CAL_MACHINE_TONGA_ISA, "Tonga", "tonga", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_MULLINS */ { ED_ATI_CAL_MACHINE_GODAVARI_ISA, "Mullins", "mullins", 4, 16, 1, 256, 64 * Ki, 32, 702 },
|
||||
/* CAL_TARGET_FIJI */ { ED_ATI_CAL_MACHINE_FIJI_ISA, "Fiji", "fiji", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_CARRIZO */ { ED_ATI_CAL_MACHINE_CARRIZO_ISA, "Carrizo" , "carrizo", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_ELLESMERE */ { ED_ATI_CAL_MACHINE_ELLESMERE_ISA, "Ellesmere", "ellesmere", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_BAFFIN */ { ED_ATI_CAL_MACHINE_BAFFIN_ISA, "Baffin", "baffin", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_GREENLAND */ { ED_ATI_CAL_MACHINE_GREENLAND_ISA, IF(IS_BRAHMA,"","gfx900"), IF(IS_BRAHMA,"","gfx900"), 4, 16, 1, 256, 64 * Ki, 32, 900 },
|
||||
/* CAL_TARGET_STONEY */ { ED_ATI_CAL_MACHINE_STONEY_ISA, "Stoney", "stoney", 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_LEXA */ { ED_ATI_CAL_MACHINE_LEXA_ISA, IF(IS_BRAHMA,"","gfx804"), IF(IS_BRAHMA,"","gfx804"), 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
/* CAL_TARGET_RAVEN */ { ED_ATI_CAL_MACHINE_RAVEN_ISA, IF(IS_BRAHMA,"","gfx901"), IF(IS_BRAHMA,"","gfx901"), 4, 16, 1, 256, 64 * Ki, 32, 900 },
|
||||
/* CAL_TARGET_POLARIS22 */ { ED_ATI_CAL_MACHINE_POLARIS22_ISA, IF(IS_BRAHMA,"","gfx804"), IF(IS_BRAHMA,"","gfx804"), 4, 16, 1, 256, 64 * Ki, 32, 800 },
|
||||
// Machine targetName machineTarget
|
||||
/* CAL_TARGET_600 */ {ED_ATI_CAL_MACHINE_R600_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_610 */ {ED_ATI_CAL_MACHINE_R610_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_630 */ {ED_ATI_CAL_MACHINE_R630_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_670 */ {ED_ATI_CAL_MACHINE_R670_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_7XX */ {ED_ATI_CAL_MACHINE_R770_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_770 */ {ED_ATI_CAL_MACHINE_R770_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_710 */ {ED_ATI_CAL_MACHINE_R710_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_730 */ {ED_ATI_CAL_MACHINE_R730_ISA, "", "", 0, 0, 0, 0, 0, 0, 0},
|
||||
/* CAL_TARGET_CYPRESS */ {ED_ATI_CAL_MACHINE_CYPRESS_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32,
|
||||
400},
|
||||
/* CAL_TARGET_JUNIPER */ {ED_ATI_CAL_MACHINE_JUNIPER_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32,
|
||||
400},
|
||||
/* CAL_TARGET_REDWOOD */ {ED_ATI_CAL_MACHINE_REDWOOD_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 16,
|
||||
400},
|
||||
/* CAL_TARGET_CEDAR */ {ED_ATI_CAL_MACHINE_CEDAR_ISA, "", "", 1, 8, 5, 256, 32 * Ki, 16, 400},
|
||||
/* CAL_TARGET_SUMO */ {ED_ATI_CAL_MACHINE_SUMO_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 16, 400},
|
||||
/* CAL_TARGET_SUPERSUMO*/ {ED_ATI_CAL_MACHINE_SUPERSUMO_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 16,
|
||||
400},
|
||||
/* CAL_TARGET_WRESTLER*/ {ED_ATI_CAL_MACHINE_WRESTLER_ISA, "", "", 1, 8, 5, 256, 32 * Ki, 16,
|
||||
400},
|
||||
/* CAL_TARGET_CAYMAN */ {ED_ATI_CAL_MACHINE_CAYMAN_ISA, "", "", 1, 16, 4, 256, 32 * Ki, 32,
|
||||
500},
|
||||
/* CAL_TARGET_KAUAI */ {ED_ATI_CAL_MACHINE_KAUAI_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400},
|
||||
/* CAL_TARGET_BARTS */ {ED_ATI_CAL_MACHINE_BARTS_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400},
|
||||
/* CAL_TARGET_TURKS */ {ED_ATI_CAL_MACHINE_TURKS_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32, 400},
|
||||
/* CAL_TARGET_CAICOS */ {ED_ATI_CAL_MACHINE_CAICOS_ISA, "", "", 1, 16, 5, 256, 32 * Ki, 32,
|
||||
400},
|
||||
/* CAL_TARGET_TAHITI */ {ED_ATI_CAL_MACHINE_TAHITI_ISA, "Tahiti", "tahiti", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 600},
|
||||
/* CAL_TARGET_PITCAIRN */ {ED_ATI_CAL_MACHINE_PITCAIRN_ISA, "Pitcairn", "pitcairn", 4, 16, 1,
|
||||
256, 64 * Ki, 32, 600},
|
||||
/* CAL_TARGET_CAPEVERDE */ {ED_ATI_CAL_MACHINE_CAPEVERDE_ISA, "Capeverde", "capeverde", 4, 16,
|
||||
1, 256, 64 * Ki, 32, 600},
|
||||
/* CAL_TARGET_DEVASTATOR */ {ED_ATI_CAL_MACHINE_DEVASTATOR_ISA, "", "", 1, 16, 4, 256, 32 * Ki,
|
||||
32, 500},
|
||||
/* CAL_TARGET_SCRAPPER */ {ED_ATI_CAL_MACHINE_SCRAPPER_ISA, "", "", 1, 16, 4, 256, 32 * Ki, 32,
|
||||
500},
|
||||
/* CAL_TARGET_OLAND */ {ED_ATI_CAL_MACHINE_OLAND_ISA, "Oland", "oland", 4, 16, 1, 256, 64 * Ki,
|
||||
32, 600},
|
||||
/* CAL_TARGET_BONAIRE */ {ED_ATI_CAL_MACHINE_BONAIRE_ISA, "Bonaire", "bonaire", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 702},
|
||||
/* CAL_TARGET_SPECTRE */ {ED_ATI_CAL_MACHINE_SPECTRE_ISA, "Spectre", "spectre", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 701},
|
||||
/* CAL_TARGET_SPOOKY */ {ED_ATI_CAL_MACHINE_SPOOKY_ISA, "Spooky", "spooky", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 701},
|
||||
/* CAL_TARGET_KALINDI */ {ED_ATI_CAL_MACHINE_KALINDI_ISA, "Kalindi", "kalindi", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 702},
|
||||
/* CAL_TARGET_HAINAN */ {ED_ATI_CAL_MACHINE_HAINAN_ISA, "Hainan", "hainan", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 600},
|
||||
/* CAL_TARGET_HAWAII */ {ED_ATI_CAL_MACHINE_HAWAII_ISA, "Hawaii", "hawaii", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 702},
|
||||
/* CAL_TARGET_ICELAND */ {ED_ATI_CAL_MACHINE_ICELAND_ISA, "Iceland", "iceland", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 800},
|
||||
/* CAL_TARGET_TONGA */ {ED_ATI_CAL_MACHINE_TONGA_ISA, "Tonga", "tonga", 4, 16, 1, 256, 64 * Ki,
|
||||
32, 800},
|
||||
/* CAL_TARGET_MULLINS */ {ED_ATI_CAL_MACHINE_GODAVARI_ISA, "Mullins", "mullins", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 702},
|
||||
/* CAL_TARGET_FIJI */ {ED_ATI_CAL_MACHINE_FIJI_ISA, "Fiji", "fiji", 4, 16, 1, 256, 64 * Ki, 32,
|
||||
800},
|
||||
/* CAL_TARGET_CARRIZO */ {ED_ATI_CAL_MACHINE_CARRIZO_ISA, "Carrizo", "carrizo", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 800},
|
||||
/* CAL_TARGET_ELLESMERE */ {ED_ATI_CAL_MACHINE_ELLESMERE_ISA, "Ellesmere", "ellesmere", 4, 16,
|
||||
1, 256, 64 * Ki, 32, 800},
|
||||
/* CAL_TARGET_BAFFIN */ {ED_ATI_CAL_MACHINE_BAFFIN_ISA, "Baffin", "baffin", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 800},
|
||||
/* CAL_TARGET_GREENLAND */ {ED_ATI_CAL_MACHINE_GREENLAND_ISA, IF(IS_BRAHMA, "", "gfx900"),
|
||||
IF(IS_BRAHMA, "", "gfx900"), 4, 16, 1, 256, 64 * Ki, 32, 900},
|
||||
/* CAL_TARGET_STONEY */ {ED_ATI_CAL_MACHINE_STONEY_ISA, "Stoney", "stoney", 4, 16, 1, 256,
|
||||
64 * Ki, 32, 800},
|
||||
/* CAL_TARGET_LEXA */ {ED_ATI_CAL_MACHINE_LEXA_ISA, IF(IS_BRAHMA, "", "gfx804"),
|
||||
IF(IS_BRAHMA, "", "gfx804"), 4, 16, 1, 256, 64 * Ki, 32, 800},
|
||||
/* CAL_TARGET_RAVEN */ {ED_ATI_CAL_MACHINE_RAVEN_ISA, IF(IS_BRAHMA, "", "gfx901"),
|
||||
IF(IS_BRAHMA, "", "gfx901"), 4, 16, 1, 256, 64 * Ki, 32, 900},
|
||||
/* CAL_TARGET_POLARIS22 */ {ED_ATI_CAL_MACHINE_POLARIS22_ISA, IF(IS_BRAHMA, "", "gfx804"),
|
||||
IF(IS_BRAHMA, "", "gfx804"), 4, 16, 1, 256, 64 * Ki, 32, 800},
|
||||
};
|
||||
|
||||
enum gfx_handle {
|
||||
gfx700 = 700,
|
||||
gfx701 = 701,
|
||||
gfx702 = 702,
|
||||
gfx800 = 800,
|
||||
gfx801 = 801,
|
||||
gfx804 = 804,
|
||||
gfx810 = 810,
|
||||
gfx900 = 900,
|
||||
gfx901 = 901
|
||||
gfx700 = 700,
|
||||
gfx701 = 701,
|
||||
gfx702 = 702,
|
||||
gfx800 = 800,
|
||||
gfx801 = 801,
|
||||
gfx804 = 804,
|
||||
gfx810 = 810,
|
||||
gfx900 = 900,
|
||||
gfx901 = 901
|
||||
};
|
||||
|
||||
static const char* Gfx700 = "AMD:AMDGPU:7:0:0";
|
||||
@@ -154,334 +181,272 @@ static const char* Gfx900 = "AMD:AMDGPU:9:0:0";
|
||||
static const char* Gfx901 = "AMD:AMDGPU:9:0:1";
|
||||
|
||||
// Supported OpenCL versions
|
||||
enum OclVersion {
|
||||
OpenCL10,
|
||||
OpenCL11,
|
||||
OpenCL12,
|
||||
OpenCL20
|
||||
};
|
||||
enum OclVersion { OpenCL10, OpenCL11, OpenCL12, OpenCL20 };
|
||||
|
||||
struct CalFormat {
|
||||
gslChannelOrder channelOrder_; //!< Texel/pixel GSL channel order
|
||||
cmSurfFmt type_; //!< Texel/pixel CAL format
|
||||
gslChannelOrder channelOrder_; //!< Texel/pixel GSL channel order
|
||||
cmSurfFmt type_; //!< Texel/pixel CAL format
|
||||
};
|
||||
|
||||
struct MemoryFormat {
|
||||
cl_image_format clFormat_; //!< CL image format
|
||||
CalFormat calFormat_; //!< CAL image format
|
||||
cl_image_format clFormat_; //!< CL image format
|
||||
CalFormat calFormat_; //!< CAL image format
|
||||
};
|
||||
|
||||
static const MemoryFormat
|
||||
MemoryFormatMap[] = {
|
||||
static const MemoryFormat MemoryFormatMap[] = {
|
||||
// R
|
||||
{ { CL_R, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_INTENSITY8 } },
|
||||
{ { CL_R, CL_UNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R16 } },
|
||||
{{CL_R, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_INTENSITY8}},
|
||||
{{CL_R, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R16}},
|
||||
|
||||
{ { CL_R, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR8 } },
|
||||
{ { CL_R, CL_SNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sU16 } },
|
||||
{{CL_R, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR8}},
|
||||
{{CL_R, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sU16}},
|
||||
|
||||
{ { CL_R, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR8I } },
|
||||
{ { CL_R, CL_SIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR16I } },
|
||||
{ { CL_R, CL_SIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR32I } },
|
||||
{ { CL_R, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R8I } },
|
||||
{ { CL_R, CL_UNSIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R16I } },
|
||||
{ { CL_R, CL_UNSIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_R , CM_SURF_FMT_R32I } },
|
||||
{{CL_R, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR8I}},
|
||||
{{CL_R, CL_SIGNED_INT16}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR16I}},
|
||||
{{CL_R, CL_SIGNED_INT32}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_sR32I}},
|
||||
{{CL_R, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R8I}},
|
||||
{{CL_R, CL_UNSIGNED_INT16}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R16I}},
|
||||
{{CL_R, CL_UNSIGNED_INT32}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R32I}},
|
||||
|
||||
{ { CL_R, CL_HALF_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R16F } },
|
||||
{ { CL_R, CL_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R32F } },
|
||||
{{CL_R, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R16F}},
|
||||
{{CL_R, CL_FLOAT}, {GSL_CHANNEL_ORDER_R, CM_SURF_FMT_R32F}},
|
||||
|
||||
// A
|
||||
{ { CL_A, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_INTENSITY8 } },
|
||||
{ { CL_A, CL_UNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R16 } },
|
||||
{{CL_A, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_INTENSITY8}},
|
||||
{{CL_A, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R16}},
|
||||
|
||||
{ { CL_A, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR8 } },
|
||||
{ { CL_A, CL_SNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sU16 } },
|
||||
{{CL_A, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR8}},
|
||||
{{CL_A, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sU16}},
|
||||
|
||||
{ { CL_A, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR8I } },
|
||||
{ { CL_A, CL_SIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR16I } },
|
||||
{ { CL_A, CL_SIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR32I } },
|
||||
{ { CL_A, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R8I } },
|
||||
{ { CL_A, CL_UNSIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R16I } },
|
||||
{ { CL_A, CL_UNSIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_A , CM_SURF_FMT_R32I } },
|
||||
{{CL_A, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR8I}},
|
||||
{{CL_A, CL_SIGNED_INT16}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR16I}},
|
||||
{{CL_A, CL_SIGNED_INT32}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_sR32I}},
|
||||
{{CL_A, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R8I}},
|
||||
{{CL_A, CL_UNSIGNED_INT16}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R16I}},
|
||||
{{CL_A, CL_UNSIGNED_INT32}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R32I}},
|
||||
|
||||
{ { CL_A, CL_HALF_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R16F } },
|
||||
{ { CL_A, CL_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R32F } },
|
||||
{{CL_A, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R16F}},
|
||||
{{CL_A, CL_FLOAT}, {GSL_CHANNEL_ORDER_A, CM_SURF_FMT_R32F}},
|
||||
|
||||
// RG
|
||||
{ { CL_RG, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG8 } },
|
||||
{ { CL_RG, CL_UNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG16 } },
|
||||
{{CL_RG, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG8}},
|
||||
{{CL_RG, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG16}},
|
||||
|
||||
{ { CL_RG, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG8 } },
|
||||
{ { CL_RG, CL_SNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sUV16 } },
|
||||
{{CL_RG, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG8}},
|
||||
{{CL_RG, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sUV16}},
|
||||
|
||||
{ { CL_RG, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG8I } },
|
||||
{ { CL_RG, CL_SIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG16I } },
|
||||
{ { CL_RG, CL_SIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG32I } },
|
||||
{ { CL_RG, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG8I } },
|
||||
{ { CL_RG, CL_UNSIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG16I } },
|
||||
{ { CL_RG, CL_UNSIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_RG , CM_SURF_FMT_RG32I } },
|
||||
{{CL_RG, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG8I}},
|
||||
{{CL_RG, CL_SIGNED_INT16}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG16I}},
|
||||
{{CL_RG, CL_SIGNED_INT32}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_sRG32I}},
|
||||
{{CL_RG, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG8I}},
|
||||
{{CL_RG, CL_UNSIGNED_INT16}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG16I}},
|
||||
{{CL_RG, CL_UNSIGNED_INT32}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG32I}},
|
||||
|
||||
{ { CL_RG, CL_HALF_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG16F } },
|
||||
{ { CL_RG, CL_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG32F } },
|
||||
{{CL_RG, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG16F}},
|
||||
{{CL_RG, CL_FLOAT}, {GSL_CHANNEL_ORDER_RG, CM_SURF_FMT_RG32F}},
|
||||
|
||||
// RA
|
||||
{ { CL_RA, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG8 } },
|
||||
{ { CL_RA, CL_UNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG16 } },
|
||||
{{CL_RA, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG8}},
|
||||
{{CL_RA, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG16}},
|
||||
|
||||
{ { CL_RA, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG8 } },
|
||||
{ { CL_RA, CL_SNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sUV16 } },
|
||||
{{CL_RA, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG8}},
|
||||
{{CL_RA, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sUV16}},
|
||||
|
||||
{ { CL_RA, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG8I } },
|
||||
{ { CL_RA, CL_SIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG16I } },
|
||||
{ { CL_RA, CL_SIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG32I } },
|
||||
{ { CL_RA, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG8I } },
|
||||
{ { CL_RA, CL_UNSIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG16I } },
|
||||
{ { CL_RA, CL_UNSIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_RA , CM_SURF_FMT_RG32I } },
|
||||
{{CL_RA, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG8I}},
|
||||
{{CL_RA, CL_SIGNED_INT16}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG16I}},
|
||||
{{CL_RA, CL_SIGNED_INT32}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_sRG32I}},
|
||||
{{CL_RA, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG8I}},
|
||||
{{CL_RA, CL_UNSIGNED_INT16}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG16I}},
|
||||
{{CL_RA, CL_UNSIGNED_INT32}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG32I}},
|
||||
|
||||
{ { CL_RA, CL_HALF_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG16F } },
|
||||
{ { CL_RA, CL_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG32F } },
|
||||
{{CL_RA, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG16F}},
|
||||
{{CL_RA, CL_FLOAT}, {GSL_CHANNEL_ORDER_RA, CM_SURF_FMT_RG32F}},
|
||||
|
||||
// RGB
|
||||
{ { CL_RGB, CL_UNORM_INT_101010 },
|
||||
{ GSL_CHANNEL_ORDER_RGB, CM_SURF_FMT_BGR10_X2 } },
|
||||
{ { CL_RGB, CL_UNSIGNED_INT8 }, // This is used only by blit kernel
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_RGB, CL_UNORM_INT_101010}, {GSL_CHANNEL_ORDER_RGB, CM_SURF_FMT_BGR10_X2}},
|
||||
{{CL_RGB, CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// RGBA
|
||||
{ { CL_RGBA, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA8 } },
|
||||
{ { CL_RGBA, CL_UNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA16 } },
|
||||
{{CL_RGBA, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA8}},
|
||||
{{CL_RGBA, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA16}},
|
||||
|
||||
{ { CL_RGBA, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA8 } },
|
||||
{ { CL_RGBA, CL_SNORM_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sUVWQ16 } },
|
||||
{{CL_RGBA, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA8}},
|
||||
{{CL_RGBA, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sUVWQ16}},
|
||||
|
||||
{ { CL_RGBA, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA8I } },
|
||||
{ { CL_RGBA, CL_SIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA16I } },
|
||||
{ { CL_RGBA, CL_SIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA32I } },
|
||||
{ { CL_RGBA, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA8UI } },
|
||||
{ { CL_RGBA, CL_UNSIGNED_INT16 },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA16UI } },
|
||||
{ { CL_RGBA, CL_UNSIGNED_INT32},
|
||||
{ GSL_CHANNEL_ORDER_RGBA , CM_SURF_FMT_RGBA32UI } },
|
||||
{{CL_RGBA, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA8I}},
|
||||
{{CL_RGBA, CL_SIGNED_INT16}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA16I}},
|
||||
{{CL_RGBA, CL_SIGNED_INT32}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_sRGBA32I}},
|
||||
{{CL_RGBA, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA8UI}},
|
||||
{{CL_RGBA, CL_UNSIGNED_INT16}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA16UI}},
|
||||
{{CL_RGBA, CL_UNSIGNED_INT32}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA32UI}},
|
||||
|
||||
{ { CL_RGBA, CL_HALF_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA16F } },
|
||||
{ { CL_RGBA, CL_FLOAT },
|
||||
{ GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA32F } },
|
||||
{{CL_RGBA, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA16F}},
|
||||
{{CL_RGBA, CL_FLOAT}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGBA32F}},
|
||||
|
||||
// ARGB
|
||||
{ { CL_ARGB, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_RGBA8 } },
|
||||
{ { CL_ARGB, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_sRGBA8 } },
|
||||
{ { CL_ARGB, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_sRGBA8I } },
|
||||
{ { CL_ARGB, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_ARGB, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_RGBA8}},
|
||||
{{CL_ARGB, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_sRGBA8}},
|
||||
{{CL_ARGB, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_sRGBA8I}},
|
||||
{{CL_ARGB, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_ARGB, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// BGRA
|
||||
{ { CL_BGRA, CL_UNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_RGBA8 } },
|
||||
{ { CL_BGRA, CL_SNORM_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_sRGBA8 } },
|
||||
{ { CL_BGRA, CL_SIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_sRGBA8I } },
|
||||
{ { CL_BGRA, CL_UNSIGNED_INT8 },
|
||||
{ GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_BGRA, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_RGBA8}},
|
||||
{{CL_BGRA, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_sRGBA8}},
|
||||
{{CL_BGRA, CL_SIGNED_INT8}, {GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_sRGBA8I}},
|
||||
{{CL_BGRA, CL_UNSIGNED_INT8}, {GSL_CHANNEL_ORDER_BGRA, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// LUMINANCE
|
||||
{ {CL_LUMINANCE, CL_SNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_LUMINANCE,CM_SURF_FMT_sR8 } },
|
||||
{ {CL_LUMINANCE, CL_SNORM_INT16},
|
||||
{ GSL_CHANNEL_ORDER_LUMINANCE,CM_SURF_FMT_sU16 } },
|
||||
{ {CL_LUMINANCE, CL_UNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_LUMINANCE,CM_SURF_FMT_INTENSITY8 } },
|
||||
{ {CL_LUMINANCE, CL_UNORM_INT16},
|
||||
{ GSL_CHANNEL_ORDER_LUMINANCE,CM_SURF_FMT_R16 } },
|
||||
{ {CL_LUMINANCE, CL_HALF_FLOAT},
|
||||
{ GSL_CHANNEL_ORDER_LUMINANCE,CM_SURF_FMT_R16F } },
|
||||
{ {CL_LUMINANCE, CL_FLOAT},
|
||||
{ GSL_CHANNEL_ORDER_LUMINANCE,CM_SURF_FMT_R32F } },
|
||||
{{CL_LUMINANCE, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_LUMINANCE, CM_SURF_FMT_sR8}},
|
||||
{{CL_LUMINANCE, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_LUMINANCE, CM_SURF_FMT_sU16}},
|
||||
{{CL_LUMINANCE, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_LUMINANCE, CM_SURF_FMT_INTENSITY8}},
|
||||
{{CL_LUMINANCE, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_LUMINANCE, CM_SURF_FMT_R16}},
|
||||
{{CL_LUMINANCE, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_LUMINANCE, CM_SURF_FMT_R16F}},
|
||||
{{CL_LUMINANCE, CL_FLOAT}, {GSL_CHANNEL_ORDER_LUMINANCE, CM_SURF_FMT_R32F}},
|
||||
|
||||
// INTENSITY
|
||||
{ {CL_INTENSITY, CL_SNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_INTENSITY,CM_SURF_FMT_sR8 } },
|
||||
{ {CL_INTENSITY, CL_SNORM_INT16},
|
||||
{ GSL_CHANNEL_ORDER_INTENSITY,CM_SURF_FMT_sU16 } },
|
||||
{ {CL_INTENSITY, CL_UNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_INTENSITY,CM_SURF_FMT_INTENSITY8 } },
|
||||
{ {CL_INTENSITY, CL_UNORM_INT16},
|
||||
{ GSL_CHANNEL_ORDER_INTENSITY,CM_SURF_FMT_R16 } },
|
||||
{ {CL_INTENSITY, CL_HALF_FLOAT},
|
||||
{ GSL_CHANNEL_ORDER_INTENSITY,CM_SURF_FMT_R16F } },
|
||||
{ {CL_INTENSITY, CL_FLOAT},
|
||||
{ GSL_CHANNEL_ORDER_INTENSITY,CM_SURF_FMT_R32F } },
|
||||
{{CL_INTENSITY, CL_SNORM_INT8}, {GSL_CHANNEL_ORDER_INTENSITY, CM_SURF_FMT_sR8}},
|
||||
{{CL_INTENSITY, CL_SNORM_INT16}, {GSL_CHANNEL_ORDER_INTENSITY, CM_SURF_FMT_sU16}},
|
||||
{{CL_INTENSITY, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_INTENSITY, CM_SURF_FMT_INTENSITY8}},
|
||||
{{CL_INTENSITY, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_INTENSITY, CM_SURF_FMT_R16}},
|
||||
{{CL_INTENSITY, CL_HALF_FLOAT}, {GSL_CHANNEL_ORDER_INTENSITY, CM_SURF_FMT_R16F}},
|
||||
{{CL_INTENSITY, CL_FLOAT}, {GSL_CHANNEL_ORDER_INTENSITY, CM_SURF_FMT_R32F}},
|
||||
|
||||
// sRBGA
|
||||
{ {CL_sRGBA ,CL_UNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_SRGBA, CM_SURF_FMT_RGBA8_SRGB } },
|
||||
{ {CL_sRGBA ,CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{ GSL_CHANNEL_ORDER_SRGBA, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_sRGBA, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_SRGBA, CM_SURF_FMT_RGBA8_SRGB}},
|
||||
{{CL_sRGBA, CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_SRGBA, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// sRBG
|
||||
{ {CL_sRGB ,CL_UNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_SRGB, CM_SURF_FMT_RGBX8UI } },
|
||||
{ {CL_sRGB ,CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{ GSL_CHANNEL_ORDER_SRGB, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_sRGB, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_SRGB, CM_SURF_FMT_RGBX8UI}},
|
||||
{{CL_sRGB, CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_SRGB, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// sRBGx
|
||||
{ {CL_sRGBx ,CL_UNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_SRGBX, CM_SURF_FMT_RGBX8UI } },
|
||||
{ {CL_sRGBx ,CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{ GSL_CHANNEL_ORDER_SRGBX, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_sRGBx, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_SRGBX, CM_SURF_FMT_RGBX8UI}},
|
||||
{{CL_sRGBx, CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_SRGBX, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// sBGRA
|
||||
{ {CL_sBGRA ,CL_UNORM_INT8},
|
||||
{ GSL_CHANNEL_ORDER_SBGRA, CM_SURF_FMT_RGBA8 } },
|
||||
{ {CL_sBGRA ,CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{ GSL_CHANNEL_ORDER_SBGRA, CM_SURF_FMT_RGBA8UI } },
|
||||
{{CL_sBGRA, CL_UNORM_INT8}, {GSL_CHANNEL_ORDER_SBGRA, CM_SURF_FMT_RGBA8}},
|
||||
{{CL_sBGRA, CL_UNSIGNED_INT8}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_SBGRA, CM_SURF_FMT_RGBA8UI}},
|
||||
|
||||
// DEPTH
|
||||
{ {CL_DEPTH ,CL_FLOAT},
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R ,CM_SURF_FMT_DEPTH32F}},
|
||||
{ {CL_DEPTH ,CL_UNSIGNED_INT32}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R ,CM_SURF_FMT_R32I}},
|
||||
{{CL_DEPTH, CL_FLOAT}, {GSL_CHANNEL_ORDER_REPLICATE_R, CM_SURF_FMT_DEPTH32F}},
|
||||
{{CL_DEPTH, CL_UNSIGNED_INT32}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R, CM_SURF_FMT_R32I}},
|
||||
|
||||
{ {CL_DEPTH ,CL_UNORM_INT16},
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R ,CM_SURF_FMT_DEPTH16}},
|
||||
{ {CL_DEPTH ,CL_UNSIGNED_INT16}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R ,CM_SURF_FMT_R16I}},
|
||||
{{CL_DEPTH, CL_UNORM_INT16}, {GSL_CHANNEL_ORDER_REPLICATE_R, CM_SURF_FMT_DEPTH16}},
|
||||
{{CL_DEPTH, CL_UNSIGNED_INT16}, // This is used only by blit kernel
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R, CM_SURF_FMT_R16I}},
|
||||
|
||||
{ {CL_DEPTH_STENCIL ,CL_UNORM_INT24},
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R ,CM_SURF_FMT_DEPTH24_STEN8}},
|
||||
{ {CL_DEPTH_STENCIL ,CL_FLOAT},
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R ,CM_SURF_FMT_DEPTH32F_X24_STEN8}}
|
||||
{{CL_DEPTH_STENCIL, CL_UNORM_INT24},
|
||||
{GSL_CHANNEL_ORDER_REPLICATE_R, CM_SURF_FMT_DEPTH24_STEN8}},
|
||||
{{CL_DEPTH_STENCIL, CL_FLOAT}, {GSL_CHANNEL_ORDER_REPLICATE_R, CM_SURF_FMT_DEPTH32F_X24_STEN8}}
|
||||
|
||||
};
|
||||
|
||||
struct MemFormatStruct {
|
||||
cmSurfFmt format_;
|
||||
uint size_;
|
||||
uint components_;
|
||||
cmSurfFmt format_;
|
||||
uint size_;
|
||||
uint components_;
|
||||
};
|
||||
|
||||
static const MemFormatStruct
|
||||
MemoryFormatSize[] = {
|
||||
{ CM_SURF_FMT_INTENSITY8, 1, 1 },/**< 1 component, normalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_RG8, 2, 2 }, /**< 2 component, normalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBA8, 4, 4 }, /**< 4 component, normalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBA8_SRGB, 4, 4 }, /**< 4 component, normalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_R16, 2, 1 }, /**< 1 component, normalized unsigned 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_RG16, 4, 2 }, /**< 2 component, normalized unsigned 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBA16, 8, 4 }, /**< 4 component, normalized unsigned 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRGBA8, 4, 4 }, /**< 4 component, normalized signed 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_sU16, 2, 1 }, /**< 1 component, normalized signed 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_sUV16, 4, 2 }, /**< 2 component, normalized signed 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_sUVWQ16, 8, 4 }, /**< 4 component, normalized signed 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_R32F, 4, 1 }, /**< A 1 component, 32-bit float value per component */
|
||||
{ CM_SURF_FMT_RG32F, 8, 2 }, /**< A 2 component, 32-bit float value per component */
|
||||
{ CM_SURF_FMT_RGBA32F, 16, 4 }, /**< A 4 component, 32-bit float value per component */
|
||||
{ CM_SURF_FMT_sR8, 1, 1 }, /**< 1 component, normalized signed 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRG8, 2, 2 }, /**< 2 component, normalized signed 8-bit integer value per component */
|
||||
static const MemFormatStruct MemoryFormatSize[] = {
|
||||
{CM_SURF_FMT_INTENSITY8, 1,
|
||||
1}, /**< 1 component, normalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_RG8, 2,
|
||||
2}, /**< 2 component, normalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBA8, 4,
|
||||
4}, /**< 4 component, normalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBA8_SRGB, 4,
|
||||
4}, /**< 4 component, normalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_R16, 2,
|
||||
1}, /**< 1 component, normalized unsigned 16-bit integer value per component */
|
||||
{CM_SURF_FMT_RG16, 4,
|
||||
2}, /**< 2 component, normalized unsigned 16-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBA16, 8,
|
||||
4}, /**< 4 component, normalized unsigned 16-bit integer value per component */
|
||||
{CM_SURF_FMT_sRGBA8, 4,
|
||||
4}, /**< 4 component, normalized signed 8-bit integer value per component */
|
||||
{CM_SURF_FMT_sU16, 2,
|
||||
1}, /**< 1 component, normalized signed 16-bit integer value per component */
|
||||
{CM_SURF_FMT_sUV16, 4,
|
||||
2}, /**< 2 component, normalized signed 16-bit integer value per component */
|
||||
{CM_SURF_FMT_sUVWQ16, 8,
|
||||
4}, /**< 4 component, normalized signed 16-bit integer value per component */
|
||||
{CM_SURF_FMT_R32F, 4, 1}, /**< A 1 component, 32-bit float value per component */
|
||||
{CM_SURF_FMT_RG32F, 8, 2}, /**< A 2 component, 32-bit float value per component */
|
||||
{CM_SURF_FMT_RGBA32F, 16, 4}, /**< A 4 component, 32-bit float value per component */
|
||||
{CM_SURF_FMT_sR8, 1,
|
||||
1}, /**< 1 component, normalized signed 8-bit integer value per component */
|
||||
{CM_SURF_FMT_sRG8, 2,
|
||||
2}, /**< 2 component, normalized signed 8-bit integer value per component */
|
||||
|
||||
{ CM_SURF_FMT_R8I, 1, 1 }, /**< 1 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_RG8I, 2, 2 }, /**< 2 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBA8UI, 4, 4 }, /**< 4 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBX8UI, 4, 4 }, /**< 4 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_sR8I, 1, 1 }, /**< 1 component, unnormalized signed 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRG8I, 2, 2 }, /**< 2 component, unnormalized signed 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRGBA8I, 4, 4 }, /**< 4 component, unnormalized signed 8-bit integer value per component */
|
||||
{ CM_SURF_FMT_R16I, 2, 1 }, /**< 1 component, unnormalized unsigned 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_RG16I, 4, 2 }, /**< 2 component, unnormalized unsigned 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBA16UI, 8, 4 }, /**< 4 component, unnormalized unsigned 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_sR16I, 2, 1 }, /**< 1 component, unnormalized signed 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRG16I, 4, 2 }, /**< 2 component, unnormalized signed 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRGBA16I, 8, 4 }, /**< 4 component, unnormalized signed 16-bit integer value per component */
|
||||
{ CM_SURF_FMT_R32I, 4, 1 }, /**< 1 component, unnormalized unsigned 32-bit integer value per component */
|
||||
{ CM_SURF_FMT_RG32I, 8, 2 }, /**< 2 component, unnormalized unsigned 32-bit integer value per component */
|
||||
{ CM_SURF_FMT_RGBA32UI, 16, 4 }, /**< 4 component, unnormalized unsigned 32-bit integer value per component */
|
||||
{ CM_SURF_FMT_sR32I, 4, 1 }, /**< 1 component, unnormalized signed 32-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRG32I, 8, 2 }, /**< 2 component, unnormalized signed 32-bit integer value per component */
|
||||
{ CM_SURF_FMT_sRGBA32I, 16, 4 }, /**< 4 component, unnormalized signed 32-bit integer value per component */
|
||||
{CM_SURF_FMT_R8I, 1,
|
||||
1}, /**< 1 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_RG8I, 2,
|
||||
2}, /**< 2 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBA8UI, 4,
|
||||
4}, /**< 4 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBX8UI, 4,
|
||||
4}, /**< 4 component, unnormalized unsigned 8-bit integer value per component */
|
||||
{CM_SURF_FMT_sR8I, 1,
|
||||
1}, /**< 1 component, unnormalized signed 8-bit integer value per component */
|
||||
{CM_SURF_FMT_sRG8I, 2,
|
||||
2}, /**< 2 component, unnormalized signed 8-bit integer value per component */
|
||||
{CM_SURF_FMT_sRGBA8I, 4,
|
||||
4}, /**< 4 component, unnormalized signed 8-bit integer value per component */
|
||||
{CM_SURF_FMT_R16I, 2,
|
||||
1}, /**< 1 component, unnormalized unsigned 16-bit integer value per component */
|
||||
{CM_SURF_FMT_RG16I, 4,
|
||||
2}, /**< 2 component, unnormalized unsigned 16-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBA16UI, 8,
|
||||
4}, /**< 4 component, unnormalized unsigned 16-bit integer value per component */
|
||||
{CM_SURF_FMT_sR16I, 2,
|
||||
1}, /**< 1 component, unnormalized signed 16-bit integer value per component */
|
||||
{CM_SURF_FMT_sRG16I, 4,
|
||||
2}, /**< 2 component, unnormalized signed 16-bit integer value per component */
|
||||
{CM_SURF_FMT_sRGBA16I, 8,
|
||||
4}, /**< 4 component, unnormalized signed 16-bit integer value per component */
|
||||
{CM_SURF_FMT_R32I, 4,
|
||||
1}, /**< 1 component, unnormalized unsigned 32-bit integer value per component */
|
||||
{CM_SURF_FMT_RG32I, 8,
|
||||
2}, /**< 2 component, unnormalized unsigned 32-bit integer value per component */
|
||||
{CM_SURF_FMT_RGBA32UI, 16,
|
||||
4}, /**< 4 component, unnormalized unsigned 32-bit integer value per component */
|
||||
{CM_SURF_FMT_sR32I, 4,
|
||||
1}, /**< 1 component, unnormalized signed 32-bit integer value per component */
|
||||
{CM_SURF_FMT_sRG32I, 8,
|
||||
2}, /**< 2 component, unnormalized signed 32-bit integer value per component */
|
||||
{CM_SURF_FMT_sRGBA32I, 16,
|
||||
4}, /**< 4 component, unnormalized signed 32-bit integer value per component */
|
||||
|
||||
{ CM_SURF_FMT_R16F, 2, 1 }, /**< A 1 component, 16-bit float value per component */
|
||||
{ CM_SURF_FMT_RG16F, 4, 2 }, /**< A 2 component, 16-bit float value per component */
|
||||
{ CM_SURF_FMT_RGBA16F, 8, 4 }, /**< A 4 component, 16-bit float value per component */
|
||||
{CM_SURF_FMT_R16F, 2, 1}, /**< A 1 component, 16-bit float value per component */
|
||||
{CM_SURF_FMT_RG16F, 4, 2}, /**< A 2 component, 16-bit float value per component */
|
||||
{CM_SURF_FMT_RGBA16F, 8, 4}, /**< A 4 component, 16-bit float value per component */
|
||||
|
||||
{ CM_SURF_FMT_BGR10_X2, 4, 4 }, /**< 4 component, unnormalized signed 10-bit integer value per component packed as (@c XXRRRRRRRRRRGGGGGGGGGGBBBBBBBBBB)*/
|
||||
{ CM_SURF_FMT_DEPTH32F, 4, 1 }, /**< A one component, 32 float value per component */
|
||||
{ CM_SURF_FMT_DEPTH16 , 2, 1 }, /**< A one component, 16 unsigned int value per component */
|
||||
{ CM_SURF_FMT_DEPTH24_STEN8 , 4 ,1}, /**< A one component, 32 float value per component */
|
||||
{ CM_SURF_FMT_DEPTH32F_X24_STEN8 , 8 ,2} /**< depth + stencil, 64 bits per element packed as (@c XXXXXXXXXXXXXXXXXXXXXXXXSSSSSSSSDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD) */
|
||||
{CM_SURF_FMT_BGR10_X2, 4, 4}, /**< 4 component, unnormalized signed 10-bit integer value per
|
||||
component packed as (@c XXRRRRRRRRRRGGGGGGGGGGBBBBBBBBBB)*/
|
||||
{CM_SURF_FMT_DEPTH32F, 4, 1}, /**< A one component, 32 float value per component */
|
||||
{CM_SURF_FMT_DEPTH16, 2, 1}, /**< A one component, 16 unsigned int value per component */
|
||||
{CM_SURF_FMT_DEPTH24_STEN8, 4, 1}, /**< A one component, 32 float value per component */
|
||||
{CM_SURF_FMT_DEPTH32F_X24_STEN8, 8,
|
||||
2} /**< depth + stencil, 64 bits per element packed as (@c
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXSSSSSSSSDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD) */
|
||||
};
|
||||
|
||||
__inline const MemFormatStruct&
|
||||
memoryFormatSize(cmSurfFmt fmt)
|
||||
{
|
||||
for (uint i = 0; i < sizeof(MemoryFormatSize) / sizeof(MemFormatStruct); ++i) {
|
||||
if (MemoryFormatSize[i].format_ == fmt) {
|
||||
return MemoryFormatSize[i];
|
||||
}
|
||||
__inline const MemFormatStruct& memoryFormatSize(cmSurfFmt fmt) {
|
||||
for (uint i = 0; i < sizeof(MemoryFormatSize) / sizeof(MemFormatStruct); ++i) {
|
||||
if (MemoryFormatSize[i].format_ == fmt) {
|
||||
return MemoryFormatSize[i];
|
||||
}
|
||||
assert (!"Unknown GSL memory format!");
|
||||
return MemoryFormatSize[0];
|
||||
}
|
||||
assert(!"Unknown GSL memory format!");
|
||||
return MemoryFormatSize[0];
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUDEFS_HPP_
|
||||
#endif // GPUDEFS_HPP_
|
||||
+1852
-2077
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+3144
-3460
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1003
-1156
File diff suppressed because it is too large.
Load diff
@@ -28,275 +28,245 @@ class VirtualGPU;
|
||||
|
||||
//! GPU memory object.
|
||||
// Wrapper that can contain a heap block or an interop buffer/image.
|
||||
class Memory: public device::Memory, public Resource
|
||||
{
|
||||
public:
|
||||
enum InteropType {
|
||||
InteropNone = 0, //!< None interop memory
|
||||
InteropHwEmulation = 1, //!< Uses HW emulaiton with calMemCopy
|
||||
InteropDirectAccess = 2 //!< Uses direct access to the interop surface
|
||||
};
|
||||
class Memory : public device::Memory, public Resource {
|
||||
public:
|
||||
enum InteropType {
|
||||
InteropNone = 0, //!< None interop memory
|
||||
InteropHwEmulation = 1, //!< Uses HW emulaiton with calMemCopy
|
||||
InteropDirectAccess = 2 //!< Uses direct access to the interop surface
|
||||
};
|
||||
|
||||
//! Constructor (with owner)
|
||||
Memory(
|
||||
const Device& gpuDev,
|
||||
amd::Memory& owner,
|
||||
size_t size = 0);
|
||||
//! Constructor (with owner)
|
||||
Memory(const Device& gpuDev, amd::Memory& owner, size_t size = 0);
|
||||
|
||||
//! Constructor (nonfat version for local scratch mem use without heap block)
|
||||
Memory(
|
||||
const Device& gpuDev,
|
||||
size_t size);
|
||||
//! Constructor (nonfat version for local scratch mem use without heap block)
|
||||
Memory(const Device& gpuDev, size_t size);
|
||||
|
||||
//! Constructor memory for buffer (without global heap allocaton)
|
||||
Memory(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t width, //!< Memory width
|
||||
cmSurfFmt format //!< CAL format
|
||||
);
|
||||
//! Constructor memory for buffer (without global heap allocaton)
|
||||
Memory(const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t width, //!< Memory width
|
||||
cmSurfFmt format //!< CAL format
|
||||
);
|
||||
|
||||
//! Constructor memory for buffer (without global heap allocaton)
|
||||
Memory(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
size_t size, //!< Memory object size
|
||||
size_t width, //!< Memory width
|
||||
cmSurfFmt format //!< CAL format
|
||||
);
|
||||
//! Constructor memory for buffer (without global heap allocaton)
|
||||
Memory(const Device& gpuDev, //!< GPU device object
|
||||
size_t size, //!< Memory object size
|
||||
size_t width, //!< Memory width
|
||||
cmSurfFmt format //!< CAL format
|
||||
);
|
||||
|
||||
//! Constructor memory for images (without global heap allocaton)
|
||||
Memory(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
);
|
||||
//! Constructor memory for images (without global heap allocaton)
|
||||
Memory(const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
);
|
||||
|
||||
//! Constructor memory for images (without global heap allocaton)
|
||||
Memory(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
size_t size, //!< Memory object size
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
);
|
||||
//! Constructor memory for images (without global heap allocaton)
|
||||
Memory(const Device& gpuDev, //!< GPU device object
|
||||
size_t size, //!< Memory object size
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
);
|
||||
|
||||
//! Default destructor
|
||||
~Memory();
|
||||
//! Default destructor
|
||||
~Memory();
|
||||
|
||||
//! Creates the interop memory
|
||||
bool createInterop(
|
||||
InteropType type //!< The interop type
|
||||
);
|
||||
//! Creates the interop memory
|
||||
bool createInterop(InteropType type //!< The interop type
|
||||
);
|
||||
|
||||
//! Overloads the resource create method
|
||||
virtual bool create(
|
||||
Resource::MemoryType memType, //!< Memory type
|
||||
Resource::CreateParams* params = NULL //!< Prameters for create
|
||||
);
|
||||
//! Overloads the resource create method
|
||||
virtual bool create(Resource::MemoryType memType, //!< Memory type
|
||||
Resource::CreateParams* params = NULL //!< Prameters for create
|
||||
);
|
||||
|
||||
//! Allocate memory for API-level maps
|
||||
virtual void* allocMapTarget(
|
||||
const amd::Coord3D& origin, //!< The map location in memory
|
||||
const amd::Coord3D& region, //!< The map region in memory
|
||||
uint mapFlags, //!< Map flags
|
||||
size_t* rowPitch = NULL, //!< Row pitch for the mapped memory
|
||||
size_t* slicePitch = NULL //!< Slice for the mapped memory
|
||||
);
|
||||
//! Allocate memory for API-level maps
|
||||
virtual void* allocMapTarget(const amd::Coord3D& origin, //!< The map location in memory
|
||||
const amd::Coord3D& region, //!< The map region in memory
|
||||
uint mapFlags, //!< Map flags
|
||||
size_t* rowPitch = NULL, //!< Row pitch for the mapped memory
|
||||
size_t* slicePitch = NULL //!< Slice for the mapped memory
|
||||
);
|
||||
|
||||
//! Pins system memory associated with this memory object
|
||||
virtual bool pinSystemMemory(
|
||||
void* hostPtr, //!< System memory address
|
||||
size_t size //!< Size of allocated system memory
|
||||
);
|
||||
//! Pins system memory associated with this memory object
|
||||
virtual bool pinSystemMemory(void* hostPtr, //!< System memory address
|
||||
size_t size //!< Size of allocated system memory
|
||||
);
|
||||
|
||||
//! Releases indirect map surface
|
||||
virtual void releaseIndirectMap() { decIndMapCount(); }
|
||||
//! Releases indirect map surface
|
||||
virtual void releaseIndirectMap() { decIndMapCount(); }
|
||||
|
||||
//! Map the device memory to CPU visible
|
||||
virtual void* cpuMap(
|
||||
device::VirtualDevice& vDev,//!< Virtual device for map operaiton
|
||||
uint flags = 0, //!< flags for the map operation
|
||||
// Optimization for multilayer map/unmap
|
||||
uint startLayer = 0, //!< Start layer for multilayer map
|
||||
uint numLayers = 0, //!< End layer for multilayer map
|
||||
size_t* rowPitch = NULL, //!< Row pitch for the device memory
|
||||
size_t* slicePitch = NULL //!< Slice pitch for the device memory
|
||||
);
|
||||
//! Map the device memory to CPU visible
|
||||
virtual void* cpuMap(device::VirtualDevice& vDev, //!< Virtual device for map operaiton
|
||||
uint flags = 0, //!< flags for the map operation
|
||||
// Optimization for multilayer map/unmap
|
||||
uint startLayer = 0, //!< Start layer for multilayer map
|
||||
uint numLayers = 0, //!< End layer for multilayer map
|
||||
size_t* rowPitch = NULL, //!< Row pitch for the device memory
|
||||
size_t* slicePitch = NULL //!< Slice pitch for the device memory
|
||||
);
|
||||
|
||||
//! Unmap the device memory
|
||||
virtual void cpuUnmap(
|
||||
device::VirtualDevice& vDev //!< Virtual device for unmap operaiton
|
||||
);
|
||||
//! Unmap the device memory
|
||||
virtual void cpuUnmap(device::VirtualDevice& vDev //!< Virtual device for unmap operaiton
|
||||
);
|
||||
|
||||
//! Updates device memory from the owner's host allocation
|
||||
void syncCacheFromHost(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
//! Synchronization flags
|
||||
device::Memory::SyncFlags syncFlags = device::Memory::SyncFlags()
|
||||
);
|
||||
//! Updates device memory from the owner's host allocation
|
||||
void syncCacheFromHost(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
//! Synchronization flags
|
||||
device::Memory::SyncFlags syncFlags = device::Memory::SyncFlags());
|
||||
|
||||
//! Updates the owner's host allocation from device memory
|
||||
virtual void syncHostFromCache(
|
||||
//! Synchronization flags
|
||||
device::Memory::SyncFlags syncFlags = device::Memory::SyncFlags()
|
||||
);
|
||||
//! Updates the owner's host allocation from device memory
|
||||
virtual void syncHostFromCache(
|
||||
//! Synchronization flags
|
||||
device::Memory::SyncFlags syncFlags = device::Memory::SyncFlags());
|
||||
|
||||
//! Creates a view from current resource
|
||||
virtual Memory* createBufferView(
|
||||
amd::Memory& subBufferOwner //!< The abstraction layer subbuf owner
|
||||
);
|
||||
//! Creates a view from current resource
|
||||
virtual Memory* createBufferView(
|
||||
amd::Memory& subBufferOwner //!< The abstraction layer subbuf owner
|
||||
);
|
||||
|
||||
//! Allocates host memory for synchronization with MGPU context
|
||||
void mgpuCacheWriteBack();
|
||||
//! Allocates host memory for synchronization with MGPU context
|
||||
void mgpuCacheWriteBack();
|
||||
|
||||
//! Transfers objects data to the destination object
|
||||
bool moveTo(Memory& dst);
|
||||
//! Transfers objects data to the destination object
|
||||
bool moveTo(Memory& dst);
|
||||
|
||||
//! Accessors for indirect map memory object
|
||||
Memory* mapMemory() const;
|
||||
//! Accessors for indirect map memory object
|
||||
Memory* mapMemory() const;
|
||||
|
||||
//! Returns the interop memory for this memory object
|
||||
Memory* interop() const { return interopMemory_; }
|
||||
//! Returns the interop memory for this memory object
|
||||
Memory* interop() const { return interopMemory_; }
|
||||
|
||||
//! Gets interop type for this memory object
|
||||
InteropType interopType() const { return interopType_; }
|
||||
//! Gets interop type for this memory object
|
||||
InteropType interopType() const { return interopType_; }
|
||||
|
||||
//! Sets interop type for this memory object
|
||||
void setInteropType(InteropType type) { interopType_ = type; }
|
||||
//! Sets interop type for this memory object
|
||||
void setInteropType(InteropType type) { interopType_ = type; }
|
||||
|
||||
//! Set the owner
|
||||
void setOwner(amd::Memory* owner) { owner_ = owner; }
|
||||
//! Set the owner
|
||||
void setOwner(amd::Memory* owner) { owner_ = owner; }
|
||||
|
||||
// Decompress GL depth-stencil/MSAA resources for CL access
|
||||
// Invalidates any FBOs the resource may be bound to, otherwise the GL driver may crash.
|
||||
virtual bool processGLResource(GLResourceOP operation);
|
||||
// Decompress GL depth-stencil/MSAA resources for CL access
|
||||
// Invalidates any FBOs the resource may be bound to, otherwise the GL driver may crash.
|
||||
virtual bool processGLResource(GLResourceOP operation);
|
||||
|
||||
//! Returns the interop resource for this memory object
|
||||
const Memory* parent() const { return parent_; }
|
||||
//! Returns the interop resource for this memory object
|
||||
const Memory* parent() const { return parent_; }
|
||||
|
||||
//! Returns TRUE if direct map is acceaptable. The method detects
|
||||
//! forced USWC memory on APU and will cause a switch to
|
||||
//! indirect map for allocations with a possibility of host read
|
||||
bool isDirectMap()
|
||||
{
|
||||
return (isCacheable() || !isHostMemDirectAccess() ||
|
||||
//! Returns TRUE if direct map is acceaptable. The method detects
|
||||
//! forced USWC memory on APU and will cause a switch to
|
||||
//! indirect map for allocations with a possibility of host read
|
||||
bool isDirectMap() {
|
||||
return (isCacheable() || !isHostMemDirectAccess() ||
|
||||
(owner()->getMemFlags() &
|
||||
(CL_MEM_ALLOC_HOST_PTR | CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY)));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Decrement map count
|
||||
void decIndMapCount();
|
||||
protected:
|
||||
//! Decrement map count
|
||||
void decIndMapCount();
|
||||
|
||||
//! Initialize the object members
|
||||
void init();
|
||||
//! Initialize the object members
|
||||
void init();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Memory(const Memory&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Memory(const Memory&);
|
||||
|
||||
//! Disable operator=
|
||||
Memory& operator=(const Memory&);
|
||||
//! Disable operator=
|
||||
Memory& operator=(const Memory&);
|
||||
|
||||
InteropType interopType_; //!< Interop type
|
||||
Memory* interopMemory_; //!< interop memory
|
||||
InteropType interopType_; //!< Interop type
|
||||
Memory* interopMemory_; //!< interop memory
|
||||
|
||||
Memory* pinnedMemory_; //!< Memory used as pinned system memory
|
||||
const Memory* parent_; //!< Parent memory object
|
||||
Memory* pinnedMemory_; //!< Memory used as pinned system memory
|
||||
const Memory* parent_; //!< Parent memory object
|
||||
};
|
||||
|
||||
class Buffer: public gpu::Memory
|
||||
{
|
||||
public:
|
||||
//! Buffer constructor
|
||||
Buffer(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t size //!< Buffer size
|
||||
)
|
||||
: gpu::Memory(gpuDev, owner,
|
||||
amd::alignUp(size, ElementSize) / ElementSize, ElementType)
|
||||
{}
|
||||
class Buffer : public gpu::Memory {
|
||||
public:
|
||||
//! Buffer constructor
|
||||
Buffer(const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t size //!< Buffer size
|
||||
)
|
||||
: gpu::Memory(gpuDev, owner, amd::alignUp(size, ElementSize) / ElementSize, ElementType) {}
|
||||
|
||||
//! Creates a view from current resource
|
||||
virtual Memory* createBufferView(
|
||||
amd::Memory& subBufferOwner //!< The abstraction layer subbuf owner
|
||||
) const;
|
||||
//! Creates a view from current resource
|
||||
virtual Memory* createBufferView(
|
||||
amd::Memory& subBufferOwner //!< The abstraction layer subbuf owner
|
||||
) const;
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Buffer(const Buffer&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Buffer(const Buffer&);
|
||||
|
||||
//! Disable operator=
|
||||
Buffer& operator=(const Buffer&);
|
||||
//! Disable operator=
|
||||
Buffer& operator=(const Buffer&);
|
||||
|
||||
//! The size of buffer element in bytes
|
||||
static const size_t ElementSize = 4;
|
||||
//! The size of buffer element in bytes
|
||||
static const size_t ElementSize = 4;
|
||||
|
||||
//! The type of buffer element
|
||||
static const cmSurfFmt ElementType = CM_SURF_FMT_R32I;
|
||||
//! The type of buffer element
|
||||
static const cmSurfFmt ElementType = CM_SURF_FMT_R32I;
|
||||
};
|
||||
|
||||
class Image: public gpu::Memory
|
||||
{
|
||||
public:
|
||||
//! Image constructor
|
||||
Image(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
class Image : public gpu::Memory {
|
||||
public:
|
||||
//! Image constructor
|
||||
Image(const Device& gpuDev, //!< GPU device object
|
||||
amd::Memory& owner, //!< Abstraction layer memory object
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
)
|
||||
: gpu::Memory(gpuDev, owner, width, height, depth, format, chOrder, imageType, mipLevels)
|
||||
{}
|
||||
: gpu::Memory(gpuDev, owner, width, height, depth, format, chOrder, imageType, mipLevels) {}
|
||||
|
||||
//! Image constructor
|
||||
Image(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
size_t size, //!< Memory size
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
//! Image constructor
|
||||
Image(const Device& gpuDev, //!< GPU device object
|
||||
size_t size, //!< Memory size
|
||||
size_t width, //!< Allocated memory width
|
||||
size_t height, //!< Allocated memory height
|
||||
size_t depth, //!< Allocated memory depth
|
||||
cmSurfFmt format, //!< Memory format
|
||||
gslChannelOrder chOrder, //!< Channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels //!< The number of mip levels
|
||||
)
|
||||
: gpu::Memory(gpuDev, size, width, height, depth, format, chOrder, imageType, mipLevels)
|
||||
{}
|
||||
: gpu::Memory(gpuDev, size, width, height, depth, format, chOrder, imageType, mipLevels) {}
|
||||
|
||||
//! Allocate memory for API-level maps
|
||||
virtual void* allocMapTarget(
|
||||
const amd::Coord3D& origin, //!< The map location in memory
|
||||
const amd::Coord3D& region, //!< The map region in memory
|
||||
uint mapFlags, //!< Map flags
|
||||
size_t* rowPitch = NULL, //!< Row pitch for the mapped memory
|
||||
size_t* slicePitch = NULL //!< Slice for the mapped memory
|
||||
);
|
||||
//! Allocate memory for API-level maps
|
||||
virtual void* allocMapTarget(const amd::Coord3D& origin, //!< The map location in memory
|
||||
const amd::Coord3D& region, //!< The map region in memory
|
||||
uint mapFlags, //!< Map flags
|
||||
size_t* rowPitch = NULL, //!< Row pitch for the mapped memory
|
||||
size_t* slicePitch = NULL //!< Slice for the mapped memory
|
||||
);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Image(const Image&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Image(const Image&);
|
||||
|
||||
//! Disable operator=
|
||||
Image& operator=(const Image&);
|
||||
//! Disable operator=
|
||||
Image& operator=(const Image&);
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUMEMORY_HPP_
|
||||
#endif // GPUMEMORY_HPP_
|
||||
File diff suppressed because it is too large.
Load diff
@@ -12,182 +12,159 @@
|
||||
#ifndef isinf
|
||||
#ifdef _MSC_VER
|
||||
#define isinf(X) (!_finite(X) && !_isnan(X))
|
||||
#endif //_MSC_VER
|
||||
#endif //isinf
|
||||
#endif //_MSC_VER
|
||||
#endif // isinf
|
||||
|
||||
#ifndef isnan
|
||||
#ifdef _MSC_VER
|
||||
#define isnan(X) (_isnan(X))
|
||||
#endif //_MSC_VER
|
||||
#endif //isnan
|
||||
#endif //_MSC_VER
|
||||
#endif // isnan
|
||||
|
||||
#ifndef copysign
|
||||
#ifdef _MSC_VER
|
||||
#define copysign(X,Y) (_copysign(X,Y))
|
||||
#endif //_MSC_VER
|
||||
#endif //copysign
|
||||
#define copysign(X, Y) (_copysign(X, Y))
|
||||
#endif //_MSC_VER
|
||||
#endif // copysign
|
||||
|
||||
//! GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
//! Printf info structure
|
||||
struct PrintfInfo
|
||||
{
|
||||
std::string fmtString_; //!< formated string for printf
|
||||
std::vector<uint> arguments_; //!< passed arguments to the printf() call
|
||||
struct PrintfInfo {
|
||||
std::string fmtString_; //!< formated string for printf
|
||||
std::vector<uint> arguments_; //!< passed arguments to the printf() call
|
||||
};
|
||||
|
||||
class Kernel;
|
||||
class VirtualGPU;
|
||||
class Memory;
|
||||
|
||||
class PrintfDbg : public amd::HeapObject
|
||||
{
|
||||
public:
|
||||
//! Debug buffer size per workitem
|
||||
static const uint WorkitemDebugSize = 4096;
|
||||
class PrintfDbg : public amd::HeapObject {
|
||||
public:
|
||||
//! Debug buffer size per workitem
|
||||
static const uint WorkitemDebugSize = 4096;
|
||||
|
||||
//! Default constructor
|
||||
PrintfDbg(
|
||||
Device& device,
|
||||
FILE* file = NULL
|
||||
);
|
||||
//! Default constructor
|
||||
PrintfDbg(Device& device, FILE* file = NULL);
|
||||
|
||||
//! Destructor
|
||||
~PrintfDbg();
|
||||
//! Destructor
|
||||
~PrintfDbg();
|
||||
|
||||
//! Creates the PrintfDbg object
|
||||
bool create();
|
||||
//! Creates the PrintfDbg object
|
||||
bool create();
|
||||
|
||||
//! Initializes the debug buffer before kernel's execution
|
||||
bool init(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const amd::NDRange& size //!< Kernel's workload
|
||||
);
|
||||
//! Initializes the debug buffer before kernel's execution
|
||||
bool init(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const amd::NDRange& size //!< Kernel's workload
|
||||
);
|
||||
|
||||
//! Prints the kernel's debug informaiton from the buffer
|
||||
bool output(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const amd::NDRange& size, //!< Kernel's workload
|
||||
const std::vector<PrintfInfo>& printfInfo //!< printf info
|
||||
);
|
||||
//! Prints the kernel's debug informaiton from the buffer
|
||||
bool output(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const amd::NDRange& size, //!< Kernel's workload
|
||||
const std::vector<PrintfInfo>& printfInfo //!< printf info
|
||||
);
|
||||
|
||||
//! Returns the debug buffer offset
|
||||
uint64_t bufOffset() const;
|
||||
//! Returns the debug buffer offset
|
||||
uint64_t bufOffset() const;
|
||||
|
||||
//! Debug buffer size per workitem
|
||||
size_t wiDbgSize() const { return wiDbgSize_; }
|
||||
//! Debug buffer size per workitem
|
||||
size_t wiDbgSize() const { return wiDbgSize_; }
|
||||
|
||||
//! Returns debug buffer object
|
||||
Memory* dbgBuffer() const { return dbgBuffer_; }
|
||||
//! Returns debug buffer object
|
||||
Memory* dbgBuffer() const { return dbgBuffer_; }
|
||||
|
||||
protected:
|
||||
Memory* dbgBuffer_; //!< Buffer to hold debug output
|
||||
FILE* dbgFile_; //!< Debug file
|
||||
Device& gpuDevice_; //!< GPU device object
|
||||
Memory* xferBufRead_; //!< Transfer buffer for the dump read
|
||||
protected:
|
||||
Memory* dbgBuffer_; //!< Buffer to hold debug output
|
||||
FILE* dbgFile_; //!< Debug file
|
||||
Device& gpuDevice_; //!< GPU device object
|
||||
Memory* xferBufRead_; //!< Transfer buffer for the dump read
|
||||
|
||||
//! Gets GPU device object
|
||||
Device& dev() const { return gpuDevice_; }
|
||||
//! Gets GPU device object
|
||||
Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Allocates the debug buffer
|
||||
bool allocate(
|
||||
bool realloc = false //!< If TRUE then reallocate the debug memory
|
||||
);
|
||||
//! Allocates the debug buffer
|
||||
bool allocate(bool realloc = false //!< If TRUE then reallocate the debug memory
|
||||
);
|
||||
|
||||
//! Returns TRUE if a float value has to be printed
|
||||
bool checkFloat(
|
||||
const std::string& fmt //!< Format string
|
||||
) const;
|
||||
//! Returns TRUE if a float value has to be printed
|
||||
bool checkFloat(const std::string& fmt //!< Format string
|
||||
) const;
|
||||
|
||||
//! Returns TRUE if a string value has to be printed
|
||||
bool checkString(
|
||||
const std::string& fmt //!< Format string
|
||||
) const;
|
||||
//! Returns TRUE if a string value has to be printed
|
||||
bool checkString(const std::string& fmt //!< Format string
|
||||
) const;
|
||||
|
||||
//! Finds the specifier in the format string
|
||||
int checkVectorSpecifier(
|
||||
const std::string& fmt, //!< Format string
|
||||
size_t startPos, //!< Start position for processing
|
||||
size_t& curPos //!< End position for processing
|
||||
) const;
|
||||
//! Finds the specifier in the format string
|
||||
int checkVectorSpecifier(const std::string& fmt, //!< Format string
|
||||
size_t startPos, //!< Start position for processing
|
||||
size_t& curPos //!< End position for processing
|
||||
) const;
|
||||
|
||||
//! Outputs an argument
|
||||
size_t outputArgument(
|
||||
const std::string& fmt, //!< Format strint
|
||||
bool printFloat, //!< Argument is a float value
|
||||
size_t size, //!< Argument's size
|
||||
const uint32_t* argument //!< Argument's location
|
||||
) const;
|
||||
//! Outputs an argument
|
||||
size_t outputArgument(const std::string& fmt, //!< Format strint
|
||||
bool printFloat, //!< Argument is a float value
|
||||
size_t size, //!< Argument's size
|
||||
const uint32_t* argument //!< Argument's location
|
||||
) const;
|
||||
|
||||
//! Displays the PrintfDbg
|
||||
void outputDbgBuffer(
|
||||
const PrintfInfo& info, //!< printf info
|
||||
const uint32_t* workitemData, //!< The PrintfDbg dump buffer
|
||||
size_t& i //!< index to the data in the buffer
|
||||
) const;
|
||||
//! Displays the PrintfDbg
|
||||
void outputDbgBuffer(const PrintfInfo& info, //!< printf info
|
||||
const uint32_t* workitemData, //!< The PrintfDbg dump buffer
|
||||
size_t& i //!< index to the data in the buffer
|
||||
) const;
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
PrintfDbg(const PrintfDbg&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
PrintfDbg(const PrintfDbg&);
|
||||
|
||||
//! Disable assignment
|
||||
PrintfDbg& operator=(const PrintfDbg&);
|
||||
//! Disable assignment
|
||||
PrintfDbg& operator=(const PrintfDbg&);
|
||||
|
||||
//! Returns the pointer to the workitem data block
|
||||
bool clearWorkitems(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
size_t idxStart, //!< Workitem global index start
|
||||
size_t number //!< Number of workitems to clear
|
||||
) const;
|
||||
//! Returns the pointer to the workitem data block
|
||||
bool clearWorkitems(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
size_t idxStart, //!< Workitem global index start
|
||||
size_t number //!< Number of workitems to clear
|
||||
) const;
|
||||
|
||||
//! Returns the pointer to the workitem data block
|
||||
uint32_t* mapWorkitem(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
size_t idx, //!< Workitem global index
|
||||
bool* realloc //!< Returns TRUE if workitem reached the buffer limit
|
||||
);
|
||||
//! Returns the pointer to the workitem data block
|
||||
uint32_t* mapWorkitem(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
size_t idx, //!< Workitem global index
|
||||
bool* realloc //!< Returns TRUE if workitem reached the buffer limit
|
||||
);
|
||||
|
||||
//! Unamp the staged buffer
|
||||
void unmapWorkitem(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
const uint32_t* workitemData //!< The PrintfDbg dump buffer
|
||||
) const;
|
||||
//! Unamp the staged buffer
|
||||
void unmapWorkitem(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
const uint32_t* workitemData //!< The PrintfDbg dump buffer
|
||||
) const;
|
||||
|
||||
size_t wiDbgSize_; //!< Workitem debug size
|
||||
Memory initCntValue_; //!< Initialized count value
|
||||
size_t wiDbgSize_; //!< Workitem debug size
|
||||
Memory initCntValue_; //!< Initialized count value
|
||||
};
|
||||
class PrintfDbgHSA : public PrintfDbg
|
||||
{
|
||||
public:
|
||||
class PrintfDbgHSA : public PrintfDbg {
|
||||
public:
|
||||
//! Default constructor
|
||||
PrintfDbgHSA(Device& device, FILE* file = NULL) : PrintfDbg(device, file) {}
|
||||
|
||||
//! Default constructor
|
||||
PrintfDbgHSA(
|
||||
Device& device,
|
||||
FILE* file = NULL
|
||||
): PrintfDbg(device, file) { }
|
||||
//! Initializes the debug buffer before kernel's execution
|
||||
bool init(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled //!< checks for printf
|
||||
);
|
||||
|
||||
//! Initializes the debug buffer before kernel's execution
|
||||
bool init(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled //!< checks for printf
|
||||
);
|
||||
//! Prints the kernel's debug informaiton from the buffer
|
||||
bool output(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const std::vector<PrintfInfo>& printfInfo //!< printf info
|
||||
);
|
||||
|
||||
//! Prints the kernel's debug informaiton from the buffer
|
||||
bool output(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const std::vector<PrintfInfo>& printfInfo //!< printf info
|
||||
);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
PrintfDbgHSA(const PrintfDbgHSA&);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
PrintfDbgHSA(const PrintfDbgHSA&);
|
||||
|
||||
//! Disable assignment
|
||||
PrintfDbgHSA& operator=(const PrintfDbgHSA&);
|
||||
//! Disable assignment
|
||||
PrintfDbgHSA& operator=(const PrintfDbgHSA&);
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -19,483 +19,453 @@ class VirtualGPU;
|
||||
* @{
|
||||
*/
|
||||
|
||||
class GslResourceReference : public amd::ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
GslResourceReference(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
gslMemObject gslResource, //!< CAL resource
|
||||
gslMemObject gslResOriginal = NULL //!< Original CAL resource
|
||||
);
|
||||
class GslResourceReference : public amd::ReferenceCountedObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
GslResourceReference(const Device& gpuDev, //!< GPU device object
|
||||
gslMemObject gslResource, //!< CAL resource
|
||||
gslMemObject gslResOriginal = NULL //!< Original CAL resource
|
||||
);
|
||||
|
||||
//! Get CAL resource
|
||||
gslMemObject gslResource() const { return resource_; }
|
||||
//! Get CAL resource
|
||||
gslMemObject gslResource() const { return resource_; }
|
||||
|
||||
//! Original CAL resource
|
||||
gslMemObject gslOriginal() const { return (resOriginal_ == 0) ? resource_ : resOriginal_; }
|
||||
//! Original CAL resource
|
||||
gslMemObject gslOriginal() const { return (resOriginal_ == 0) ? resource_ : resOriginal_; }
|
||||
|
||||
const Device& device_; //!< GPU device
|
||||
gslMemObject resource_; //!< GSL resource object
|
||||
gslMemObject resOriginal_; //!< Original resource object, NULL if no channel order
|
||||
void* cpuAddress_; //!< CPU address of this memory
|
||||
const Device& device_; //!< GPU device
|
||||
gslMemObject resource_; //!< GSL resource object
|
||||
gslMemObject resOriginal_; //!< Original resource object, NULL if no channel order
|
||||
void* cpuAddress_; //!< CPU address of this memory
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~GslResourceReference();
|
||||
protected:
|
||||
//! Default destructor
|
||||
~GslResourceReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
GslResourceReference(const GslResourceReference&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
GslResourceReference(const GslResourceReference&);
|
||||
|
||||
//! Disable operator=
|
||||
GslResourceReference& operator=(const GslResourceReference&);
|
||||
//! Disable operator=
|
||||
GslResourceReference& operator=(const GslResourceReference&);
|
||||
};
|
||||
|
||||
//! GPU resource
|
||||
class Resource : public amd::HeapObject
|
||||
{
|
||||
public:
|
||||
enum InteropType {
|
||||
InteropTypeless = 0,
|
||||
InteropVertexBuffer,
|
||||
InteropIndexBuffer,
|
||||
InteropRenderBuffer,
|
||||
InteropTexture,
|
||||
InteropTextureViewLevel,
|
||||
InteropTextureViewCube,
|
||||
InteropSurface
|
||||
};
|
||||
class Resource : public amd::HeapObject {
|
||||
public:
|
||||
enum InteropType {
|
||||
InteropTypeless = 0,
|
||||
InteropVertexBuffer,
|
||||
InteropIndexBuffer,
|
||||
InteropRenderBuffer,
|
||||
InteropTexture,
|
||||
InteropTextureViewLevel,
|
||||
InteropTextureViewCube,
|
||||
InteropSurface
|
||||
};
|
||||
|
||||
struct CreateParams : public amd::StackObject {
|
||||
amd::Memory* owner_; //!< Resource's owner
|
||||
VirtualGPU* gpu_; //!< Resource won't be shared between multiple queues
|
||||
CreateParams(): owner_(NULL), gpu_(NULL) {}
|
||||
};
|
||||
struct CreateParams : public amd::StackObject {
|
||||
amd::Memory* owner_; //!< Resource's owner
|
||||
VirtualGPU* gpu_; //!< Resource won't be shared between multiple queues
|
||||
CreateParams() : owner_(NULL), gpu_(NULL) {}
|
||||
};
|
||||
|
||||
struct PinnedParams : public CreateParams {
|
||||
const amd::HostMemoryReference* hostMemRef_;//!< System memory pointer for pinning
|
||||
size_t size_; //!< System memory size
|
||||
};
|
||||
struct PinnedParams : public CreateParams {
|
||||
const amd::HostMemoryReference* hostMemRef_; //!< System memory pointer for pinning
|
||||
size_t size_; //!< System memory size
|
||||
};
|
||||
|
||||
struct ViewParams : public CreateParams {
|
||||
size_t offset_; //!< Alias resource offset
|
||||
size_t size_; //!< Alias resource size
|
||||
const Resource* resource_; //!< Parent resource for the view creation
|
||||
const void* memory_;
|
||||
};
|
||||
struct ViewParams : public CreateParams {
|
||||
size_t offset_; //!< Alias resource offset
|
||||
size_t size_; //!< Alias resource size
|
||||
const Resource* resource_; //!< Parent resource for the view creation
|
||||
const void* memory_;
|
||||
};
|
||||
|
||||
struct ImageViewParams : public CreateParams {
|
||||
size_t level_; //!< Image mip level for a new view
|
||||
size_t layer_; //!< Image layer for a new view
|
||||
const Resource* resource_; //!< Parent resource for the view creation
|
||||
const void* memory_;
|
||||
};
|
||||
struct ImageViewParams : public CreateParams {
|
||||
size_t level_; //!< Image mip level for a new view
|
||||
size_t layer_; //!< Image layer for a new view
|
||||
const Resource* resource_; //!< Parent resource for the view creation
|
||||
const void* memory_;
|
||||
};
|
||||
|
||||
struct ImageBufferParams : public CreateParams {
|
||||
const Resource* resource_; //!< Parent resource for the image creation
|
||||
const void* memory_;
|
||||
};
|
||||
struct ImageBufferParams : public CreateParams {
|
||||
const Resource* resource_; //!< Parent resource for the image creation
|
||||
const void* memory_;
|
||||
};
|
||||
|
||||
struct OGLInteropParams : public CreateParams {
|
||||
InteropType type_; //!< OGL resource type
|
||||
CALuint handle_; //!< OGL resource handle
|
||||
uint mipLevel_; //!< Texture mip level
|
||||
uint layer_; //!< Texture layer
|
||||
void* glPlatformContext_;
|
||||
void* glDeviceContext_;
|
||||
uint flags_;
|
||||
};
|
||||
struct OGLInteropParams : public CreateParams {
|
||||
InteropType type_; //!< OGL resource type
|
||||
CALuint handle_; //!< OGL resource handle
|
||||
uint mipLevel_; //!< Texture mip level
|
||||
uint layer_; //!< Texture layer
|
||||
void* glPlatformContext_;
|
||||
void* glDeviceContext_;
|
||||
uint flags_;
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
struct D3DInteropParams : public CreateParams {
|
||||
InteropType type_; //!< D3D resource type
|
||||
void* iDirect3D_; //!< D3D resource interface object
|
||||
HANDLE handle_; //!< D3D resource handle
|
||||
uint mipLevel_; //!< Texture mip level
|
||||
int layer_; //!< Texture layer
|
||||
uint misc; //!< miscellaneous cases
|
||||
struct D3DInteropParams : public CreateParams {
|
||||
InteropType type_; //!< D3D resource type
|
||||
void* iDirect3D_; //!< D3D resource interface object
|
||||
HANDLE handle_; //!< D3D resource handle
|
||||
uint mipLevel_; //!< Texture mip level
|
||||
int layer_; //!< Texture layer
|
||||
uint misc; //!< miscellaneous cases
|
||||
};
|
||||
#endif // _WIN32
|
||||
|
||||
//! Resource memory
|
||||
enum MemoryType {
|
||||
Empty = 0x0, //!< resource is empty
|
||||
Local, //!< resource in local memory
|
||||
Persistent, //!< resource in persistent memory
|
||||
Remote, //!< resource in nonlocal memory
|
||||
RemoteUSWC, //!< resource in nonlocal memory
|
||||
Pinned, //!< resource in pinned system memory
|
||||
View, //!< resource is an alias
|
||||
OGLInterop, //!< resource is an OGL memory object
|
||||
D3D10Interop, //!< resource is a D3D10 memory object
|
||||
D3D11Interop, //!< resource is a D3D11 memory object
|
||||
Heap, //!< resource is a heap
|
||||
ImageView, //!< resource is a view to some image
|
||||
ImageBuffer, //!< resource is an image view of a buffer
|
||||
BusAddressable, //!< resource is a bus addressable memory
|
||||
ExternalPhysical, //!< resource is an external physical memory
|
||||
D3D9Interop, //!< resource is a D3D9 memory object
|
||||
Scratch, //!< resource is scratch memory
|
||||
Shader, //!< resource is a shader
|
||||
};
|
||||
|
||||
//! Resource map flags
|
||||
enum MapFlags {
|
||||
Discard = 0x00000001, //!< discard lock
|
||||
NoOverwrite = 0x00000002, //!< lock with no overwrite
|
||||
ReadOnly = 0x00000004, //!< lock for read only operation
|
||||
WriteOnly = 0x00000008, //!< lock for write only operation
|
||||
NoWait = 0x00000010, //!< lock with no wait
|
||||
};
|
||||
|
||||
//! CAL resource descriptor
|
||||
struct CalResourceDesc : public amd::HeapObject {
|
||||
MemoryType type_; //!< Memory type
|
||||
size_t width_; //!< CAL resource width
|
||||
size_t height_; //!< CAL resource height
|
||||
size_t depth_; //!< CAL resource depth
|
||||
uint mipLevels_; //!< Number of mip levels
|
||||
cmSurfFmt format_; //!< GSL resource format
|
||||
CALuint flags_; //!< CAL resource flags, used in creation
|
||||
size_t pitch_; //!< CAL resource pitch, valid if locked
|
||||
CALuint slice_; //!< CAL resource slice, valid if locked
|
||||
gslChannelOrder channelOrder_; //!< GSL resource channel order
|
||||
gslMemObjectAttribType dimension_; //!< GSL resource dimension
|
||||
cl_mem_object_type imageType_; //!< CL image type
|
||||
union {
|
||||
struct {
|
||||
uint dimSize_ : 2; //!< Dimension size
|
||||
uint cardMemory_ : 1; //!< GSL resource is in video memory
|
||||
uint imageArray_ : 1; //!< GSL resource is an array of images
|
||||
uint buffer_ : 1; //!< GSL resource is a buffer
|
||||
uint tiled_ : 1; //!< GSL resource is tiled
|
||||
uint scratch_ : 1; //!< Scratch buffer
|
||||
uint skipRsrcCache_ : 1; //!< Skip caching of a cal resource
|
||||
uint isAllocSVM_ : 1; //!< SVM resource attribute
|
||||
uint isAllocExecute_ : 1; //!< SVM resource allocation attribute for shader\cmdbuf
|
||||
};
|
||||
uint state_;
|
||||
};
|
||||
#endif // _WIN32
|
||||
};
|
||||
|
||||
//! Resource memory
|
||||
enum MemoryType
|
||||
{
|
||||
Empty = 0x0, //!< resource is empty
|
||||
Local, //!< resource in local memory
|
||||
Persistent, //!< resource in persistent memory
|
||||
Remote, //!< resource in nonlocal memory
|
||||
RemoteUSWC, //!< resource in nonlocal memory
|
||||
Pinned, //!< resource in pinned system memory
|
||||
View, //!< resource is an alias
|
||||
OGLInterop, //!< resource is an OGL memory object
|
||||
D3D10Interop, //!< resource is a D3D10 memory object
|
||||
D3D11Interop, //!< resource is a D3D11 memory object
|
||||
Heap, //!< resource is a heap
|
||||
ImageView, //!< resource is a view to some image
|
||||
ImageBuffer, //!< resource is an image view of a buffer
|
||||
BusAddressable, //!< resource is a bus addressable memory
|
||||
ExternalPhysical, //!< resource is an external physical memory
|
||||
D3D9Interop, //!< resource is a D3D9 memory object
|
||||
Scratch, //!< resource is scratch memory
|
||||
Shader, //!< resource is a shader
|
||||
};
|
||||
//! Constructor of 1D Resource object
|
||||
Resource(const Device& gpuDev, //!< GPU device object
|
||||
size_t width, //!< resource width
|
||||
cmSurfFmt format //!< resource format
|
||||
);
|
||||
|
||||
//! Resource map flags
|
||||
enum MapFlags
|
||||
{
|
||||
Discard = 0x00000001, //!< discard lock
|
||||
NoOverwrite = 0x00000002, //!< lock with no overwrite
|
||||
ReadOnly = 0x00000004, //!< lock for read only operation
|
||||
WriteOnly = 0x00000008, //!< lock for write only operation
|
||||
NoWait = 0x00000010, //!< lock with no wait
|
||||
};
|
||||
//! Constructor of Image Resource object
|
||||
Resource(const Device& gpuDev, //!< GPU device object
|
||||
size_t width, //!< resource width
|
||||
size_t height, //!< resource height
|
||||
size_t depth, //!< resource depth
|
||||
cmSurfFmt format, //!< resource format
|
||||
gslChannelOrder chOrder, //!< resource channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels = 1 //!< Number of mip levels
|
||||
);
|
||||
|
||||
//! CAL resource descriptor
|
||||
struct CalResourceDesc : public amd::HeapObject
|
||||
{
|
||||
MemoryType type_; //!< Memory type
|
||||
size_t width_; //!< CAL resource width
|
||||
size_t height_; //!< CAL resource height
|
||||
size_t depth_; //!< CAL resource depth
|
||||
uint mipLevels_; //!< Number of mip levels
|
||||
cmSurfFmt format_; //!< GSL resource format
|
||||
CALuint flags_; //!< CAL resource flags, used in creation
|
||||
size_t pitch_; //!< CAL resource pitch, valid if locked
|
||||
CALuint slice_; //!< CAL resource slice, valid if locked
|
||||
gslChannelOrder channelOrder_; //!< GSL resource channel order
|
||||
gslMemObjectAttribType dimension_; //!< GSL resource dimension
|
||||
cl_mem_object_type imageType_; //!< CL image type
|
||||
union {
|
||||
struct {
|
||||
uint dimSize_ : 2; //!< Dimension size
|
||||
uint cardMemory_ : 1; //!< GSL resource is in video memory
|
||||
uint imageArray_ : 1; //!< GSL resource is an array of images
|
||||
uint buffer_ : 1; //!< GSL resource is a buffer
|
||||
uint tiled_ : 1; //!< GSL resource is tiled
|
||||
uint scratch_ : 1; //!< Scratch buffer
|
||||
uint skipRsrcCache_ : 1; //!< Skip caching of a cal resource
|
||||
uint isAllocSVM_ : 1; //!< SVM resource attribute
|
||||
uint isAllocExecute_ : 1; //!< SVM resource allocation attribute for shader\cmdbuf
|
||||
};
|
||||
uint state_;
|
||||
};
|
||||
};
|
||||
//! Destructor of the resource
|
||||
virtual ~Resource();
|
||||
|
||||
//! Constructor of 1D Resource object
|
||||
Resource(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
size_t width, //!< resource width
|
||||
cmSurfFmt format //!< resource format
|
||||
);
|
||||
/*! \brief Creates a CAL object, associated with the resource
|
||||
*
|
||||
* \return True if we succesfully created a CAL resource
|
||||
*/
|
||||
virtual bool create(MemoryType memType, //!< memory type
|
||||
CreateParams* params = 0 //!< special parameters for resource allocation
|
||||
);
|
||||
|
||||
//! Constructor of Image Resource object
|
||||
Resource(
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
size_t width, //!< resource width
|
||||
size_t height, //!< resource height
|
||||
size_t depth, //!< resource depth
|
||||
cmSurfFmt format, //!< resource format
|
||||
gslChannelOrder chOrder, //!< resource channel order
|
||||
cl_mem_object_type imageType, //!< CL image type
|
||||
uint mipLevels = 1 //!< Number of mip levels
|
||||
);
|
||||
/*! \brief Copies a subregion of memory from one resource to another
|
||||
*
|
||||
* This is a general copy from anything to anything (as long as it fits).
|
||||
* All positions and sizes are given in bytes. Note, however, that only
|
||||
* a subset of this general interface is currently implemented.
|
||||
*
|
||||
* \return true if successful
|
||||
*/
|
||||
bool partialMemCopyTo(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
const amd::Coord3D& srcOrigin, //!< Origin of the source region
|
||||
const amd::Coord3D& dstOrigin, //!< Origin of the destination region
|
||||
const amd::Coord3D& size, //!< Size of the region to copy
|
||||
Resource& dstResource, //!< Destination resource
|
||||
bool enableRectCopy = false, //!< Rectangular DMA support
|
||||
bool flushDMA = false, //!< Flush DMA if requested
|
||||
uint bytesPerElement = 1 //!< Bytes Per Element
|
||||
) const;
|
||||
|
||||
//! Destructor of the resource
|
||||
virtual ~Resource();
|
||||
/*! \brief Copies size/4 DWORD of memory to a surface
|
||||
*
|
||||
* This is a raw copy to any surface using a CP packet.
|
||||
* Size needs to be atleast a DWORD or multiple
|
||||
*
|
||||
*/
|
||||
void writeRawData(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
size_t size, //!< Size in bytes of data to be copied(multiple of DWORDS)
|
||||
const void* data, //!< Data to be copied
|
||||
bool waitForEvent //!< Wait for event complete
|
||||
) const;
|
||||
|
||||
/*! \brief Creates a CAL object, associated with the resource
|
||||
*
|
||||
* \return True if we succesfully created a CAL resource
|
||||
*/
|
||||
virtual bool create(
|
||||
MemoryType memType, //!< memory type
|
||||
CreateParams* params = 0 //!< special parameters for resource allocation
|
||||
);
|
||||
//! Returns the offset in GPU memory for aliases
|
||||
size_t offset() const { return offset_; }
|
||||
|
||||
/*! \brief Copies a subregion of memory from one resource to another
|
||||
*
|
||||
* This is a general copy from anything to anything (as long as it fits).
|
||||
* All positions and sizes are given in bytes. Note, however, that only
|
||||
* a subset of this general interface is currently implemented.
|
||||
*
|
||||
* \return true if successful
|
||||
*/
|
||||
bool partialMemCopyTo(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
const amd::Coord3D& srcOrigin, //!< Origin of the source region
|
||||
const amd::Coord3D& dstOrigin, //!< Origin of the destination region
|
||||
const amd::Coord3D& size, //!< Size of the region to copy
|
||||
Resource& dstResource, //!< Destination resource
|
||||
bool enableRectCopy = false, //!< Rectangular DMA support
|
||||
bool flushDMA = false, //!< Flush DMA if requested
|
||||
uint bytesPerElement = 1 //!< Bytes Per Element
|
||||
) const;
|
||||
//! Returns the offset in GPU heap
|
||||
uint64_t hbOffset() const { return hbOffset_; }
|
||||
|
||||
/*! \brief Copies size/4 DWORD of memory to a surface
|
||||
*
|
||||
* This is a raw copy to any surface using a CP packet.
|
||||
* Size needs to be atleast a DWORD or multiple
|
||||
*
|
||||
*/
|
||||
void writeRawData(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
size_t size, //!< Size in bytes of data to be copied(multiple of DWORDS)
|
||||
const void* data, //!< Data to be copied
|
||||
bool waitForEvent //!< Wait for event complete
|
||||
) const;
|
||||
//! Returns the pinned memory offset
|
||||
uint64_t pinOffset() const { return pinOffset_; }
|
||||
|
||||
//! Returns the offset in GPU memory for aliases
|
||||
size_t offset() const { return offset_; }
|
||||
//! Returns the size in GPU heap
|
||||
uint64_t hbSize() const { return hbSize_; }
|
||||
|
||||
//! Returns the offset in GPU heap
|
||||
uint64_t hbOffset() const { return hbOffset_; }
|
||||
//! Returns the GPU device that owns this resource
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Returns the pinned memory offset
|
||||
uint64_t pinOffset() const { return pinOffset_; }
|
||||
//! Returns the CAL descriptor for resource
|
||||
const CalResourceDesc* cal() const { return &cal_; }
|
||||
|
||||
//! Returns the size in GPU heap
|
||||
uint64_t hbSize() const { return hbSize_; }
|
||||
//! Returns the CAL resource handle
|
||||
gslMemObject gslResource() const { return gslRef_->gslResource(); }
|
||||
|
||||
//! Returns the GPU device that owns this resource
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
//! Returns global memory offset
|
||||
uint64_t vmAddress() const { return gslResource()->getSurfaceAddress(); }
|
||||
|
||||
//! Returns the CAL descriptor for resource
|
||||
const CalResourceDesc* cal() const { return &cal_; }
|
||||
//! Returns global memory offset
|
||||
bool mipMapped() const { return (cal()->mipLevels_ > 1) ? true : false; }
|
||||
|
||||
//! Returns the CAL resource handle
|
||||
gslMemObject gslResource() const { return gslRef_->gslResource(); }
|
||||
//! Checks if persistent memory can have a direct map
|
||||
bool isPersistentDirectMap() const;
|
||||
|
||||
//! Returns global memory offset
|
||||
uint64_t vmAddress() const { return gslResource()->getSurfaceAddress(); }
|
||||
/*! \brief Locks the resource and returns a physical pointer
|
||||
*
|
||||
* \note This operation stalls HW pipeline!
|
||||
*
|
||||
* \return Pointer to the physical memory
|
||||
*/
|
||||
void* map(VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
uint flags = 0, //!< flags for the map operation
|
||||
// Optimization for multilayer map/unmap
|
||||
uint startLayer = 0, //!< Start layer for multilayer map
|
||||
uint numLayers = 0 //!< End layer for multilayer map
|
||||
);
|
||||
|
||||
//! Returns global memory offset
|
||||
bool mipMapped() const { return (cal()->mipLevels_ > 1) ? true : false; }
|
||||
//! Unlocks the resource if it was locked
|
||||
void unmap(VirtualGPU* gpu //!< Virtual GPU device object
|
||||
);
|
||||
|
||||
//! Checks if persistent memory can have a direct map
|
||||
bool isPersistentDirectMap() const;
|
||||
//! Marks the resource as busy
|
||||
void setBusy(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GpuEvent calEvent //!< CAL event
|
||||
) const;
|
||||
|
||||
/*! \brief Locks the resource and returns a physical pointer
|
||||
*
|
||||
* \note This operation stalls HW pipeline!
|
||||
*
|
||||
* \return Pointer to the physical memory
|
||||
*/
|
||||
void* map(
|
||||
VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
uint flags = 0, //!< flags for the map operation
|
||||
// Optimization for multilayer map/unmap
|
||||
uint startLayer = 0, //!< Start layer for multilayer map
|
||||
uint numLayers = 0 //!< End layer for multilayer map
|
||||
);
|
||||
//! Wait for the resource
|
||||
void wait(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
bool waitOnBusyEngine = false //!< Wait only if engine has changed
|
||||
) const;
|
||||
|
||||
//! Unlocks the resource if it was locked
|
||||
void unmap(
|
||||
VirtualGPU* gpu //!< Virtual GPU device object
|
||||
);
|
||||
//! Performs host write to the resource GPU memory
|
||||
bool hostWrite(VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
const void* hostPtr, //!< Host pointer to the SRC data
|
||||
const amd::Coord3D& origin, //!< Offsets for the update
|
||||
const amd::Coord3D& size, //!< The number of bytes to write
|
||||
uint flags = 0, //!< Map flags
|
||||
size_t rowPitch = 0, //!< Raw data row pitch
|
||||
size_t slicePitch = 0 //!< Raw data slice pitch
|
||||
);
|
||||
|
||||
//! Marks the resource as busy
|
||||
void setBusy(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GpuEvent calEvent //!< CAL event
|
||||
) const;
|
||||
//! Performs host read from the resource GPU memory
|
||||
bool hostRead(VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
void* hostPtr, //!< Host pointer to the DST data
|
||||
const amd::Coord3D& origin, //!< Offsets for the update
|
||||
const amd::Coord3D& size, //!< The number of bytes to write
|
||||
size_t rowPitch = 0, //!< Raw data row pitch
|
||||
size_t slicePitch = 0 //!< Raw data slice pitch
|
||||
);
|
||||
|
||||
//! Wait for the resource
|
||||
void wait(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
bool waitOnBusyEngine = false//!< Wait only if engine has changed
|
||||
) const;
|
||||
//! Warms up the rename list for this resource
|
||||
void warmUpRenames(VirtualGPU& gpu);
|
||||
|
||||
//! Performs host write to the resource GPU memory
|
||||
bool hostWrite(
|
||||
VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
const void* hostPtr, //!< Host pointer to the SRC data
|
||||
const amd::Coord3D& origin, //!< Offsets for the update
|
||||
const amd::Coord3D& size, //!< The number of bytes to write
|
||||
uint flags = 0, //!< Map flags
|
||||
size_t rowPitch = 0, //!< Raw data row pitch
|
||||
size_t slicePitch = 0 //!< Raw data slice pitch
|
||||
);
|
||||
//! Gets the resource element size
|
||||
size_t elementSize() const { return elementSize_; }
|
||||
|
||||
//! Performs host read from the resource GPU memory
|
||||
bool hostRead(
|
||||
VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
void* hostPtr, //!< Host pointer to the DST data
|
||||
const amd::Coord3D& origin, //!< Offsets for the update
|
||||
const amd::Coord3D& size, //!< The number of bytes to write
|
||||
size_t rowPitch = 0, //!< Raw data row pitch
|
||||
size_t slicePitch = 0 //!< Raw data slice pitch
|
||||
);
|
||||
//! Get the mapped address of this resource
|
||||
address data() const { return reinterpret_cast<address>(address_); }
|
||||
|
||||
//! Warms up the rename list for this resource
|
||||
void warmUpRenames(VirtualGPU& gpu);
|
||||
//! Frees all allocated CAL memories and resources,
|
||||
//! associated with this objects. And also destroys all rename structures
|
||||
//! Note: doesn't destroy the object itself
|
||||
void free();
|
||||
|
||||
//! Gets the resource element size
|
||||
size_t elementSize() const { return elementSize_; }
|
||||
//! Return memory type
|
||||
MemoryType memoryType() const { return cal_.type_; }
|
||||
|
||||
//! Get the mapped address of this resource
|
||||
address data() const { return reinterpret_cast<address>(address_); }
|
||||
//! Retunrs true if memory type matches specified
|
||||
bool isMemoryType(MemoryType memType) const;
|
||||
|
||||
//! Frees all allocated CAL memories and resources,
|
||||
//! associated with this objects. And also destroys all rename structures
|
||||
//! Note: doesn't destroy the object itself
|
||||
void free();
|
||||
//! Returns TRUE if resource was allocated as cacheable
|
||||
bool isCacheable() const { return (isMemoryType(Remote) || isMemoryType(Pinned)) ? true : false; }
|
||||
|
||||
//! Return memory type
|
||||
MemoryType memoryType() const { return cal_.type_; }
|
||||
bool gslGLAcquire();
|
||||
bool gslGLRelease();
|
||||
|
||||
//! Retunrs true if memory type matches specified
|
||||
bool isMemoryType(MemoryType memType) const;
|
||||
//! Returns HW state for the resource (used for images only)
|
||||
const void* hwState() const { return hwState_; }
|
||||
|
||||
//! Returns TRUE if resource was allocated as cacheable
|
||||
bool isCacheable() const
|
||||
{ return (isMemoryType(Remote) || isMemoryType(Pinned)) ? true : false; }
|
||||
//! Returns CPU HW SRD for the resource (used for images only)
|
||||
uint64_t hwSrd() const { return hwSrd_; }
|
||||
|
||||
bool gslGLAcquire() ;
|
||||
bool gslGLRelease() ;
|
||||
protected:
|
||||
size_t elementSize_; //!< Size of a single element in bytes
|
||||
|
||||
//! Returns HW state for the resource (used for images only)
|
||||
const void* hwState() const { return hwState_; }
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Resource(const Resource&);
|
||||
|
||||
//! Returns CPU HW SRD for the resource (used for images only)
|
||||
uint64_t hwSrd() const { return hwSrd_; }
|
||||
//! Disable operator=
|
||||
Resource& operator=(const Resource&);
|
||||
|
||||
protected:
|
||||
size_t elementSize_; //!< Size of a single element in bytes
|
||||
typedef std::vector<GslResourceReference*> RenameList;
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Resource(const Resource&);
|
||||
//! Rename current resource
|
||||
bool rename(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
bool force = false //!< Force renaming
|
||||
);
|
||||
|
||||
//! Disable operator=
|
||||
Resource& operator=(const Resource&);
|
||||
//! Sets the rename as active
|
||||
void setActiveRename(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GslResourceReference* rename //!< new active rename
|
||||
);
|
||||
|
||||
typedef std::vector<GslResourceReference*> RenameList;
|
||||
//! Gets the active rename
|
||||
bool getActiveRename(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GslResourceReference** rename //!< Saved active rename
|
||||
);
|
||||
|
||||
//! Rename current resource
|
||||
bool rename(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
bool force = false //!< Force renaming
|
||||
);
|
||||
/*! \brief Locks the resource with layers and returns a physical pointer
|
||||
*
|
||||
* \return Pointer to the physical memory
|
||||
*/
|
||||
void* mapLayers(VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
CALuint flags = 0 //!< flags for the map operation
|
||||
);
|
||||
|
||||
//! Sets the rename as active
|
||||
void setActiveRename(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GslResourceReference* rename //!< new active rename
|
||||
);
|
||||
//! Unlocks the resource with layers if it was locked
|
||||
void unmapLayers(VirtualGPU* gpu //!< Virtual GPU device object
|
||||
);
|
||||
|
||||
//! Gets the active rename
|
||||
bool getActiveRename(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GslResourceReference** rename //!< Saved active rename
|
||||
);
|
||||
//! Calls GSL to map a resource
|
||||
void* gslMap(size_t* pitch, //!< Pitch value for the image
|
||||
gslMapAccessType flags, //!< Map flags
|
||||
gslMemObject resource //!< GSL memory object
|
||||
) const;
|
||||
|
||||
/*! \brief Locks the resource with layers and returns a physical pointer
|
||||
*
|
||||
* \return Pointer to the physical memory
|
||||
*/
|
||||
void* mapLayers(
|
||||
VirtualGPU* gpu, //!< Virtual GPU device object
|
||||
CALuint flags = 0 //!< flags for the map operation
|
||||
);
|
||||
//! Uses GSL to unmap a resource
|
||||
void gslUnmap(gslMemObject resource //!< GSL memory object
|
||||
) const;
|
||||
|
||||
//! Unlocks the resource with layers if it was locked
|
||||
void unmapLayers(
|
||||
VirtualGPU* gpu //!< Virtual GPU device object
|
||||
);
|
||||
//! Fress all GSL resources associated with OCL resource
|
||||
void gslFree() const;
|
||||
|
||||
//! Calls GSL to map a resource
|
||||
void* gslMap(
|
||||
size_t* pitch, //!< Pitch value for the image
|
||||
gslMapAccessType flags, //!< Map flags
|
||||
gslMemObject resource //!< GSL memory object
|
||||
) const;
|
||||
const Device& gpuDevice_; //!< GPU device
|
||||
CalResourceDesc cal_; //!< CAL descriptor for this resource
|
||||
amd::Atomic<int> mapCount_; //!< Total number of maps
|
||||
void* address_; //!< Physical address of this resource
|
||||
size_t offset_; //!< Resource offset
|
||||
size_t curRename_; //!< Current active rename in the list
|
||||
RenameList renames_; //!< Rename resource list
|
||||
GslResourceReference* gslRef_; //!< GSL resource reference
|
||||
const Resource* viewOwner_; //!< GPU resource, which owns this view
|
||||
uint64_t hbOffset_; //!< Offset in the heap (virtual or real)
|
||||
uint64_t hbSize_; //!< Memory size
|
||||
uint64_t pinOffset_; //!< Pinned memory offset
|
||||
gslMemObject glInterop_; //!< Original GL interop object
|
||||
void* glInteropMbRes_; //!< Mb Res handle
|
||||
uint32_t glType_; //!< GL interop type
|
||||
void* glPlatformContext_;
|
||||
void* glDeviceContext_;
|
||||
|
||||
//! Uses GSL to unmap a resource
|
||||
void gslUnmap(
|
||||
gslMemObject resource //!< GSL memory object
|
||||
) const;
|
||||
// Optimization for multilayer map/unmap
|
||||
uint startLayer_; //!< Start layer for map/unmapLayer
|
||||
uint numLayers_; //!< Number of layers for map/unmapLayer
|
||||
CALuint mapFlags_; //!< Map flags for map/umapLayer
|
||||
|
||||
//! Fress all GSL resources associated with OCL resource
|
||||
void gslFree() const;
|
||||
//! @note: This field is necessary for the thread safe release only
|
||||
VirtualGPU* gpu_; //!< Resource will be used only on this queue
|
||||
|
||||
const Device& gpuDevice_; //!< GPU device
|
||||
CalResourceDesc cal_; //!< CAL descriptor for this resource
|
||||
amd::Atomic<int> mapCount_; //!< Total number of maps
|
||||
void* address_; //!< Physical address of this resource
|
||||
size_t offset_; //!< Resource offset
|
||||
size_t curRename_; //!< Current active rename in the list
|
||||
RenameList renames_; //!< Rename resource list
|
||||
GslResourceReference* gslRef_; //!< GSL resource reference
|
||||
const Resource* viewOwner_; //!< GPU resource, which owns this view
|
||||
uint64_t hbOffset_; //!< Offset in the heap (virtual or real)
|
||||
uint64_t hbSize_; //!< Memory size
|
||||
uint64_t pinOffset_; //!< Pinned memory offset
|
||||
gslMemObject glInterop_; //!< Original GL interop object
|
||||
void* glInteropMbRes_;//!< Mb Res handle
|
||||
uint32_t glType_; //!< GL interop type
|
||||
void* glPlatformContext_;
|
||||
void* glDeviceContext_;
|
||||
|
||||
// Optimization for multilayer map/unmap
|
||||
uint startLayer_; //!< Start layer for map/unmapLayer
|
||||
uint numLayers_; //!< Number of layers for map/unmapLayer
|
||||
CALuint mapFlags_; //!< Map flags for map/umapLayer
|
||||
|
||||
//! @note: This field is necessary for the thread safe release only
|
||||
VirtualGPU* gpu_; //!< Resource will be used only on this queue
|
||||
|
||||
uint32_t* hwState_; //!< HW state for image object
|
||||
uint64_t hwSrd_; //!< GPU pointer to HW SRD
|
||||
uint32_t* hwState_; //!< HW state for image object
|
||||
uint64_t hwSrd_; //!< GPU pointer to HW SRD
|
||||
};
|
||||
|
||||
class ResourceCache : public amd::HeapObject
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
ResourceCache(size_t cacheSizeLimit)
|
||||
: lockCacheOps_("CAL resource cache", true)
|
||||
, cacheSize_(0)
|
||||
, cacheSizeLimit_(cacheSizeLimit)
|
||||
{}
|
||||
class ResourceCache : public amd::HeapObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
ResourceCache(size_t cacheSizeLimit)
|
||||
: lockCacheOps_("CAL resource cache", true), cacheSize_(0), cacheSizeLimit_(cacheSizeLimit) {}
|
||||
|
||||
//! Default destructor
|
||||
~ResourceCache();
|
||||
//! Default destructor
|
||||
~ResourceCache();
|
||||
|
||||
//! Adds a CAL resource to the cache
|
||||
bool addCalResource(
|
||||
Resource::CalResourceDesc* desc, //!< CAL resource descriptor - cache key
|
||||
GslResourceReference* ref //!< CAL resource reference
|
||||
);
|
||||
//! Adds a CAL resource to the cache
|
||||
bool addCalResource(Resource::CalResourceDesc* desc, //!< CAL resource descriptor - cache key
|
||||
GslResourceReference* ref //!< CAL resource reference
|
||||
);
|
||||
|
||||
//! Finds a CAL resource from the cache
|
||||
GslResourceReference* findCalResource(
|
||||
Resource::CalResourceDesc* desc //!< CAL resource descriptor - cache key
|
||||
);
|
||||
//! Finds a CAL resource from the cache
|
||||
GslResourceReference* findCalResource(
|
||||
Resource::CalResourceDesc* desc //!< CAL resource descriptor - cache key
|
||||
);
|
||||
|
||||
//! Destroys cache
|
||||
bool free(size_t minCacheEntries = 0);
|
||||
//! Destroys cache
|
||||
bool free(size_t minCacheEntries = 0);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ResourceCache(const ResourceCache&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ResourceCache(const ResourceCache&);
|
||||
|
||||
//! Disable operator=
|
||||
ResourceCache& operator=(const ResourceCache&);
|
||||
//! Disable operator=
|
||||
ResourceCache& operator=(const ResourceCache&);
|
||||
|
||||
//! Gets resource size in bytes
|
||||
size_t getResourceSize(Resource::CalResourceDesc* desc);
|
||||
//! Gets resource size in bytes
|
||||
size_t getResourceSize(Resource::CalResourceDesc* desc);
|
||||
|
||||
//! Removes one last entry from the cache
|
||||
void removeLast();
|
||||
//! Removes one last entry from the cache
|
||||
void removeLast();
|
||||
|
||||
amd::Monitor lockCacheOps_; //!< Lock to serialise cache access
|
||||
amd::Monitor lockCacheOps_; //!< Lock to serialise cache access
|
||||
|
||||
size_t cacheSize_; //!< Current cache size in bytes
|
||||
size_t cacheSizeLimit_; //!< Cache size limit in bytes
|
||||
size_t cacheSize_; //!< Current cache size in bytes
|
||||
size_t cacheSizeLimit_; //!< Cache size limit in bytes
|
||||
|
||||
//! CAL resource cache
|
||||
std::list<std::pair<Resource::CalResourceDesc*, GslResourceReference*> > resCache_;
|
||||
//! CAL resource cache
|
||||
std::list<std::pair<Resource::CalResourceDesc*, GslResourceReference*> > resCache_;
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
@@ -10,69 +10,70 @@ namespace gpu {
|
||||
|
||||
//! AmdAqlWrap slot state
|
||||
enum AqlWrapState {
|
||||
AQL_WRAP_FREE = 0,
|
||||
AQL_WRAP_RESERVED,
|
||||
AQL_WRAP_READY,
|
||||
AQL_WRAP_MARKER,
|
||||
AQL_WRAP_BUSY,
|
||||
AQL_WRAP_DONE
|
||||
AQL_WRAP_FREE = 0,
|
||||
AQL_WRAP_RESERVED,
|
||||
AQL_WRAP_READY,
|
||||
AQL_WRAP_MARKER,
|
||||
AQL_WRAP_BUSY,
|
||||
AQL_WRAP_DONE
|
||||
};
|
||||
|
||||
struct AmdVQueueHeader {
|
||||
uint32_t aql_slot_num; //!< [LRO/SRO] The total number of the AQL slots (multiple of 64).
|
||||
uint32_t event_slot_num; //!< [LRO] The number of kernel events in the events buffer
|
||||
uint64_t event_slot_mask; //!< [LRO] A pointer to the allocation bitmask array for the events
|
||||
uint64_t event_slots; //!< [LRO] Pointer to a buffer for the events.
|
||||
// Array of event_slot_num entries of AmdEvent
|
||||
uint64_t aql_slot_mask; //!< [LRO/SRO]A pointer to the allocation bitmask for aql_warp slots
|
||||
uint32_t command_counter; //!< [LRW] The global counter for the submitted commands into the queue
|
||||
uint32_t wait_size; //!< [LRO] The wait list size (in clk_event_t)
|
||||
uint32_t arg_size; //!< [LRO] The size of argument buffer (in bytes)
|
||||
uint32_t mask_groups; //!< Processed mask groups by one thread
|
||||
uint64_t kernel_table; //!< [LRO] Pointer to an array with all kernel objects (ulong for each entry)
|
||||
uint32_t reserved[2]; //!< For the future usage
|
||||
uint32_t aql_slot_num; //!< [LRO/SRO] The total number of the AQL slots (multiple of 64).
|
||||
uint32_t event_slot_num; //!< [LRO] The number of kernel events in the events buffer
|
||||
uint64_t event_slot_mask; //!< [LRO] A pointer to the allocation bitmask array for the events
|
||||
uint64_t event_slots; //!< [LRO] Pointer to a buffer for the events.
|
||||
// Array of event_slot_num entries of AmdEvent
|
||||
uint64_t aql_slot_mask; //!< [LRO/SRO]A pointer to the allocation bitmask for aql_warp slots
|
||||
uint32_t command_counter; //!< [LRW] The global counter for the submitted commands into the queue
|
||||
uint32_t wait_size; //!< [LRO] The wait list size (in clk_event_t)
|
||||
uint32_t arg_size; //!< [LRO] The size of argument buffer (in bytes)
|
||||
uint32_t mask_groups; //!< Processed mask groups by one thread
|
||||
uint64_t
|
||||
kernel_table; //!< [LRO] Pointer to an array with all kernel objects (ulong for each entry)
|
||||
uint32_t reserved[2]; //!< For the future usage
|
||||
};
|
||||
|
||||
struct AmdAqlWrap {
|
||||
uint32_t state; //!< [LRW/SRW] The current state of the AQL wrapper: FREE, RESERVED, READY,
|
||||
// MARKER, BUSY and DONE. The block could be returned back to a free state.
|
||||
uint32_t enqueue_flags; //!< [LWO/SRO] Contains the flags for the kernel execution start
|
||||
uint32_t command_id; //!< [LWO/SRO] The unique command ID
|
||||
uint32_t child_counter; //!< [LRW/SRW] Counter that determine the launches of child kernels.
|
||||
// It’s incremented on the
|
||||
// start and decremented on the finish. The parent kernel can be considered as
|
||||
// done when the value is 0 and the state is DONE
|
||||
uint64_t completion; //!< [LWO/SRO] CL event for the current execution (clk_event_t)
|
||||
uint64_t parent_wrap; //!< [LWO/SRO] Pointer to the parent AQL wrapper (AmdAqlWrap*)
|
||||
uint64_t wait_list; //!< [LRO/SRO] Pointer to an array of clk_event_t objects (64 bytes default)
|
||||
uint32_t wait_num; //!< [LWO/SRO] The number of cl_event_wait objects
|
||||
uint32_t reserved[5]; //!< For the future usage
|
||||
hsa_kernel_dispatch_packet_t aql; //!< [LWO/SRO] AQL packet – 64 bytes AQL packet
|
||||
uint32_t state; //!< [LRW/SRW] The current state of the AQL wrapper: FREE, RESERVED, READY,
|
||||
// MARKER, BUSY and DONE. The block could be returned back to a free state.
|
||||
uint32_t enqueue_flags; //!< [LWO/SRO] Contains the flags for the kernel execution start
|
||||
uint32_t command_id; //!< [LWO/SRO] The unique command ID
|
||||
uint32_t child_counter; //!< [LRW/SRW] Counter that determine the launches of child kernels.
|
||||
// It’s incremented on the
|
||||
// start and decremented on the finish. The parent kernel can be considered as
|
||||
// done when the value is 0 and the state is DONE
|
||||
uint64_t completion; //!< [LWO/SRO] CL event for the current execution (clk_event_t)
|
||||
uint64_t parent_wrap; //!< [LWO/SRO] Pointer to the parent AQL wrapper (AmdAqlWrap*)
|
||||
uint64_t wait_list; //!< [LRO/SRO] Pointer to an array of clk_event_t objects (64 bytes default)
|
||||
uint32_t wait_num; //!< [LWO/SRO] The number of cl_event_wait objects
|
||||
uint32_t reserved[5]; //!< For the future usage
|
||||
hsa_kernel_dispatch_packet_t aql; //!< [LWO/SRO] AQL packet – 64 bytes AQL packet
|
||||
};
|
||||
|
||||
struct AmdEvent {
|
||||
uint32_t state; //!< [LRO/SRW] Event state: START, END, COMPLETE
|
||||
uint32_t counter; //!< [LRW] Event retain/release counter. 0 means the event is free
|
||||
uint64_t timer[3]; //!< [LRO/SWO] Timer values for profiling for each state
|
||||
uint64_t captureInfo; //!< [LRW/SRO] Profiling capture info for CLK_PROFILING_COMMAND_EXEC_TIME
|
||||
uint32_t state; //!< [LRO/SRW] Event state: START, END, COMPLETE
|
||||
uint32_t counter; //!< [LRW] Event retain/release counter. 0 means the event is free
|
||||
uint64_t timer[3]; //!< [LRO/SWO] Timer values for profiling for each state
|
||||
uint64_t captureInfo; //!< [LRW/SRO] Profiling capture info for CLK_PROFILING_COMMAND_EXEC_TIME
|
||||
};
|
||||
|
||||
struct SchedulerParam {
|
||||
uint32_t signal; //!< Signal to stop the child queue(address must be 16 bytes aligned)
|
||||
uint32_t eng_clk; //!< Engine clock in Mhz
|
||||
uint64_t hw_queue; //!< Address to HW queue
|
||||
uint64_t hsa_queue; //!< Address to HSA dummy queue
|
||||
uint32_t useATC; //!< GPU access to shader program by ATC.
|
||||
uint32_t scratchSize; //!< Scratch buffer size
|
||||
uint64_t scratch; //!< GPU address to the scratch buffer
|
||||
uint32_t numMaxWaves; //!< The max number of possible waves
|
||||
uint32_t releaseHostCP; //!< Releases CP on the host queue
|
||||
uint64_t parentAQL; //!< Host parent AmdAqlWrap packet
|
||||
uint32_t dedicatedQueue; //!< Scheduler uses a dedicated queue
|
||||
uint32_t scratchOffset; //!< Scratch buffer offset
|
||||
uint32_t reserved[2]; //!< Reserved
|
||||
uint32_t signal; //!< Signal to stop the child queue(address must be 16 bytes aligned)
|
||||
uint32_t eng_clk; //!< Engine clock in Mhz
|
||||
uint64_t hw_queue; //!< Address to HW queue
|
||||
uint64_t hsa_queue; //!< Address to HSA dummy queue
|
||||
uint32_t useATC; //!< GPU access to shader program by ATC.
|
||||
uint32_t scratchSize; //!< Scratch buffer size
|
||||
uint64_t scratch; //!< GPU address to the scratch buffer
|
||||
uint32_t numMaxWaves; //!< The max number of possible waves
|
||||
uint32_t releaseHostCP; //!< Releases CP on the host queue
|
||||
uint64_t parentAQL; //!< Host parent AmdAqlWrap packet
|
||||
uint32_t dedicatedQueue; //!< Scheduler uses a dedicated queue
|
||||
uint32_t scratchOffset; //!< Scratch buffer offset
|
||||
uint32_t reserved[2]; //!< Reserved
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
|
||||
#endif
|
||||
@@ -292,4 +292,4 @@ scheduler(
|
||||
\n
|
||||
);
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -18,182 +18,177 @@
|
||||
|
||||
namespace gpu {
|
||||
|
||||
bool
|
||||
NullKernel::siCreateHwInfo(const void* shader, AMUabiAddEncoding& encoding)
|
||||
{
|
||||
static const uint NumSiCsInfos = (70 + 5 + 1 + 32 + 6);
|
||||
CALProgramInfoEntry* newInfos;
|
||||
uint i = 0;
|
||||
uint infoCount = NumSiCsInfos;
|
||||
const SC_SI_HWSHADER_CS* cShader = reinterpret_cast<const SC_SI_HWSHADER_CS*>(shader);
|
||||
newInfos = new CALProgramInfoEntry[infoCount];
|
||||
encoding.progInfos = newInfos;
|
||||
if (encoding.progInfos == 0) {
|
||||
infoCount = 0;
|
||||
return false;
|
||||
}
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENT_COUNT;
|
||||
newInfos[i].value = cShader->common.userElementCount;
|
||||
bool NullKernel::siCreateHwInfo(const void* shader, AMUabiAddEncoding& encoding) {
|
||||
static const uint NumSiCsInfos = (70 + 5 + 1 + 32 + 6);
|
||||
CALProgramInfoEntry* newInfos;
|
||||
uint i = 0;
|
||||
uint infoCount = NumSiCsInfos;
|
||||
const SC_SI_HWSHADER_CS* cShader = reinterpret_cast<const SC_SI_HWSHADER_CS*>(shader);
|
||||
newInfos = new CALProgramInfoEntry[infoCount];
|
||||
encoding.progInfos = newInfos;
|
||||
if (encoding.progInfos == 0) {
|
||||
infoCount = 0;
|
||||
return false;
|
||||
}
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENT_COUNT;
|
||||
newInfos[i].value = cShader->common.userElementCount;
|
||||
i++;
|
||||
for (unsigned int j = 0; j < cShader->common.userElementCount; j++) {
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD0 + 4 * j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].dataClass;
|
||||
i++;
|
||||
for (unsigned int j = 0; j < cShader->common.userElementCount; j++) {
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD0 + 4*j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].dataClass;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD1 + 4*j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].apiSlot;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD2 + 4*j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].startUserReg;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD3 + 4*j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].userRegCount;
|
||||
i++;
|
||||
}
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD1 + 4 * j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].apiSlot;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD2 + 4 * j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].startUserReg;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_USER_ELEMENTS_0_DWORD3 + 4 * j;
|
||||
newInfos[i].value = HWSHADER_Get(cShader, common.pUserElements)[j].userRegCount;
|
||||
i++;
|
||||
}
|
||||
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_VGPRS;
|
||||
newInfos[i].value = cShader->common.numVgprs;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_SGPRS;
|
||||
newInfos[i].value = cShader->common.numSgprs;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_SGPRS_AVAIL;
|
||||
newInfos[i].value = SI_sgprs_avail; //512;//options.NumSGPRsAvailable;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_VGPRS_AVAIL;
|
||||
newInfos[i].value = SI_vgprs_avail;//options.NumVGPRsAvailable;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_VGPRS;
|
||||
newInfos[i].value = cShader->common.numVgprs;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_SGPRS;
|
||||
newInfos[i].value = cShader->common.numSgprs;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_SGPRS_AVAIL;
|
||||
newInfos[i].value = SI_sgprs_avail; // 512;//options.NumSGPRsAvailable;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_NUM_VGPRS_AVAIL;
|
||||
newInfos[i].value = SI_vgprs_avail; // options.NumVGPRsAvailable;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_SI_FLOAT_MODE;
|
||||
newInfos[i].value = cShader->common.floatMode;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_IEEE_MODE;
|
||||
newInfos[i].value = cShader->common.bIeeeMode;
|
||||
newInfos[i].address = AMU_ABI_SI_FLOAT_MODE;
|
||||
newInfos[i].value = cShader->common.floatMode;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_SI_IEEE_MODE;
|
||||
newInfos[i].value = cShader->common.bIeeeMode;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_SI_SCRATCH_SIZE;
|
||||
newInfos[i].value = cShader->common.scratchSize;
|
||||
;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = mmCOMPUTE_PGM_RSRC2;
|
||||
newInfos[i].value = cShader->computePgmRsrc2.u32All;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_NUM_THREAD_PER_GROUP_X;
|
||||
newInfos[i].value = cShader->numThreadX;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_NUM_THREAD_PER_GROUP_Y;
|
||||
newInfos[i].value = cShader->numThreadY;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_NUM_THREAD_PER_GROUP_Z;
|
||||
newInfos[i].value = cShader->numThreadZ;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_ORDERED_APPEND_ENABLE;
|
||||
newInfos[i].value = cShader->bOrderedAppendEnable;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_RAT_OP_IS_USED;
|
||||
newInfos[i].value = cShader->common.uavResourceUsage[0];
|
||||
i++;
|
||||
|
||||
for (unsigned int j = 0; j < ((SC_MAX_UAV + 31) / 32); j++) {
|
||||
newInfos[i].address = AMU_ABI_UAV_RESOURCE_MASK_0 + j;
|
||||
newInfos[i].value = cShader->common.uavResourceUsage[j];
|
||||
i++;
|
||||
}
|
||||
|
||||
newInfos[i].address = AMU_ABI_SI_SCRATCH_SIZE;
|
||||
newInfos[i].value = cShader->common.scratchSize;;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_NUM_WAVEFRONT_PER_SIMD; // Setting the same as for scWrapR800Info
|
||||
newInfos[i].value = 1;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = mmCOMPUTE_PGM_RSRC2;
|
||||
newInfos[i].value = cShader->computePgmRsrc2.u32All;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_WAVEFRONT_SIZE;
|
||||
newInfos[i].value = nullDev().hwInfo()->simdWidth_ * 4; // options.WavefrontSize;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_NUM_THREAD_PER_GROUP_X;
|
||||
newInfos[i].value = cShader->numThreadX;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_NUM_THREAD_PER_GROUP_Y;
|
||||
newInfos[i].value = cShader->numThreadY;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_NUM_THREAD_PER_GROUP_Z;
|
||||
newInfos[i].value = cShader->numThreadZ;
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_LDS_SIZE_AVAIL;
|
||||
newInfos[i].value = SI_ldssize_avail; // options.LDSSize;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_ORDERED_APPEND_ENABLE;
|
||||
newInfos[i].value = cShader->bOrderedAppendEnable;
|
||||
i++;
|
||||
COMPUTE_PGM_RSRC2 computePgmRsrc2;
|
||||
computePgmRsrc2.u32All = cShader->computePgmRsrc2.u32All;
|
||||
|
||||
newInfos[i].address = AMU_ABI_RAT_OP_IS_USED;
|
||||
newInfos[i].value = cShader->common.uavResourceUsage[0];
|
||||
i++;
|
||||
newInfos[i].address = AMU_ABI_LDS_SIZE_USED;
|
||||
newInfos[i].value = 64 * 4 * computePgmRsrc2.bits.LDS_SIZE;
|
||||
i++;
|
||||
|
||||
for (unsigned int j = 0; j < ((SC_MAX_UAV + 31) / 32); j++) {
|
||||
newInfos[i].address = AMU_ABI_UAV_RESOURCE_MASK_0 + j;
|
||||
newInfos[i].value = cShader->common.uavResourceUsage[j];
|
||||
i++;
|
||||
}
|
||||
infoCount = i;
|
||||
assert((i + 4 * (16 - cShader->common.userElementCount)) == NumSiCsInfos);
|
||||
encoding.progInfosCount = infoCount;
|
||||
|
||||
newInfos[i].address = AMU_ABI_NUM_WAVEFRONT_PER_SIMD; // Setting the same as for scWrapR800Info
|
||||
newInfos[i].value = 1;
|
||||
i++;
|
||||
encoding.textData = HWSHADER_Get(cShader, common.hShaderMemHandle);
|
||||
encoding.textSize = cShader->common.codeLenInByte;
|
||||
instructionCnt_ = encoding.textSize / sizeof(uint32_t);
|
||||
encoding.scratchRegisterCount = cShader->common.scratchSize;
|
||||
encoding.UAVReturnBufferTotalSize = 0;
|
||||
|
||||
newInfos[i].address = AMU_ABI_WAVEFRONT_SIZE;
|
||||
newInfos[i].value = nullDev().hwInfo()->simdWidth_ * 4; //options.WavefrontSize;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_LDS_SIZE_AVAIL;
|
||||
newInfos[i].value = SI_ldssize_avail; //options.LDSSize;
|
||||
i++;
|
||||
|
||||
COMPUTE_PGM_RSRC2 computePgmRsrc2;
|
||||
computePgmRsrc2.u32All = cShader->computePgmRsrc2.u32All;
|
||||
|
||||
newInfos[i].address = AMU_ABI_LDS_SIZE_USED;
|
||||
newInfos[i].value = 64 * 4 * computePgmRsrc2.bits.LDS_SIZE;
|
||||
i++;
|
||||
|
||||
infoCount = i;
|
||||
assert((i + 4 * (16 - cShader->common.userElementCount)) == NumSiCsInfos);
|
||||
encoding.progInfosCount = infoCount;
|
||||
|
||||
encoding.textData = HWSHADER_Get(cShader, common.hShaderMemHandle);
|
||||
encoding.textSize = cShader->common.codeLenInByte;
|
||||
instructionCnt_ = encoding.textSize / sizeof(uint32_t);
|
||||
encoding.scratchRegisterCount = cShader->common.scratchSize;
|
||||
encoding.UAVReturnBufferTotalSize = 0;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HSAILKernel::aqlCreateHWInfo(amd::hsa::loader::Symbol *sym)
|
||||
{
|
||||
if (!sym) {
|
||||
return false;
|
||||
}
|
||||
uint64_t akc_addr = 0;
|
||||
if (!sym->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, reinterpret_cast<void*>(&akc_addr))) {
|
||||
return false;
|
||||
}
|
||||
amd_kernel_code_t *akc = reinterpret_cast<amd_kernel_code_t*>(akc_addr);
|
||||
cpuAqlCode_ = akc;
|
||||
if (!sym->GetInfo(HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_SIZE, reinterpret_cast<void*>(&codeSize_))) {
|
||||
return false;
|
||||
}
|
||||
size_t akc_align = 0;
|
||||
if (!sym->GetInfo(HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_ALIGN, reinterpret_cast<void*>(&akc_align))) {
|
||||
return false;
|
||||
}
|
||||
bool HSAILKernel::aqlCreateHWInfo(amd::hsa::loader::Symbol* sym) {
|
||||
if (!sym) {
|
||||
return false;
|
||||
}
|
||||
uint64_t akc_addr = 0;
|
||||
if (!sym->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, reinterpret_cast<void*>(&akc_addr))) {
|
||||
return false;
|
||||
}
|
||||
amd_kernel_code_t* akc = reinterpret_cast<amd_kernel_code_t*>(akc_addr);
|
||||
cpuAqlCode_ = akc;
|
||||
if (!sym->GetInfo(HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_SIZE,
|
||||
reinterpret_cast<void*>(&codeSize_))) {
|
||||
return false;
|
||||
}
|
||||
size_t akc_align = 0;
|
||||
if (!sym->GetInfo(HSA_EXT_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT_ALIGN,
|
||||
reinterpret_cast<void*>(&akc_align))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate HW resources for the real program only
|
||||
if (!prog().isNull()) {
|
||||
code_ = new gpu::Memory(dev(), amd::alignUp(codeSize_, akc_align));
|
||||
// Initialize kernel ISA code
|
||||
if (code_ && code_->create(Resource::Shader)) {
|
||||
address cpuCodePtr = static_cast<address>(code_->map(NULL, Resource::WriteOnly));
|
||||
// Copy only amd_kernel_code_t
|
||||
memcpy(cpuCodePtr, reinterpret_cast<address>(akc), codeSize_);
|
||||
code_->unmap(NULL);
|
||||
}
|
||||
else {
|
||||
LogError("Failed to allocate ISA code!");
|
||||
return false;
|
||||
}
|
||||
// Allocate HW resources for the real program only
|
||||
if (!prog().isNull()) {
|
||||
code_ = new gpu::Memory(dev(), amd::alignUp(codeSize_, akc_align));
|
||||
// Initialize kernel ISA code
|
||||
if (code_ && code_->create(Resource::Shader)) {
|
||||
address cpuCodePtr = static_cast<address>(code_->map(NULL, Resource::WriteOnly));
|
||||
// Copy only amd_kernel_code_t
|
||||
memcpy(cpuCodePtr, reinterpret_cast<address>(akc), codeSize_);
|
||||
code_->unmap(NULL);
|
||||
} else {
|
||||
LogError("Failed to allocate ISA code!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
assert((akc->workitem_private_segment_byte_size & 3) == 0 &&
|
||||
"Scratch must be DWORD aligned");
|
||||
workGroupInfo_.scratchRegs_ =
|
||||
amd::alignUp(akc->workitem_private_segment_byte_size, 16) / sizeof(uint);
|
||||
workGroupInfo_.privateMemSize_ = akc->workitem_private_segment_byte_size;
|
||||
workGroupInfo_.availableLDSSize_ = dev().info().localMemSize_;
|
||||
workGroupInfo_.localMemSize_ =
|
||||
workGroupInfo_.usedLDSSize_ = akc->workgroup_group_segment_byte_size;
|
||||
workGroupInfo_.usedSGPRs_ = akc->wavefront_sgpr_count;
|
||||
workGroupInfo_.usedStackSize_ = 0;
|
||||
workGroupInfo_.usedVGPRs_ = akc->workitem_vgpr_count;
|
||||
assert((akc->workitem_private_segment_byte_size & 3) == 0 && "Scratch must be DWORD aligned");
|
||||
workGroupInfo_.scratchRegs_ =
|
||||
amd::alignUp(akc->workitem_private_segment_byte_size, 16) / sizeof(uint);
|
||||
workGroupInfo_.privateMemSize_ = akc->workitem_private_segment_byte_size;
|
||||
workGroupInfo_.availableLDSSize_ = dev().info().localMemSize_;
|
||||
workGroupInfo_.localMemSize_ = workGroupInfo_.usedLDSSize_ =
|
||||
akc->workgroup_group_segment_byte_size;
|
||||
workGroupInfo_.usedSGPRs_ = akc->wavefront_sgpr_count;
|
||||
workGroupInfo_.usedStackSize_ = 0;
|
||||
workGroupInfo_.usedVGPRs_ = akc->workitem_vgpr_count;
|
||||
|
||||
if (!prog().isNull()) {
|
||||
workGroupInfo_.availableSGPRs_ = dev().gslCtx()->getNumSGPRsAvailable();
|
||||
workGroupInfo_.availableVGPRs_ = dev().gslCtx()->getNumVGPRsAvailable();
|
||||
workGroupInfo_.preferredSizeMultiple_ = dev().getAttribs().wavefrontSize;
|
||||
workGroupInfo_.wavefrontPerSIMD_ = dev().getAttribs().wavefrontSize;
|
||||
}
|
||||
else {
|
||||
workGroupInfo_.availableSGPRs_ = 104;
|
||||
workGroupInfo_.availableVGPRs_ = 256;
|
||||
workGroupInfo_.preferredSizeMultiple_ =
|
||||
workGroupInfo_.wavefrontPerSIMD_ = 64;
|
||||
}
|
||||
return true;
|
||||
if (!prog().isNull()) {
|
||||
workGroupInfo_.availableSGPRs_ = dev().gslCtx()->getNumSGPRsAvailable();
|
||||
workGroupInfo_.availableVGPRs_ = dev().gslCtx()->getNumVGPRsAvailable();
|
||||
workGroupInfo_.preferredSizeMultiple_ = dev().getAttribs().wavefrontSize;
|
||||
workGroupInfo_.wavefrontPerSIMD_ = dev().getAttribs().wavefrontSize;
|
||||
} else {
|
||||
workGroupInfo_.availableSGPRs_ = 104;
|
||||
workGroupInfo_.availableVGPRs_ = 256;
|
||||
workGroupInfo_.preferredSizeMultiple_ = workGroupInfo_.wavefrontPerSIMD_ = 64;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -21,174 +21,167 @@ namespace gpu {
|
||||
* This structure contains the time and OS minor version for max workload time
|
||||
* adjustment for Windows 7 or 8.
|
||||
*/
|
||||
struct ModifyMaxWorkload
|
||||
{
|
||||
uint32_t time; //!< max work load time (10x ms)
|
||||
uint32_t minorVersion; //!< OS minor version
|
||||
struct ModifyMaxWorkload {
|
||||
uint32_t time; //!< max work load time (10x ms)
|
||||
uint32_t minorVersion; //!< OS minor version
|
||||
#if defined(_WIN32)
|
||||
BYTE comparisonOps; //!< Comparison option
|
||||
BYTE comparisonOps; //!< Comparison option
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Settings::Settings()
|
||||
{
|
||||
// Initialize the GPU device default settings
|
||||
oclVersion_ = OpenCL12;
|
||||
debugFlags_ = 0;
|
||||
syncObject_ = GPU_USE_SYNC_OBJECTS;
|
||||
remoteAlloc_ = REMOTE_ALLOC;
|
||||
Settings::Settings() {
|
||||
// Initialize the GPU device default settings
|
||||
oclVersion_ = OpenCL12;
|
||||
debugFlags_ = 0;
|
||||
syncObject_ = GPU_USE_SYNC_OBJECTS;
|
||||
remoteAlloc_ = REMOTE_ALLOC;
|
||||
|
||||
stagedXferRead_ = true;
|
||||
stagedXferWrite_ = true;
|
||||
stagedXferSize_ = GPU_STAGING_BUFFER_SIZE * Ki;
|
||||
stagedXferRead_ = true;
|
||||
stagedXferWrite_ = true;
|
||||
stagedXferSize_ = GPU_STAGING_BUFFER_SIZE * Ki;
|
||||
|
||||
// We will enable staged read/write if we use local memory
|
||||
disablePersistent_ = false;
|
||||
// We will enable staged read/write if we use local memory
|
||||
disablePersistent_ = false;
|
||||
|
||||
// By Default persistent writes will be disabled.
|
||||
stagingWritePersistent_ = GPU_STAGING_WRITE_PERSISTENT;
|
||||
// By Default persistent writes will be disabled.
|
||||
stagingWritePersistent_ = GPU_STAGING_WRITE_PERSISTENT;
|
||||
|
||||
maxRenames_ = 16;
|
||||
maxRenameSize_ = 4 * Mi;
|
||||
maxRenames_ = 16;
|
||||
maxRenameSize_ = 4 * Mi;
|
||||
|
||||
imageSupport_ = false;
|
||||
hwLDSSize_ = 0;
|
||||
imageSupport_ = false;
|
||||
hwLDSSize_ = 0;
|
||||
|
||||
// Set this to true when we drop the flag
|
||||
doublePrecision_ = ::CL_KHR_FP64;
|
||||
// Set this to true when we drop the flag
|
||||
doublePrecision_ = ::CL_KHR_FP64;
|
||||
|
||||
// Fill workgroup info size
|
||||
// @todo: revisit the 256 limitation on workgroup size
|
||||
maxWorkGroupSize_ = 256;
|
||||
// Fill workgroup info size
|
||||
// @todo: revisit the 256 limitation on workgroup size
|
||||
maxWorkGroupSize_ = 256;
|
||||
|
||||
hostMemDirectAccess_ = HostMemDisable;
|
||||
hostMemDirectAccess_ = HostMemDisable;
|
||||
|
||||
libSelector_ = amd::LibraryUndefined;
|
||||
libSelector_ = amd::LibraryUndefined;
|
||||
|
||||
// Enable workload split by default (for 24 bit arithmetic or timeout)
|
||||
workloadSplitSize_ = 1 << GPU_WORKLOAD_SPLIT;
|
||||
// Enable workload split by default (for 24 bit arithmetic or timeout)
|
||||
workloadSplitSize_ = 1 << GPU_WORKLOAD_SPLIT;
|
||||
|
||||
// By default use host blit
|
||||
blitEngine_ = BlitEngineHost;
|
||||
const static size_t MaxPinnedXferSize = 32;
|
||||
pinnedXferSize_ = std::min(GPU_PINNED_XFER_SIZE, MaxPinnedXferSize) * Mi;
|
||||
pinnedMinXferSize_ = std::min(GPU_PINNED_MIN_XFER_SIZE * Ki, pinnedXferSize_);
|
||||
// By default use host blit
|
||||
blitEngine_ = BlitEngineHost;
|
||||
const static size_t MaxPinnedXferSize = 32;
|
||||
pinnedXferSize_ = std::min(GPU_PINNED_XFER_SIZE, MaxPinnedXferSize) * Mi;
|
||||
pinnedMinXferSize_ = std::min(GPU_PINNED_MIN_XFER_SIZE * Ki, pinnedXferSize_);
|
||||
|
||||
// Disable FP_FAST_FMA defines by default
|
||||
reportFMAF_ = false;
|
||||
reportFMA_ = false;
|
||||
// Disable FP_FAST_FMA defines by default
|
||||
reportFMAF_ = false;
|
||||
reportFMA_ = false;
|
||||
|
||||
// Disable async memory transfers by default
|
||||
asyncMemCopy_ = false;
|
||||
// Disable async memory transfers by default
|
||||
asyncMemCopy_ = false;
|
||||
|
||||
// GPU device by default
|
||||
apuSystem_ = false;
|
||||
// GPU device by default
|
||||
apuSystem_ = false;
|
||||
|
||||
// Disable 64 bit pointers support by default
|
||||
use64BitPtr_ = false;
|
||||
// Disable 64 bit pointers support by default
|
||||
use64BitPtr_ = false;
|
||||
|
||||
// Max alloc size is 16GB
|
||||
maxAllocSize_ = 16 * static_cast<uint64_t>(Gi);
|
||||
// Max alloc size is 16GB
|
||||
maxAllocSize_ = 16 * static_cast<uint64_t>(Gi);
|
||||
|
||||
// Disable memory dependency tracking by default
|
||||
numMemDependencies_ = 0;
|
||||
// Disable memory dependency tracking by default
|
||||
numMemDependencies_ = 0;
|
||||
|
||||
// By default cache isn't present
|
||||
cacheLineSize_ = 0;
|
||||
cacheSize_ = 0;
|
||||
// By default cache isn't present
|
||||
cacheLineSize_ = 0;
|
||||
cacheSize_ = 0;
|
||||
|
||||
// Initialize transfer buffer size to 1MB by default
|
||||
xferBufSize_ = 1024 * Ki;
|
||||
// Initialize transfer buffer size to 1MB by default
|
||||
xferBufSize_ = 1024 * Ki;
|
||||
|
||||
// Use image DMA if requested
|
||||
imageDMA_ = GPU_IMAGE_DMA;
|
||||
// Use image DMA if requested
|
||||
imageDMA_ = GPU_IMAGE_DMA;
|
||||
|
||||
// Disable ASIC specific features by default
|
||||
ciPlus_ = false;
|
||||
viPlus_ = false;
|
||||
aiPlus_ = false;
|
||||
// Disable ASIC specific features by default
|
||||
ciPlus_ = false;
|
||||
viPlus_ = false;
|
||||
aiPlus_ = false;
|
||||
|
||||
// Number of compute rings.
|
||||
numComputeRings_ = 0;
|
||||
// Number of compute rings.
|
||||
numComputeRings_ = 0;
|
||||
|
||||
minWorkloadTime_ = 100; // 0.1 ms
|
||||
maxWorkloadTime_ = 500000; // 500 ms
|
||||
minWorkloadTime_ = 100; // 0.1 ms
|
||||
maxWorkloadTime_ = 500000; // 500 ms
|
||||
|
||||
// Controls tiled images in persistent
|
||||
//!@note IOL for Linux doesn't setup tiling aperture in CMM/QS
|
||||
linearPersistentImage_ = false;
|
||||
// Controls tiled images in persistent
|
||||
//!@note IOL for Linux doesn't setup tiling aperture in CMM/QS
|
||||
linearPersistentImage_ = false;
|
||||
|
||||
useSingleScratch_ = GPU_USE_SINGLE_SCRATCH;
|
||||
useSingleScratch_ = GPU_USE_SINGLE_SCRATCH;
|
||||
|
||||
// SDMA profiling is disabled by default
|
||||
sdmaProfiling_ = false;
|
||||
// SDMA profiling is disabled by default
|
||||
sdmaProfiling_ = false;
|
||||
|
||||
// Device enqueuing settings
|
||||
numDeviceEvents_ = 1024;
|
||||
numWaitEvents_ = 8;
|
||||
// Device enqueuing settings
|
||||
numDeviceEvents_ = 1024;
|
||||
numWaitEvents_ = 8;
|
||||
|
||||
// Disable HSAIL by default
|
||||
hsail_ = false;
|
||||
// Disable HSAIL by default
|
||||
hsail_ = false;
|
||||
|
||||
// Don't support platform atomics by default.
|
||||
svmAtomics_ = false;
|
||||
// Don't support platform atomics by default.
|
||||
svmAtomics_ = false;
|
||||
|
||||
// Use host queue for device enqueuing by default
|
||||
useDeviceQueue_ = GPU_USE_DEVICE_QUEUE;
|
||||
// Use host queue for device enqueuing by default
|
||||
useDeviceQueue_ = GPU_USE_DEVICE_QUEUE;
|
||||
|
||||
// Don't support Denormals for single precision by default
|
||||
singleFpDenorm_ = false;
|
||||
// Don't support Denormals for single precision by default
|
||||
singleFpDenorm_ = false;
|
||||
}
|
||||
|
||||
bool
|
||||
Settings::create(
|
||||
const CALdeviceattribs& calAttr
|
||||
, bool reportAsOCL12Device
|
||||
, bool smallMemSystem
|
||||
)
|
||||
{
|
||||
CALuint target = calAttr.target;
|
||||
uint32_t osVer = 0x0;
|
||||
bool Settings::create(const CALdeviceattribs& calAttr, bool reportAsOCL12Device,
|
||||
bool smallMemSystem) {
|
||||
CALuint target = calAttr.target;
|
||||
uint32_t osVer = 0x0;
|
||||
|
||||
// Disable thread trace by default for all devices
|
||||
threadTraceEnable_ = false;
|
||||
// Disable thread trace by default for all devices
|
||||
threadTraceEnable_ = false;
|
||||
|
||||
if (calAttr.doublePrecision) {
|
||||
// Report FP_FAST_FMA define if double precision HW
|
||||
reportFMA_ = true;
|
||||
// FMA is 1/4 speed on Pitcairn, Cape Verde, Devastator and Scrapper
|
||||
// Bonaire, Kalindi, Spectre and Spooky so disable
|
||||
// FP_FMA_FMAF for those parts in switch below
|
||||
reportFMAF_ = true;
|
||||
}
|
||||
if (calAttr.doublePrecision) {
|
||||
// Report FP_FAST_FMA define if double precision HW
|
||||
reportFMA_ = true;
|
||||
// FMA is 1/4 speed on Pitcairn, Cape Verde, Devastator and Scrapper
|
||||
// Bonaire, Kalindi, Spectre and Spooky so disable
|
||||
// FP_FMA_FMAF for those parts in switch below
|
||||
reportFMAF_ = true;
|
||||
}
|
||||
|
||||
// Update GPU specific settings and info structure if we have any
|
||||
ModifyMaxWorkload modifyMaxWorkload = {0};
|
||||
// Update GPU specific settings and info structure if we have any
|
||||
ModifyMaxWorkload modifyMaxWorkload = {0};
|
||||
|
||||
switch (target) {
|
||||
switch (target) {
|
||||
case CAL_TARGET_RAVEN:
|
||||
// APU systems for AI
|
||||
apuSystem_ = true;
|
||||
// APU systems for AI
|
||||
apuSystem_ = true;
|
||||
case CAL_TARGET_GREENLAND:
|
||||
//TODO: specific codes for AI
|
||||
aiPlus_ = true;
|
||||
// Fall through to VI ...
|
||||
// TODO: specific codes for AI
|
||||
aiPlus_ = true;
|
||||
// Fall through to VI ...
|
||||
case CAL_TARGET_STONEY:
|
||||
if (!aiPlus_) {
|
||||
// Fix BSOD/TDR issues observed on Stoney Win7/8.1/10
|
||||
minWorkloadTime_ = 1000;
|
||||
modifyMaxWorkload.time = 1000; // Decided by experiment
|
||||
modifyMaxWorkload.minorVersion = 1; // Win 7
|
||||
if (!aiPlus_) {
|
||||
// Fix BSOD/TDR issues observed on Stoney Win7/8.1/10
|
||||
minWorkloadTime_ = 1000;
|
||||
modifyMaxWorkload.time = 1000; // Decided by experiment
|
||||
modifyMaxWorkload.minorVersion = 1; // Win 7
|
||||
#if defined(_WIN32)
|
||||
modifyMaxWorkload.comparisonOps = VER_EQUAL; // Limit to Win 7 only
|
||||
modifyMaxWorkload.comparisonOps = VER_EQUAL; // Limit to Win 7 only
|
||||
#endif
|
||||
}
|
||||
}
|
||||
case CAL_TARGET_CARRIZO:
|
||||
if (!aiPlus_) {
|
||||
// APU systems for VI
|
||||
apuSystem_ = true;
|
||||
}
|
||||
if (!aiPlus_) {
|
||||
// APU systems for VI
|
||||
apuSystem_ = true;
|
||||
}
|
||||
case CAL_TARGET_ICELAND:
|
||||
case CAL_TARGET_TONGA:
|
||||
case CAL_TARGET_FIJI:
|
||||
@@ -196,300 +189,291 @@ Settings::create(
|
||||
case CAL_TARGET_BAFFIN:
|
||||
case CAL_TARGET_LEXA:
|
||||
case CAL_TARGET_POLARIS22:
|
||||
// Disable tiling aperture on VI+
|
||||
linearPersistentImage_ = true;
|
||||
// Keep this false even though we have support
|
||||
// singleFpDenorm_ = true;
|
||||
viPlus_ = true;
|
||||
enableExtension(ClKhrFp16);
|
||||
// Fall through to CI ...
|
||||
// Disable tiling aperture on VI+
|
||||
linearPersistentImage_ = true;
|
||||
// Keep this false even though we have support
|
||||
// singleFpDenorm_ = true;
|
||||
viPlus_ = true;
|
||||
enableExtension(ClKhrFp16);
|
||||
// Fall through to CI ...
|
||||
case CAL_TARGET_KALINDI:
|
||||
case CAL_TARGET_SPECTRE:
|
||||
case CAL_TARGET_SPOOKY:
|
||||
case CAL_TARGET_GODAVARI:
|
||||
if (!viPlus_) {
|
||||
// APU systems for CI
|
||||
apuSystem_ = true;
|
||||
// Fix BSOD/TDR issues observed on Kaveri Win7 (EPR#416903)
|
||||
modifyMaxWorkload.time = 250000; // 250ms
|
||||
modifyMaxWorkload.minorVersion = 1; // Win 7
|
||||
if (!viPlus_) {
|
||||
// APU systems for CI
|
||||
apuSystem_ = true;
|
||||
// Fix BSOD/TDR issues observed on Kaveri Win7 (EPR#416903)
|
||||
modifyMaxWorkload.time = 250000; // 250ms
|
||||
modifyMaxWorkload.minorVersion = 1; // Win 7
|
||||
#if defined(_WIN32)
|
||||
modifyMaxWorkload.comparisonOps = VER_EQUAL; // limit to Win 7
|
||||
modifyMaxWorkload.comparisonOps = VER_EQUAL; // limit to Win 7
|
||||
#endif
|
||||
}
|
||||
// Fall through ...
|
||||
}
|
||||
// Fall through ...
|
||||
case CAL_TARGET_BONAIRE:
|
||||
case CAL_TARGET_HAWAII:
|
||||
ciPlus_ = true;
|
||||
sdmaProfiling_ = true;
|
||||
hsail_ = GPU_HSAIL_ENABLE;
|
||||
threadTraceEnable_ = AMD_THREAD_TRACE_ENABLE;
|
||||
// Fall through to SI ...
|
||||
ciPlus_ = true;
|
||||
sdmaProfiling_ = true;
|
||||
hsail_ = GPU_HSAIL_ENABLE;
|
||||
threadTraceEnable_ = AMD_THREAD_TRACE_ENABLE;
|
||||
// Fall through to SI ...
|
||||
case CAL_TARGET_PITCAIRN:
|
||||
case CAL_TARGET_CAPEVERDE:
|
||||
case CAL_TARGET_OLAND:
|
||||
case CAL_TARGET_HAINAN:
|
||||
reportFMAF_ = false;
|
||||
if (target == CAL_TARGET_HAWAII) {
|
||||
reportFMAF_ = true;
|
||||
}
|
||||
// Fall through ...
|
||||
reportFMAF_ = false;
|
||||
if (target == CAL_TARGET_HAWAII) {
|
||||
reportFMAF_ = true;
|
||||
}
|
||||
// Fall through ...
|
||||
case CAL_TARGET_TAHITI:
|
||||
// Cache line size is 64 bytes
|
||||
cacheLineSize_ = 64;
|
||||
// L1 cache size is 16KB
|
||||
cacheSize_ = 16 * Ki;
|
||||
// Cache line size is 64 bytes
|
||||
cacheLineSize_ = 64;
|
||||
// L1 cache size is 16KB
|
||||
cacheSize_ = 16 * Ki;
|
||||
|
||||
if (ciPlus_) {
|
||||
libSelector_ = amd::GPU_Library_CI;
|
||||
if (LP64_SWITCH(false, true)) {
|
||||
oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device ?
|
||||
XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12;
|
||||
}
|
||||
if (smallMemSystem) { //force the dGPU to be 1.2 device for small memory system.
|
||||
if (apuSystem_) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
oclVersion_ = OpenCL12;
|
||||
}
|
||||
}
|
||||
if (GPU_FORCE_OCL20_32BIT) {
|
||||
force32BitOcl20_ = true;
|
||||
oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device ?
|
||||
XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12;
|
||||
}
|
||||
if (OPENCL_VERSION < 200) {
|
||||
oclVersion_ = OpenCL12;
|
||||
}
|
||||
numComputeRings_ = 8;
|
||||
if (ciPlus_) {
|
||||
libSelector_ = amd::GPU_Library_CI;
|
||||
if (LP64_SWITCH(false, true)) {
|
||||
oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device
|
||||
? XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR))
|
||||
: OpenCL12;
|
||||
}
|
||||
else {
|
||||
numComputeRings_ = 2;
|
||||
libSelector_ = amd::GPU_Library_SI;
|
||||
if (smallMemSystem) { // force the dGPU to be 1.2 device for small memory system.
|
||||
if (apuSystem_) {
|
||||
return false;
|
||||
} else {
|
||||
oclVersion_ = OpenCL12;
|
||||
}
|
||||
}
|
||||
if (GPU_FORCE_OCL20_32BIT) {
|
||||
force32BitOcl20_ = true;
|
||||
oclVersion_ = !reportAsOCL12Device && calAttr.isOpenCL200Device
|
||||
? XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR))
|
||||
: OpenCL12;
|
||||
}
|
||||
if (OPENCL_VERSION < 200) {
|
||||
oclVersion_ = OpenCL12;
|
||||
}
|
||||
numComputeRings_ = 8;
|
||||
} else {
|
||||
numComputeRings_ = 2;
|
||||
libSelector_ = amd::GPU_Library_SI;
|
||||
}
|
||||
|
||||
// This needs to be cleaned once 64bit addressing is stable
|
||||
if (oclVersion_ < OpenCL20) {
|
||||
use64BitPtr_ = flagIsDefault(GPU_FORCE_64BIT_PTR) ? LP64_SWITCH(false,
|
||||
calAttr.isWorkstation || hsail_) : GPU_FORCE_64BIT_PTR;
|
||||
}
|
||||
else {
|
||||
if (GPU_FORCE_64BIT_PTR || LP64_SWITCH(false, (hsail_
|
||||
|| (oclVersion_ >= OpenCL20)))) {
|
||||
use64BitPtr_ = true;
|
||||
}
|
||||
// This needs to be cleaned once 64bit addressing is stable
|
||||
if (oclVersion_ < OpenCL20) {
|
||||
use64BitPtr_ = flagIsDefault(GPU_FORCE_64BIT_PTR)
|
||||
? LP64_SWITCH(false, calAttr.isWorkstation || hsail_)
|
||||
: GPU_FORCE_64BIT_PTR;
|
||||
} else {
|
||||
if (GPU_FORCE_64BIT_PTR || LP64_SWITCH(false, (hsail_ || (oclVersion_ >= OpenCL20)))) {
|
||||
use64BitPtr_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (oclVersion_ >= OpenCL20) {
|
||||
supportDepthsRGB_ = true;
|
||||
}
|
||||
if (use64BitPtr_) {
|
||||
if ((GPU_ENABLE_LARGE_ALLOCATION) && (calAttr.isWorkstation)
|
||||
&& (oclVersion_ == OpenCL20)) {
|
||||
maxAllocSize_ = 64ULL * Gi;
|
||||
}
|
||||
else {
|
||||
maxAllocSize_ = 4048 * Mi;
|
||||
}
|
||||
}
|
||||
else {
|
||||
maxAllocSize_ = 3ULL * Gi;
|
||||
if (oclVersion_ >= OpenCL20) {
|
||||
supportDepthsRGB_ = true;
|
||||
}
|
||||
if (use64BitPtr_) {
|
||||
if ((GPU_ENABLE_LARGE_ALLOCATION) && (calAttr.isWorkstation) && (oclVersion_ == OpenCL20)) {
|
||||
maxAllocSize_ = 64ULL * Gi;
|
||||
} else {
|
||||
maxAllocSize_ = 4048 * Mi;
|
||||
}
|
||||
} else {
|
||||
maxAllocSize_ = 3ULL * Gi;
|
||||
}
|
||||
|
||||
supportRA_ = false;
|
||||
partialDispatch_ = GPU_PARTIAL_DISPATCH;
|
||||
numMemDependencies_ = GPU_NUM_MEM_DEPENDENCY;
|
||||
supportRA_ = false;
|
||||
partialDispatch_ = GPU_PARTIAL_DISPATCH;
|
||||
numMemDependencies_ = GPU_NUM_MEM_DEPENDENCY;
|
||||
|
||||
enableExtension(ClKhrInt64BaseAtomics);
|
||||
enableExtension(ClKhrInt64ExtendedAtomics);
|
||||
enableExtension(ClKhrImage2dFromBuffer);
|
||||
break;
|
||||
enableExtension(ClKhrInt64BaseAtomics);
|
||||
enableExtension(ClKhrInt64ExtendedAtomics);
|
||||
enableExtension(ClKhrImage2dFromBuffer);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unknown ASIC type!");
|
||||
return false;
|
||||
}
|
||||
assert(0 && "Unknown ASIC type!");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (modifyMaxWorkload.time > 0) {
|
||||
OSVERSIONINFOEX versionInfo = { 0 };
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
versionInfo.dwMajorVersion = 6;
|
||||
versionInfo.dwMinorVersion = modifyMaxWorkload.minorVersion;
|
||||
if (modifyMaxWorkload.time > 0) {
|
||||
OSVERSIONINFOEX versionInfo = {0};
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
versionInfo.dwMajorVersion = 6;
|
||||
versionInfo.dwMinorVersion = modifyMaxWorkload.minorVersion;
|
||||
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, modifyMaxWorkload.comparisonOps);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, modifyMaxWorkload.comparisonOps);
|
||||
if (VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask)) {
|
||||
maxWorkloadTime_ = modifyMaxWorkload.time;
|
||||
}
|
||||
DWORDLONG conditionMask = 0;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, modifyMaxWorkload.comparisonOps);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, modifyMaxWorkload.comparisonOps);
|
||||
if (VerifyVersionInfo(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask)) {
|
||||
maxWorkloadTime_ = modifyMaxWorkload.time;
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
}
|
||||
#endif // defined(_WIN32)
|
||||
|
||||
// Enable atomics support
|
||||
enableExtension(ClKhrGlobalInt32BaseAtomics);
|
||||
enableExtension(ClKhrGlobalInt32ExtendedAtomics);
|
||||
enableExtension(ClKhrLocalInt32BaseAtomics);
|
||||
enableExtension(ClKhrLocalInt32ExtendedAtomics);
|
||||
enableExtension(ClKhrByteAddressableStore);
|
||||
enableExtension(ClKhrGlSharing);
|
||||
enableExtension(ClKhrGlEvent);
|
||||
enableExtension(ClAmdMediaOps);
|
||||
enableExtension(ClAmdMediaOps2);
|
||||
enableExtension(ClAmdPopcnt);
|
||||
enableExtension(ClKhr3DImageWrites);
|
||||
enableExtension(ClAmdVec3);
|
||||
enableExtension(ClAmdPrintf);
|
||||
// Enable some platform extensions
|
||||
enableExtension(ClAmdDeviceAttributeQuery);
|
||||
enableExtension(ClKhrSpir);
|
||||
enableExtension(ClAMDLiquidFlash);
|
||||
// Enable atomics support
|
||||
enableExtension(ClKhrGlobalInt32BaseAtomics);
|
||||
enableExtension(ClKhrGlobalInt32ExtendedAtomics);
|
||||
enableExtension(ClKhrLocalInt32BaseAtomics);
|
||||
enableExtension(ClKhrLocalInt32ExtendedAtomics);
|
||||
enableExtension(ClKhrByteAddressableStore);
|
||||
enableExtension(ClKhrGlSharing);
|
||||
enableExtension(ClKhrGlEvent);
|
||||
enableExtension(ClAmdMediaOps);
|
||||
enableExtension(ClAmdMediaOps2);
|
||||
enableExtension(ClAmdPopcnt);
|
||||
enableExtension(ClKhr3DImageWrites);
|
||||
enableExtension(ClAmdVec3);
|
||||
enableExtension(ClAmdPrintf);
|
||||
// Enable some platform extensions
|
||||
enableExtension(ClAmdDeviceAttributeQuery);
|
||||
enableExtension(ClKhrSpir);
|
||||
enableExtension(ClAMDLiquidFlash);
|
||||
|
||||
hwLDSSize_ = 32 * Ki;
|
||||
hwLDSSize_ = 32 * Ki;
|
||||
|
||||
imageSupport_ = true;
|
||||
imageSupport_ = true;
|
||||
|
||||
// Use kernels for blit if appropriate
|
||||
blitEngine_ = BlitEngineKernel;
|
||||
// Use kernels for blit if appropriate
|
||||
blitEngine_ = BlitEngineKernel;
|
||||
|
||||
hostMemDirectAccess_ |= HostMemBuffer;
|
||||
// HW doesn't support untiled image writes
|
||||
// hostMemDirectAccess_ |= HostMemImage;
|
||||
hostMemDirectAccess_ |= HostMemBuffer;
|
||||
// HW doesn't support untiled image writes
|
||||
// hostMemDirectAccess_ |= HostMemImage;
|
||||
|
||||
asyncMemCopy_ = true;
|
||||
asyncMemCopy_ = true;
|
||||
|
||||
// Make sure device actually supports double precision
|
||||
doublePrecision_ = (calAttr.doublePrecision) ? doublePrecision_ : false;
|
||||
if (doublePrecision_) {
|
||||
// Enable KHR double precision extension
|
||||
enableExtension(ClKhrFp64);
|
||||
}
|
||||
// Make sure device actually supports double precision
|
||||
doublePrecision_ = (calAttr.doublePrecision) ? doublePrecision_ : false;
|
||||
if (doublePrecision_) {
|
||||
// Enable KHR double precision extension
|
||||
enableExtension(ClKhrFp64);
|
||||
}
|
||||
|
||||
if (calAttr.doublePrecision) {
|
||||
// Enable AMD double precision extension
|
||||
doublePrecision_ = true;
|
||||
enableExtension(ClAmdFp64);
|
||||
}
|
||||
if (calAttr.doublePrecision) {
|
||||
// Enable AMD double precision extension
|
||||
doublePrecision_ = true;
|
||||
enableExtension(ClAmdFp64);
|
||||
}
|
||||
|
||||
if (calAttr.totalSDIHeap > 0) {
|
||||
//Enable bus addressable memory extension
|
||||
enableExtension(ClAMDBusAddressableMemory);
|
||||
}
|
||||
if (calAttr.totalSDIHeap > 0) {
|
||||
// Enable bus addressable memory extension
|
||||
enableExtension(ClAMDBusAddressableMemory);
|
||||
}
|
||||
|
||||
if (calAttr.longIdleDetect) {
|
||||
// KMD is unable to detect if we map the visible memory for CPU access, so
|
||||
// accessing persistent staged buffer may fail if LongIdleDetct is enabled.
|
||||
disablePersistent_ = true;
|
||||
}
|
||||
if (calAttr.longIdleDetect) {
|
||||
// KMD is unable to detect if we map the visible memory for CPU access, so
|
||||
// accessing persistent staged buffer may fail if LongIdleDetct is enabled.
|
||||
disablePersistent_ = true;
|
||||
}
|
||||
|
||||
svmFineGrainSystem_ = calAttr.isSVMFineGrainSystem;
|
||||
svmFineGrainSystem_ = calAttr.isSVMFineGrainSystem;
|
||||
|
||||
svmAtomics_ = (calAttr.svmAtomics || calAttr.isSVMFineGrainSystem) ? true : false;
|
||||
svmAtomics_ = (calAttr.svmAtomics || calAttr.isSVMFineGrainSystem) ? true : false;
|
||||
|
||||
#if defined(_WIN32)
|
||||
enableExtension(ClKhrD3d9Sharing);
|
||||
enableExtension(ClKhrD3d10Sharing);
|
||||
enableExtension(ClKhrD3d11Sharing);
|
||||
#endif // _WIN32
|
||||
enableExtension(ClKhrD3d9Sharing);
|
||||
enableExtension(ClKhrD3d10Sharing);
|
||||
enableExtension(ClKhrD3d11Sharing);
|
||||
#endif // _WIN32
|
||||
|
||||
// Enable some OpenCL 2.0 extensions
|
||||
if (oclVersion_ >= OpenCL20) {
|
||||
enableExtension(ClKhrGLDepthImages);
|
||||
enableExtension(ClKhrSubGroups);
|
||||
enableExtension(ClKhrDepthImages);
|
||||
// Enable some OpenCL 2.0 extensions
|
||||
if (oclVersion_ >= OpenCL20) {
|
||||
enableExtension(ClKhrGLDepthImages);
|
||||
enableExtension(ClKhrSubGroups);
|
||||
enableExtension(ClKhrDepthImages);
|
||||
|
||||
if (GPU_MIPMAP) {
|
||||
enableExtension(ClKhrMipMapImage);
|
||||
enableExtension(ClKhrMipMapImageWrites);
|
||||
}
|
||||
|
||||
// Enable HW debug
|
||||
if (GPU_ENABLE_HW_DEBUG) {
|
||||
enableHwDebug_ = true;
|
||||
}
|
||||
if (GPU_MIPMAP) {
|
||||
enableExtension(ClKhrMipMapImage);
|
||||
enableExtension(ClKhrMipMapImageWrites);
|
||||
}
|
||||
|
||||
if (apuSystem_ &&
|
||||
((calAttr.totalVisibleHeap + calAttr.totalInvisibleHeap) < 150)) {
|
||||
remoteAlloc_ = true;
|
||||
// Enable HW debug
|
||||
if (GPU_ENABLE_HW_DEBUG) {
|
||||
enableHwDebug_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Save resource cache size
|
||||
if (apuSystem_ && ((calAttr.totalVisibleHeap + calAttr.totalInvisibleHeap) < 150)) {
|
||||
remoteAlloc_ = true;
|
||||
}
|
||||
|
||||
// Save resource cache size
|
||||
#ifdef ATI_OS_LINUX
|
||||
// Due to EPR#406216, set the default value for Linux for now
|
||||
resourceCacheSize_ = GPU_RESOURCE_CACHE_SIZE * Mi;
|
||||
// Due to EPR#406216, set the default value for Linux for now
|
||||
resourceCacheSize_ = GPU_RESOURCE_CACHE_SIZE * Mi;
|
||||
#else
|
||||
if (remoteAlloc_) {
|
||||
resourceCacheSize_ = std::max((calAttr.uncachedRemoteRAM / 8) * Mi,
|
||||
GPU_RESOURCE_CACHE_SIZE * Mi);
|
||||
}
|
||||
else {
|
||||
resourceCacheSize_ = std::max((calAttr.localRAM / 8) * Mi,
|
||||
GPU_RESOURCE_CACHE_SIZE * Mi);
|
||||
}
|
||||
resourceCacheSize_ = std::min(resourceCacheSize_, 512 * Mi);
|
||||
if (remoteAlloc_) {
|
||||
resourceCacheSize_ =
|
||||
std::max((calAttr.uncachedRemoteRAM / 8) * Mi, GPU_RESOURCE_CACHE_SIZE * Mi);
|
||||
} else {
|
||||
resourceCacheSize_ = std::max((calAttr.localRAM / 8) * Mi, GPU_RESOURCE_CACHE_SIZE * Mi);
|
||||
}
|
||||
resourceCacheSize_ = std::min(resourceCacheSize_, 512 * Mi);
|
||||
#endif
|
||||
|
||||
// Override current device settings
|
||||
override();
|
||||
// Override current device settings
|
||||
override();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Settings::override()
|
||||
{
|
||||
// Limit reported workgroup size
|
||||
if (GPU_MAX_WORKGROUP_SIZE != 0) {
|
||||
maxWorkGroupSize_ = GPU_MAX_WORKGROUP_SIZE;
|
||||
}
|
||||
void Settings::override() {
|
||||
// Limit reported workgroup size
|
||||
if (GPU_MAX_WORKGROUP_SIZE != 0) {
|
||||
maxWorkGroupSize_ = GPU_MAX_WORKGROUP_SIZE;
|
||||
}
|
||||
|
||||
// Override blit engine type
|
||||
if (GPU_BLIT_ENGINE_TYPE != BlitEngineDefault) {
|
||||
blitEngine_ = GPU_BLIT_ENGINE_TYPE;
|
||||
}
|
||||
// Override blit engine type
|
||||
if (GPU_BLIT_ENGINE_TYPE != BlitEngineDefault) {
|
||||
blitEngine_ = GPU_BLIT_ENGINE_TYPE;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(DEBUG_GPU_FLAGS)) {
|
||||
debugFlags_ = DEBUG_GPU_FLAGS;
|
||||
}
|
||||
if (!flagIsDefault(DEBUG_GPU_FLAGS)) {
|
||||
debugFlags_ = DEBUG_GPU_FLAGS;
|
||||
}
|
||||
|
||||
// Check async memory transfer
|
||||
if (!flagIsDefault(GPU_ASYNC_MEM_COPY)) {
|
||||
asyncMemCopy_ = GPU_ASYNC_MEM_COPY;
|
||||
}
|
||||
// Check async memory transfer
|
||||
if (!flagIsDefault(GPU_ASYNC_MEM_COPY)) {
|
||||
asyncMemCopy_ = GPU_ASYNC_MEM_COPY;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(DEBUG_GPU_FLAGS)) {
|
||||
debugFlags_ = DEBUG_GPU_FLAGS;
|
||||
}
|
||||
if (!flagIsDefault(DEBUG_GPU_FLAGS)) {
|
||||
debugFlags_ = DEBUG_GPU_FLAGS;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(GPU_XFER_BUFFER_SIZE)) {
|
||||
xferBufSize_ = GPU_XFER_BUFFER_SIZE * Ki;
|
||||
}
|
||||
if (!flagIsDefault(GPU_XFER_BUFFER_SIZE)) {
|
||||
xferBufSize_ = GPU_XFER_BUFFER_SIZE * Ki;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(GPU_USE_SYNC_OBJECTS)) {
|
||||
syncObject_ = GPU_USE_SYNC_OBJECTS;
|
||||
}
|
||||
if (!flagIsDefault(GPU_USE_SYNC_OBJECTS)) {
|
||||
syncObject_ = GPU_USE_SYNC_OBJECTS;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(GPU_NUM_COMPUTE_RINGS)) {
|
||||
numComputeRings_ = GPU_NUM_COMPUTE_RINGS;
|
||||
}
|
||||
if (!flagIsDefault(GPU_NUM_COMPUTE_RINGS)) {
|
||||
numComputeRings_ = GPU_NUM_COMPUTE_RINGS;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(GPU_RESOURCE_CACHE_SIZE)) {
|
||||
resourceCacheSize_ = GPU_RESOURCE_CACHE_SIZE * Mi;
|
||||
}
|
||||
if (!flagIsDefault(GPU_RESOURCE_CACHE_SIZE)) {
|
||||
resourceCacheSize_ = GPU_RESOURCE_CACHE_SIZE * Mi;
|
||||
}
|
||||
|
||||
if (!flagIsDefault(AMD_GPU_FORCE_SINGLE_FP_DENORM)) {
|
||||
switch (AMD_GPU_FORCE_SINGLE_FP_DENORM) {
|
||||
case 0:
|
||||
singleFpDenorm_ = false;
|
||||
break;
|
||||
case 1:
|
||||
singleFpDenorm_ = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!flagIsDefault(AMD_GPU_FORCE_SINGLE_FP_DENORM)) {
|
||||
switch (AMD_GPU_FORCE_SINGLE_FP_DENORM) {
|
||||
case 0:
|
||||
singleFpDenorm_ = false;
|
||||
break;
|
||||
case 1:
|
||||
singleFpDenorm_ = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -15,111 +15,108 @@
|
||||
namespace gpu {
|
||||
|
||||
//! Device settings
|
||||
class Settings : public device::Settings
|
||||
{
|
||||
public:
|
||||
//! Debug GPU flags
|
||||
enum DebugGpuFlags
|
||||
{
|
||||
CheckForILSource = 0x00000001,
|
||||
StubCLPrograms = 0x00000002, //!< Enables OpenCL programs stubbing
|
||||
LockGlobalMemory = 0x00000004,
|
||||
class Settings : public device::Settings {
|
||||
public:
|
||||
//! Debug GPU flags
|
||||
enum DebugGpuFlags {
|
||||
CheckForILSource = 0x00000001,
|
||||
StubCLPrograms = 0x00000002, //!< Enables OpenCL programs stubbing
|
||||
LockGlobalMemory = 0x00000004,
|
||||
};
|
||||
|
||||
enum BlitEngineType {
|
||||
BlitEngineDefault = 0x00000000,
|
||||
BlitEngineHost = 0x00000001,
|
||||
BlitEngineCAL = 0x00000002,
|
||||
BlitEngineKernel = 0x00000003,
|
||||
};
|
||||
|
||||
enum HostMemFlags {
|
||||
HostMemDisable = 0x00000000,
|
||||
HostMemBuffer = 0x00000001,
|
||||
HostMemImage = 0x00000002,
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint remoteAlloc_ : 1; //!< Allocate remote memory for the heap
|
||||
uint stagedXferRead_ : 1; //!< Uses a staged buffer read
|
||||
uint stagedXferWrite_ : 1; //!< Uses a staged buffer write
|
||||
uint disablePersistent_ : 1; //!< Disables using persistent memory for staging
|
||||
uint imageSupport_ : 1; //!< Report images support
|
||||
uint doublePrecision_ : 1; //!< Enables double precision support
|
||||
uint reportFMAF_ : 1; //!< Report FP_FAST_FMAF define in CL program
|
||||
uint reportFMA_ : 1; //!< Report FP_FAST_FMA define in CL program
|
||||
uint use64BitPtr_ : 1; //!< Use 64bit pointers on GPU
|
||||
uint force32BitOcl20_ : 1; //!< Force 32bit apps to take CLANG/HSAIL path on GPU
|
||||
uint imageDMA_ : 1; //!< Enable direct image DMA transfers
|
||||
uint syncObject_ : 1; //!< Enable syncobject
|
||||
uint ciPlus_ : 1; //!< CI and post CI features
|
||||
uint viPlus_ : 1; //!< VI and post VI features
|
||||
uint aiPlus_ : 1; //!< AI and post AI features
|
||||
uint threadTraceEnable_ : 1; //!< Thread trace enable
|
||||
uint linearPersistentImage_ : 1; //!< Allocates linear images in persistent
|
||||
uint useSingleScratch_ : 1; //!< Allocates single scratch per device
|
||||
uint sdmaProfiling_ : 1; //!< Enables SDMA profiling
|
||||
uint hsail_ : 1; //!< Enables HSAIL compilation
|
||||
uint stagingWritePersistent_ : 1; //!< Enables persistent writes
|
||||
uint svmAtomics_ : 1; //!< SVM device atomics
|
||||
uint svmFineGrainSystem_ : 1; //!< SVM fine grain system support
|
||||
uint apuSystem_ : 1; //!< Device is APU system with shared memory
|
||||
uint asyncMemCopy_ : 1; //!< Use async memory transfers
|
||||
uint useDeviceQueue_ : 1; //!< Submit to separate device queue
|
||||
uint singleFpDenorm_ : 1; //!< Support Single FP Denorm
|
||||
uint reserved_ : 5;
|
||||
};
|
||||
uint value_;
|
||||
};
|
||||
|
||||
enum BlitEngineType
|
||||
{
|
||||
BlitEngineDefault = 0x00000000,
|
||||
BlitEngineHost = 0x00000001,
|
||||
BlitEngineCAL = 0x00000002,
|
||||
BlitEngineKernel = 0x00000003,
|
||||
};
|
||||
|
||||
enum HostMemFlags
|
||||
{
|
||||
HostMemDisable = 0x00000000,
|
||||
HostMemBuffer = 0x00000001,
|
||||
HostMemImage = 0x00000002,
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint remoteAlloc_: 1; //!< Allocate remote memory for the heap
|
||||
uint stagedXferRead_: 1; //!< Uses a staged buffer read
|
||||
uint stagedXferWrite_: 1; //!< Uses a staged buffer write
|
||||
uint disablePersistent_: 1; //!< Disables using persistent memory for staging
|
||||
uint imageSupport_: 1; //!< Report images support
|
||||
uint doublePrecision_: 1; //!< Enables double precision support
|
||||
uint reportFMAF_: 1; //!< Report FP_FAST_FMAF define in CL program
|
||||
uint reportFMA_: 1; //!< Report FP_FAST_FMA define in CL program
|
||||
uint use64BitPtr_: 1; //!< Use 64bit pointers on GPU
|
||||
uint force32BitOcl20_: 1; //!< Force 32bit apps to take CLANG/HSAIL path on GPU
|
||||
uint imageDMA_: 1; //!< Enable direct image DMA transfers
|
||||
uint syncObject_: 1; //!< Enable syncobject
|
||||
uint ciPlus_: 1; //!< CI and post CI features
|
||||
uint viPlus_: 1; //!< VI and post VI features
|
||||
uint aiPlus_: 1; //!< AI and post AI features
|
||||
uint threadTraceEnable_: 1; //!< Thread trace enable
|
||||
uint linearPersistentImage_: 1; //!< Allocates linear images in persistent
|
||||
uint useSingleScratch_: 1; //!< Allocates single scratch per device
|
||||
uint sdmaProfiling_: 1; //!< Enables SDMA profiling
|
||||
uint hsail_: 1; //!< Enables HSAIL compilation
|
||||
uint stagingWritePersistent_: 1; //!< Enables persistent writes
|
||||
uint svmAtomics_: 1; //!< SVM device atomics
|
||||
uint svmFineGrainSystem_: 1; //!< SVM fine grain system support
|
||||
uint apuSystem_: 1; //!< Device is APU system with shared memory
|
||||
uint asyncMemCopy_: 1; //!< Use async memory transfers
|
||||
uint useDeviceQueue_: 1; //!< Submit to separate device queue
|
||||
uint singleFpDenorm_: 1; //!< Support Single FP Denorm
|
||||
uint reserved_: 5;
|
||||
};
|
||||
uint value_;
|
||||
};
|
||||
|
||||
uint oclVersion_; //!< Reported OpenCL version support
|
||||
uint debugFlags_; //!< Debug GPU flags
|
||||
size_t stagedXferSize_; //!< Staged buffer size
|
||||
uint maxRenames_; //!< Maximum number of possible renames
|
||||
uint maxRenameSize_; //!< Maximum size for all renames
|
||||
uint hwLDSSize_; //!< HW local data store size
|
||||
uint maxWorkGroupSize_; //!< Requested workgroup size for this device
|
||||
uint hostMemDirectAccess_; //!< Enables direct access to the host memory
|
||||
amd::LibrarySelector libSelector_; //!< Select linking libraries for compiler
|
||||
uint workloadSplitSize_; //!< Workload split size
|
||||
uint minWorkloadTime_; //!< Minimal workload time in 0.1 ms
|
||||
uint maxWorkloadTime_; //!< Maximum workload time in 0.1 ms
|
||||
uint blitEngine_; //!< Blit engine type
|
||||
size_t pinnedXferSize_; //!< Pinned buffer size for transfer
|
||||
size_t pinnedMinXferSize_; //!< Minimal buffer size for pinned transfer
|
||||
size_t resourceCacheSize_; //!< Resource cache size in MB
|
||||
uint64_t maxAllocSize_; //!< Maximum single allocation size
|
||||
size_t numMemDependencies_;//!< The array size for memory dependencies tracking
|
||||
uint cacheLineSize_; //!< Cache line size in bytes
|
||||
uint cacheSize_; //!< L1 cache size in bytes
|
||||
size_t xferBufSize_; //!< Transfer buffer size for image copy optimization
|
||||
uint numComputeRings_; //!< 0 - disabled, 1 , 2,.. - the number of compute rings
|
||||
uint numDeviceEvents_; //!< The number of device events
|
||||
uint numWaitEvents_; //!< The number of wait events for device enqueue
|
||||
uint oclVersion_; //!< Reported OpenCL version support
|
||||
uint debugFlags_; //!< Debug GPU flags
|
||||
size_t stagedXferSize_; //!< Staged buffer size
|
||||
uint maxRenames_; //!< Maximum number of possible renames
|
||||
uint maxRenameSize_; //!< Maximum size for all renames
|
||||
uint hwLDSSize_; //!< HW local data store size
|
||||
uint maxWorkGroupSize_; //!< Requested workgroup size for this device
|
||||
uint hostMemDirectAccess_; //!< Enables direct access to the host memory
|
||||
amd::LibrarySelector libSelector_; //!< Select linking libraries for compiler
|
||||
uint workloadSplitSize_; //!< Workload split size
|
||||
uint minWorkloadTime_; //!< Minimal workload time in 0.1 ms
|
||||
uint maxWorkloadTime_; //!< Maximum workload time in 0.1 ms
|
||||
uint blitEngine_; //!< Blit engine type
|
||||
size_t pinnedXferSize_; //!< Pinned buffer size for transfer
|
||||
size_t pinnedMinXferSize_; //!< Minimal buffer size for pinned transfer
|
||||
size_t resourceCacheSize_; //!< Resource cache size in MB
|
||||
uint64_t maxAllocSize_; //!< Maximum single allocation size
|
||||
size_t numMemDependencies_; //!< The array size for memory dependencies tracking
|
||||
uint cacheLineSize_; //!< Cache line size in bytes
|
||||
uint cacheSize_; //!< L1 cache size in bytes
|
||||
size_t xferBufSize_; //!< Transfer buffer size for image copy optimization
|
||||
uint numComputeRings_; //!< 0 - disabled, 1 , 2,.. - the number of compute rings
|
||||
uint numDeviceEvents_; //!< The number of device events
|
||||
uint numWaitEvents_; //!< The number of wait events for device enqueue
|
||||
|
||||
|
||||
//! Default constructor
|
||||
Settings();
|
||||
//! Default constructor
|
||||
Settings();
|
||||
|
||||
//! Creates settings
|
||||
bool create(
|
||||
const CALdeviceattribs& calAttr //!< CAL attributes structure
|
||||
, bool reportAsOCL12Device = false //!< Report As OpenCL1.2 Device
|
||||
, bool smallMemSystem = false //!< report the sys memory is small
|
||||
);
|
||||
//! Creates settings
|
||||
bool create(const CALdeviceattribs& calAttr //!< CAL attributes structure
|
||||
,
|
||||
bool reportAsOCL12Device = false //!< Report As OpenCL1.2 Device
|
||||
,
|
||||
bool smallMemSystem = false //!< report the sys memory is small
|
||||
);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Settings(const Settings&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Settings(const Settings&);
|
||||
|
||||
//! Disable assignment
|
||||
Settings& operator=(const Settings&);
|
||||
//! Disable assignment
|
||||
Settings& operator=(const Settings&);
|
||||
|
||||
//! Overrides current settings based on registry/environment
|
||||
void override();
|
||||
//! Overrides current settings based on registry/environment
|
||||
void override();
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
@@ -8,60 +8,54 @@
|
||||
namespace gpu {
|
||||
|
||||
CalThreadTraceReference::~CalThreadTraceReference() {
|
||||
// The thread trace object is always associated with a particular queue,
|
||||
// so we have to lock just this queue
|
||||
amd::ScopedLock lock(gpu_.execution());
|
||||
// The thread trace object is always associated with a particular queue,
|
||||
// so we have to lock just this queue
|
||||
amd::ScopedLock lock(gpu_.execution());
|
||||
|
||||
if (0 != threadTrace_) {
|
||||
//gpu().cs()->destroyQuery(gslThreadTrace());
|
||||
}
|
||||
if (0 != threadTrace_) {
|
||||
// gpu().cs()->destroyQuery(gslThreadTrace());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ThreadTrace::~ThreadTrace()
|
||||
{
|
||||
if (calRef_ == NULL) {
|
||||
return;
|
||||
}
|
||||
for(uint i = 0; i < amdThreadTraceMemObjsNum_;++i) {
|
||||
threadTraceBufferObjs_[i]->attachMemObject(gpu().cs(), NULL, 0, 0, 0, i);
|
||||
gpu().cs()->destroyShaderTraceBuffer(threadTraceBufferObjs_[i]);
|
||||
}
|
||||
ThreadTrace::~ThreadTrace() {
|
||||
if (calRef_ == NULL) {
|
||||
return;
|
||||
}
|
||||
for (uint i = 0; i < amdThreadTraceMemObjsNum_; ++i) {
|
||||
threadTraceBufferObjs_[i]->attachMemObject(gpu().cs(), NULL, 0, 0, 0, i);
|
||||
gpu().cs()->destroyShaderTraceBuffer(threadTraceBufferObjs_[i]);
|
||||
}
|
||||
|
||||
// Release the thread trace reference object
|
||||
//calRef_->release();
|
||||
// Release the thread trace reference object
|
||||
// calRef_->release();
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadTrace::create(CalThreadTraceReference* calRef)
|
||||
{
|
||||
assert(&gpu() == &calRef->gpu());
|
||||
bool ThreadTrace::create(CalThreadTraceReference* calRef) {
|
||||
assert(&gpu() == &calRef->gpu());
|
||||
|
||||
calRef_ = calRef;
|
||||
threadTrace_ = calRef->gslThreadTrace();
|
||||
calRef_ = calRef;
|
||||
threadTrace_ = calRef->gslThreadTrace();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadTrace::info(uint infoType, uint* info, uint infoSize) const
|
||||
{
|
||||
switch (infoType) {
|
||||
bool ThreadTrace::info(uint infoType, uint* info, uint infoSize) const {
|
||||
switch (infoType) {
|
||||
case CL_THREAD_TRACE_BUFFERS_SIZE: {
|
||||
if (infoSize < amdThreadTraceMemObjsNum_) {
|
||||
LogError("The amount of buffers should be equal to the amount of Shader Engines");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
gslThreadTrace()->GetResultAll(gpu().cs(), info);
|
||||
}
|
||||
break;
|
||||
if (infoSize < amdThreadTraceMemObjsNum_) {
|
||||
LogError("The amount of buffers should be equal to the amount of Shader Engines");
|
||||
return false;
|
||||
} else {
|
||||
gslThreadTrace()->GetResultAll(gpu().cs(), info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogError("Wrong ThreadTrace::getInfo parameter");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
LogError("Wrong ThreadTrace::getInfo parameter");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -14,125 +14,118 @@ namespace gpu {
|
||||
|
||||
class VirtualGPU;
|
||||
|
||||
class CalThreadTraceReference : public amd::ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
CalThreadTraceReference(
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
gslQueryObject gslThreadTrace) //!< GSL query thread trace object
|
||||
: gpu_(gpu)
|
||||
, threadTrace_(gslThreadTrace){}
|
||||
class CalThreadTraceReference : public amd::ReferenceCountedObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
CalThreadTraceReference(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
gslQueryObject gslThreadTrace) //!< GSL query thread trace object
|
||||
: gpu_(gpu),
|
||||
threadTrace_(gslThreadTrace) {}
|
||||
|
||||
//! Get GSL thread race object
|
||||
gslQueryObject gslThreadTrace() const { return threadTrace_; }
|
||||
//! Get GSL thread race object
|
||||
gslQueryObject gslThreadTrace() const { return threadTrace_; }
|
||||
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalThreadTraceReference();
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalThreadTraceReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalThreadTraceReference(const CalThreadTraceReference&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalThreadTraceReference(const CalThreadTraceReference&);
|
||||
|
||||
//! Disable operator=
|
||||
CalThreadTraceReference& operator=(const CalThreadTraceReference&);
|
||||
//! Disable operator=
|
||||
CalThreadTraceReference& operator=(const CalThreadTraceReference&);
|
||||
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
gslQueryObject threadTrace_; //!< GSL thread trace query object
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
gslQueryObject threadTrace_; //!< GSL thread trace query object
|
||||
};
|
||||
|
||||
//! ThreadTrace implementation on GPU
|
||||
class ThreadTrace : public device::ThreadTrace
|
||||
{
|
||||
public:
|
||||
class ThreadTrace : public device::ThreadTrace {
|
||||
public:
|
||||
//! Destructor for the GPU ThreadTrace object
|
||||
virtual ~ThreadTrace();
|
||||
|
||||
//! Destructor for the GPU ThreadTrace object
|
||||
virtual ~ThreadTrace();
|
||||
//! Creates the current object
|
||||
bool create(CalThreadTraceReference* calRef //!< Reference ThreadTrace
|
||||
);
|
||||
|
||||
//! Creates the current object
|
||||
bool create(
|
||||
CalThreadTraceReference* calRef //!< Reference ThreadTrace
|
||||
);
|
||||
//! Returns the GPU device, associated with the current object
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Returns the GPU device, associated with the current object
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
//! Constructor for the GPU ThreadTrace object
|
||||
ThreadTrace(
|
||||
Device& device, //!< A GPU device object
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
uint amdThreadTraceMemObjsNum)
|
||||
: gpuDevice_(device)
|
||||
, gpu_(gpu)
|
||||
, calRef_(NULL)
|
||||
, index_(0)
|
||||
, amdThreadTraceMemObjsNum_(amdThreadTraceMemObjsNum)
|
||||
{
|
||||
threadTraceBufferObjs_ = new gslShaderTraceBufferObject[amdThreadTraceMemObjsNum];
|
||||
for (uint i = 0; i < amdThreadTraceMemObjsNum;++i) {
|
||||
threadTraceBufferObjs_[i] = gpu.cs()->createShaderTraceBuffer();
|
||||
}
|
||||
//! Constructor for the GPU ThreadTrace object
|
||||
ThreadTrace(Device& device, //!< A GPU device object
|
||||
VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
uint amdThreadTraceMemObjsNum)
|
||||
: gpuDevice_(device),
|
||||
gpu_(gpu),
|
||||
calRef_(NULL),
|
||||
index_(0),
|
||||
amdThreadTraceMemObjsNum_(amdThreadTraceMemObjsNum) {
|
||||
threadTraceBufferObjs_ = new gslShaderTraceBufferObject[amdThreadTraceMemObjsNum];
|
||||
for (uint i = 0; i < amdThreadTraceMemObjsNum; ++i) {
|
||||
threadTraceBufferObjs_[i] = gpu.cs()->createShaderTraceBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns the specific information about the thread trace object
|
||||
bool info(
|
||||
uint infoType, //!< The type of returned information
|
||||
uint* info, //!< The returned information
|
||||
uint infoSize //!< The size of returned information
|
||||
) const;
|
||||
//! Returns the specific information about the thread trace object
|
||||
bool info(uint infoType, //!< The type of returned information
|
||||
uint* info, //!< The returned information
|
||||
uint infoSize //!< The size of returned information
|
||||
) const;
|
||||
|
||||
//! Set the ThreadTrace memory buffer size
|
||||
void setMemBufferSizeTT(uint memBufferSizeTT) { memBufferSizeTT_ = memBufferSizeTT;}
|
||||
//! Set the ThreadTrace memory buffer size
|
||||
void setMemBufferSizeTT(uint memBufferSizeTT) { memBufferSizeTT_ = memBufferSizeTT; }
|
||||
|
||||
//! Set isNewBufferBinded_ to true/false if new buffer was binded/unbinded respectively
|
||||
void setNewBufferBinded(bool isNewBufferBinded) { isNewBufferBinded_ = isNewBufferBinded; }
|
||||
//! Set isNewBufferBinded_ to true/false if new buffer was binded/unbinded respectively
|
||||
void setNewBufferBinded(bool isNewBufferBinded) { isNewBufferBinded_ = isNewBufferBinded; }
|
||||
|
||||
//! Attach gslMemObject to the TreadTrace buffer
|
||||
void attachMemToThreadTraceBuffer();
|
||||
//! Attach gslMemObject to the TreadTrace buffer
|
||||
void attachMemToThreadTraceBuffer();
|
||||
|
||||
void setMemObj(size_t memObjSize,std::vector<amd::Memory*> memObj)
|
||||
{
|
||||
memObj_ = memObj;
|
||||
memBufferSizeTT_ = memObjSize;
|
||||
}
|
||||
//! Get GSL thread trace object
|
||||
gslQueryObject gslThreadTrace() const { return threadTrace_; }
|
||||
void setMemObj(size_t memObjSize, std::vector<amd::Memory*> memObj) {
|
||||
memObj_ = memObj;
|
||||
memBufferSizeTT_ = memObjSize;
|
||||
}
|
||||
//! Get GSL thread trace object
|
||||
gslQueryObject gslThreadTrace() const { return threadTrace_; }
|
||||
|
||||
//! Get GSL Thread Trace Buffer objects
|
||||
gslShaderTraceBufferObject* getThreadTraceBufferObjects() {return threadTraceBufferObjs_;}
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
ThreadTrace(const ThreadTrace&);
|
||||
//! Get GSL Thread Trace Buffer objects
|
||||
gslShaderTraceBufferObject* getThreadTraceBufferObjects() { return threadTraceBufferObjs_; }
|
||||
|
||||
//! Disable default operator=
|
||||
ThreadTrace& operator=(const ThreadTrace&);
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
ThreadTrace(const ThreadTrace&);
|
||||
|
||||
//! Retrieve gslMemoryObject
|
||||
gslMemObject getCurrentGslMemObject(amd::Memory* );
|
||||
//! Disable default operator=
|
||||
ThreadTrace& operator=(const ThreadTrace&);
|
||||
|
||||
const Device& gpuDevice_; //!< The backend device
|
||||
//! Retrieve gslMemoryObject
|
||||
gslMemObject getCurrentGslMemObject(amd::Memory*);
|
||||
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
const Device& gpuDevice_; //!< The backend device
|
||||
|
||||
CalThreadTraceReference* calRef_; //!< Reference ThreadTrace
|
||||
gslShaderTraceBufferObject* threadTraceBufferObjs_; //!< The buffer object for Thread Trace recording
|
||||
uint index_; //!< ThreadTrace index in the CAL container
|
||||
uint memBufferSizeTT_; //!< ThreadTrace memory buffer size
|
||||
std::vector<amd::Memory*> memObj_; //!< ThreadTrace memory object
|
||||
gslQueryObject threadTrace_; //!< GSL thread trace query object
|
||||
uint amdThreadTraceMemObjsNum_; //!< ThreadTrace memory object`s number (should be equal to the SE number)
|
||||
bool isNewBufferBinded_; //!< The indicator if new buffer was binded to the ThreadTrace object
|
||||
bool isBufferOnSubmit_; //!< The indicator if "new buffer on submit" mode is used
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
|
||||
CalThreadTraceReference* calRef_; //!< Reference ThreadTrace
|
||||
gslShaderTraceBufferObject*
|
||||
threadTraceBufferObjs_; //!< The buffer object for Thread Trace recording
|
||||
uint index_; //!< ThreadTrace index in the CAL container
|
||||
uint memBufferSizeTT_; //!< ThreadTrace memory buffer size
|
||||
std::vector<amd::Memory*> memObj_; //!< ThreadTrace memory object
|
||||
gslQueryObject threadTrace_; //!< GSL thread trace query object
|
||||
uint amdThreadTraceMemObjsNum_; //!< ThreadTrace memory object`s number (should be equal to the
|
||||
//!SE number)
|
||||
bool isNewBufferBinded_; //!< The indicator if new buffer was binded to the ThreadTrace object
|
||||
bool isBufferOnSubmit_; //!< The indicator if "new buffer on submit" mode is used
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPU_THREAD_TRACE_HPP_
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPU_THREAD_TRACE_HPP_
|
||||
@@ -11,109 +11,86 @@
|
||||
|
||||
namespace gpu {
|
||||
|
||||
TimeStamp::TimeStamp(
|
||||
const VirtualGPU& gpu,
|
||||
gslMemObject gslMem,
|
||||
uint memOffset,
|
||||
address cpuAddr)
|
||||
: gpu_(gpu)
|
||||
, gslMem_(gslMem)
|
||||
, memOffset_(memOffset)
|
||||
{
|
||||
values_ = reinterpret_cast<volatile uint64_t*>(cpuAddr + memOffset);
|
||||
TimeStamp::TimeStamp(const VirtualGPU& gpu, gslMemObject gslMem, uint memOffset, address cpuAddr)
|
||||
: gpu_(gpu), gslMem_(gslMem), memOffset_(memOffset) {
|
||||
values_ = reinterpret_cast<volatile uint64_t*>(cpuAddr + memOffset);
|
||||
}
|
||||
|
||||
TimeStamp::~TimeStamp()
|
||||
{
|
||||
}
|
||||
TimeStamp::~TimeStamp() {}
|
||||
|
||||
void
|
||||
TimeStamp::begin(bool sdma)
|
||||
{
|
||||
if (!flags_.beginIssued_) {
|
||||
gpu().rs()->writeTimer(gpu().cs(), sdma, gslMem_,
|
||||
memOffset_ + CommandStartTime * sizeof(uint64_t));
|
||||
flags_.beginIssued_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimeStamp::end(bool sdma)
|
||||
{
|
||||
CondLog(!flags_.beginIssued_, "We didn't issue a begin operation!");
|
||||
void TimeStamp::begin(bool sdma) {
|
||||
if (!flags_.beginIssued_) {
|
||||
gpu().rs()->writeTimer(gpu().cs(), sdma, gslMem_,
|
||||
memOffset_ + CommandEndTime * sizeof(uint64_t));
|
||||
flags_.endIssued_ = true;
|
||||
flags_.sdma_ = sdma;
|
||||
memOffset_ + CommandStartTime * sizeof(uint64_t));
|
||||
flags_.beginIssued_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
SetValue(uint64_t* time, uint64_t val, double nanos)
|
||||
{
|
||||
*time = static_cast<uint64_t>(static_cast<double>(val) * nanos);
|
||||
void TimeStamp::end(bool sdma) {
|
||||
CondLog(!flags_.beginIssued_, "We didn't issue a begin operation!");
|
||||
gpu().rs()->writeTimer(gpu().cs(), sdma, gslMem_, memOffset_ + CommandEndTime * sizeof(uint64_t));
|
||||
flags_.endIssued_ = true;
|
||||
flags_.sdma_ = sdma;
|
||||
}
|
||||
|
||||
void
|
||||
TimeStamp::value(uint64_t* startTime, uint64_t* endTime)
|
||||
{
|
||||
CondLog(!flags_.endIssued_, "We didn't send the counter end operation!");
|
||||
const double NanoSecondsPerTick = gpu_.dev().getAttribs().nanoSecondsPerTick;
|
||||
|
||||
SetValue(startTime, values_[CommandStartTime], NanoSecondsPerTick);
|
||||
SetValue(endTime, values_[CommandEndTime], NanoSecondsPerTick);
|
||||
inline void SetValue(uint64_t* time, uint64_t val, double nanos) {
|
||||
*time = static_cast<uint64_t>(static_cast<double>(val) * nanos);
|
||||
}
|
||||
|
||||
TimeStampCache::~TimeStampCache()
|
||||
{
|
||||
// Release all time stamp objects from the cache
|
||||
for (uint i = 0; i < freedTS_.size(); ++i) {
|
||||
delete freedTS_[i];
|
||||
void TimeStamp::value(uint64_t* startTime, uint64_t* endTime) {
|
||||
CondLog(!flags_.endIssued_, "We didn't send the counter end operation!");
|
||||
const double NanoSecondsPerTick = gpu_.dev().getAttribs().nanoSecondsPerTick;
|
||||
|
||||
SetValue(startTime, values_[CommandStartTime], NanoSecondsPerTick);
|
||||
SetValue(endTime, values_[CommandEndTime], NanoSecondsPerTick);
|
||||
}
|
||||
|
||||
TimeStampCache::~TimeStampCache() {
|
||||
// Release all time stamp objects from the cache
|
||||
for (uint i = 0; i < freedTS_.size(); ++i) {
|
||||
delete freedTS_[i];
|
||||
}
|
||||
freedTS_.clear();
|
||||
|
||||
// Release all memory objects
|
||||
for (uint i = 0; i < tsBuf_.size(); ++i) {
|
||||
tsBuf_[i]->unmap(&gpu_);
|
||||
delete tsBuf_[i];
|
||||
}
|
||||
tsBuf_.clear();
|
||||
}
|
||||
|
||||
TimeStamp* TimeStampCache::allocTimeStamp() {
|
||||
TimeStamp* ts = NULL;
|
||||
if (0 != freedTS_.size()) {
|
||||
ts = freedTS_.back();
|
||||
freedTS_.pop_back();
|
||||
}
|
||||
|
||||
if (NULL == ts) {
|
||||
if ((tsBufCpu_ == NULL) || ((tsOffset_ + TimerSlotSize) > TimerBufSize)) {
|
||||
Memory* buf = new Memory(gpu_.dev(), TimerBufSize);
|
||||
if (buf == NULL || !buf->create(Resource::Remote)) {
|
||||
return NULL;
|
||||
}
|
||||
tsBufCpu_ = reinterpret_cast<address>(buf->map(&gpu_));
|
||||
memset(tsBufCpu_, 0, TimerBufSize);
|
||||
tsOffset_ = 0;
|
||||
tsBuf_.push_back(buf);
|
||||
}
|
||||
freedTS_.clear();
|
||||
|
||||
// Release all memory objects
|
||||
for (uint i = 0; i < tsBuf_.size(); ++i) {
|
||||
tsBuf_[i]->unmap(&gpu_);
|
||||
delete tsBuf_[i];
|
||||
// Allocate a TimeStamp object
|
||||
ts = new TimeStamp(gpu_, tsBuf_[(tsBuf_.size() - 1)]->gslResource(), tsOffset_, tsBufCpu_);
|
||||
// Create a timestamp
|
||||
if (ts == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tsBuf_.clear();
|
||||
tsOffset_ += TimerSlotSize;
|
||||
}
|
||||
|
||||
// Set this timestamp into DRM profile mode if it was requested
|
||||
ts->clearStates();
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
TimeStamp*
|
||||
TimeStampCache::allocTimeStamp()
|
||||
{
|
||||
TimeStamp* ts = NULL;
|
||||
if (0 != freedTS_.size()) {
|
||||
ts = freedTS_.back();
|
||||
freedTS_.pop_back();
|
||||
}
|
||||
|
||||
if (NULL == ts) {
|
||||
if ((tsBufCpu_ == NULL) || ((tsOffset_ + TimerSlotSize) > TimerBufSize)) {
|
||||
Memory* buf = new Memory(gpu_.dev(), TimerBufSize);
|
||||
if (buf == NULL || !buf->create(Resource::Remote)) {
|
||||
return NULL;
|
||||
}
|
||||
tsBufCpu_ = reinterpret_cast<address>(buf->map(&gpu_));
|
||||
memset(tsBufCpu_, 0, TimerBufSize);
|
||||
tsOffset_ = 0;
|
||||
tsBuf_.push_back(buf);
|
||||
}
|
||||
// Allocate a TimeStamp object
|
||||
ts = new TimeStamp(gpu_, tsBuf_[(tsBuf_.size() - 1)]->gslResource(),
|
||||
tsOffset_, tsBufCpu_);
|
||||
// Create a timestamp
|
||||
if (ts == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tsOffset_ += TimerSlotSize;
|
||||
}
|
||||
|
||||
// Set this timestamp into DRM profile mode if it was requested
|
||||
ts->clearStates();
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace gpu
|
||||
@@ -18,113 +18,101 @@ class Device;
|
||||
class VirtualGPU;
|
||||
class Memory;
|
||||
|
||||
class TimeStamp : public amd::HeapObject
|
||||
{
|
||||
public:
|
||||
//! Enums for the timestamp information
|
||||
//! \note *4 is the limitaiton of SDMA HW
|
||||
//! (address has to be aligned by 256 bit)
|
||||
enum TimeStampValue {
|
||||
CommandStartTime = 0,
|
||||
CommandEndTime = 4,
|
||||
CommandTotal = 8
|
||||
class TimeStamp : public amd::HeapObject {
|
||||
public:
|
||||
//! Enums for the timestamp information
|
||||
//! \note *4 is the limitaiton of SDMA HW
|
||||
//! (address has to be aligned by 256 bit)
|
||||
enum TimeStampValue { CommandStartTime = 0, CommandEndTime = 4, CommandTotal = 8 };
|
||||
|
||||
//! The TimeStamp object flags
|
||||
union Flags {
|
||||
struct {
|
||||
uint32_t beginIssued_ : 1;
|
||||
uint32_t endIssued_ : 1;
|
||||
uint32_t sdma_ : 1;
|
||||
};
|
||||
uint32_t value_;
|
||||
Flags() : value_(0) {}
|
||||
};
|
||||
|
||||
//! The TimeStamp object flags
|
||||
union Flags
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t beginIssued_ : 1;
|
||||
uint32_t endIssued_ : 1;
|
||||
uint32_t sdma_ : 1;
|
||||
};
|
||||
uint32_t value_;
|
||||
Flags(): value_(0) {}
|
||||
};
|
||||
//! Default constructor
|
||||
TimeStamp(const VirtualGPU& gpu, //!< Virtual GPU
|
||||
gslMemObject gslMem, //!< Buffer with the timer values
|
||||
uint memOffset, //!< Offset in the buffer for the current TS
|
||||
address cpuAddr //!< CPU pointer for the values in memory
|
||||
);
|
||||
|
||||
//! Default constructor
|
||||
TimeStamp(
|
||||
const VirtualGPU& gpu, //!< Virtual GPU
|
||||
gslMemObject gslMem, //!< Buffer with the timer values
|
||||
uint memOffset, //!< Offset in the buffer for the current TS
|
||||
address cpuAddr //!< CPU pointer for the values in memory
|
||||
);
|
||||
//! Default destructor
|
||||
~TimeStamp();
|
||||
|
||||
//! Default destructor
|
||||
~TimeStamp();
|
||||
//! Starts the timestamp
|
||||
void begin(bool sdma = false);
|
||||
|
||||
//! Starts the timestamp
|
||||
void begin(bool sdma = false);
|
||||
//! Ends the timestamp
|
||||
void end(bool sdma = false);
|
||||
|
||||
//! Ends the timestamp
|
||||
void end(bool sdma = false);
|
||||
//! Returns the timestamp result in nano seconds
|
||||
void value(uint64_t* startTime, uint64_t* endTime);
|
||||
|
||||
//! Returns the timestamp result in nano seconds
|
||||
void value(uint64_t* startTime, uint64_t* endTime);
|
||||
//! Clear all TimeStamp states
|
||||
void clearStates() {
|
||||
flags_.value_ = 0;
|
||||
values_[CommandStartTime] = 0;
|
||||
values_[CommandEndTime] = 0;
|
||||
}
|
||||
|
||||
//! Clear all TimeStamp states
|
||||
void clearStates()
|
||||
{ flags_.value_ = 0;
|
||||
values_[CommandStartTime] = 0;
|
||||
values_[CommandEndTime] = 0;
|
||||
}
|
||||
//! Timer commands were submitted to HW
|
||||
bool isValid() const { return (flags_.endIssued_) ? true : false; }
|
||||
|
||||
//! Timer commands were submitted to HW
|
||||
bool isValid() const { return (flags_.endIssued_) ? true : false; }
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
TimeStamp(const TimeStamp&);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
TimeStamp(const TimeStamp&);
|
||||
//! Disable operator=
|
||||
TimeStamp& operator=(const TimeStamp&);
|
||||
|
||||
//! Disable operator=
|
||||
TimeStamp& operator=(const TimeStamp&);
|
||||
//! Returns the GPU device object
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
//! Returns the GPU device object
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
const VirtualGPU& gpu_; //!< Virtual GPU
|
||||
Flags flags_; //!< The time stamp state
|
||||
gslMemObject gslMem_; //!< Buffer with the timer values
|
||||
uint memOffset_; //!< Offset in the buffer for the current timer
|
||||
volatile uint64_t* values_; //!< CPU pointer to the timer values
|
||||
const VirtualGPU& gpu_; //!< Virtual GPU
|
||||
Flags flags_; //!< The time stamp state
|
||||
gslMemObject gslMem_; //!< Buffer with the timer values
|
||||
uint memOffset_; //!< Offset in the buffer for the current timer
|
||||
volatile uint64_t* values_; //!< CPU pointer to the timer values
|
||||
};
|
||||
|
||||
class TimeStampCache : public amd::HeapObject
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
TimeStampCache(
|
||||
VirtualGPU& gpu //!< Virtual GPU object
|
||||
)
|
||||
: gpu_(gpu)
|
||||
, tsBufCpu_(NULL)
|
||||
, tsOffset_(0) {}
|
||||
class TimeStampCache : public amd::HeapObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
TimeStampCache(VirtualGPU& gpu //!< Virtual GPU object
|
||||
)
|
||||
: gpu_(gpu), tsBufCpu_(NULL), tsOffset_(0) {}
|
||||
|
||||
//! Default destructor
|
||||
~TimeStampCache();
|
||||
//! Default destructor
|
||||
~TimeStampCache();
|
||||
|
||||
//! Gets a time stamp object. It will find a freed object or allocate a new one
|
||||
TimeStamp* allocTimeStamp();
|
||||
//! Gets a time stamp object. It will find a freed object or allocate a new one
|
||||
TimeStamp* allocTimeStamp();
|
||||
|
||||
//! Frees a time stamp object
|
||||
void freeTimeStamp(TimeStamp* ts) { freedTS_.push_back(ts); }
|
||||
//! Frees a time stamp object
|
||||
void freeTimeStamp(TimeStamp* ts) { freedTS_.push_back(ts); }
|
||||
|
||||
private:
|
||||
static const uint TimerSlotSize = TimeStamp::CommandTotal * sizeof(uint64_t);
|
||||
static const uint TimerBufSize = TimerSlotSize * 4096;
|
||||
private:
|
||||
static const uint TimerSlotSize = TimeStamp::CommandTotal * sizeof(uint64_t);
|
||||
static const uint TimerBufSize = TimerSlotSize * 4096;
|
||||
|
||||
//! Disable copy constructor
|
||||
TimeStampCache(const TimeStampCache&);
|
||||
//! Disable copy constructor
|
||||
TimeStampCache(const TimeStampCache&);
|
||||
|
||||
//! Disable operator=
|
||||
TimeStampCache& operator=(const TimeStampCache&);
|
||||
//! Disable operator=
|
||||
TimeStampCache& operator=(const TimeStampCache&);
|
||||
|
||||
std::vector<TimeStamp*> freedTS_; //!< Array of freed time stamp objects
|
||||
VirtualGPU& gpu_; //!< Virtual GPU
|
||||
std::vector<Memory*> tsBuf_; //!< Array of memory objects with the timer value
|
||||
address tsBufCpu_; //!< CPU pointer for current TS memory
|
||||
uint tsOffset_; //!< Active offset in the current mem object
|
||||
std::vector<TimeStamp*> freedTS_; //!< Array of freed time stamp objects
|
||||
VirtualGPU& gpu_; //!< Virtual GPU
|
||||
std::vector<Memory*> tsBuf_; //!< Array of memory objects with the timer value
|
||||
address tsBufCpu_; //!< CPU pointer for current TS memory
|
||||
uint tsOffset_; //!< Active offset in the current mem object
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
@@ -116,72 +116,24 @@ end
|
||||
*******************************************************************************/
|
||||
|
||||
/// shader codes with "asic(TAHITI)" instruction
|
||||
static const uint32_t RuntimeTrapCode [] = {
|
||||
0x7e008200, 0xbf8c0000,
|
||||
0xbef8036c, 0x8779ff6d,
|
||||
0x0000ffff, 0x8879ff79,
|
||||
0x01000000, 0xbefa03ff,
|
||||
0x00002000, 0xbefb03ff,
|
||||
0x00024fac, 0x80f8ff78,
|
||||
0x00000100, 0xbef70300,
|
||||
0xc2007900, 0xbf8c0000,
|
||||
0xbeee0300, 0xc2007901,
|
||||
0xbf8c0000, 0xbeef0300,
|
||||
0xbe800377, 0xbef60398,
|
||||
0x8078766e, 0x8779ff6f,
|
||||
0x0000ffff, 0x8879ff79,
|
||||
0x00680000, 0xbefa03ff,
|
||||
0x00002000, 0xbefb03ff,
|
||||
0x00024fac, 0xbef6036e,
|
||||
0xbef7036f, 0xbef30300,
|
||||
0xc2007902, 0xbf8c0000,
|
||||
0xbeee0300, 0xc2007903,
|
||||
0xbf8c0000, 0xbeef0300,
|
||||
0xc2007900, 0xbf8c0000,
|
||||
0xbef20300, 0xc2007901,
|
||||
0xbf8c0000, 0x89737300,
|
||||
0x89007300, 0x89737300,
|
||||
0xbef80372, 0xbef90373,
|
||||
0xbef21f00, 0x80728872,
|
||||
0xbe802078, 0xbeef0377,
|
||||
0xbeee0376, 0x8771ff71,
|
||||
0x0000ffff, 0xbe802270
|
||||
};
|
||||
static const uint32_t RuntimeTrapCode[] = {
|
||||
0x7e008200, 0xbf8c0000, 0xbef8036c, 0x8779ff6d, 0x0000ffff, 0x8879ff79, 0x01000000, 0xbefa03ff,
|
||||
0x00002000, 0xbefb03ff, 0x00024fac, 0x80f8ff78, 0x00000100, 0xbef70300, 0xc2007900, 0xbf8c0000,
|
||||
0xbeee0300, 0xc2007901, 0xbf8c0000, 0xbeef0300, 0xbe800377, 0xbef60398, 0x8078766e, 0x8779ff6f,
|
||||
0x0000ffff, 0x8879ff79, 0x00680000, 0xbefa03ff, 0x00002000, 0xbefb03ff, 0x00024fac, 0xbef6036e,
|
||||
0xbef7036f, 0xbef30300, 0xc2007902, 0xbf8c0000, 0xbeee0300, 0xc2007903, 0xbf8c0000, 0xbeef0300,
|
||||
0xc2007900, 0xbf8c0000, 0xbef20300, 0xc2007901, 0xbf8c0000, 0x89737300, 0x89007300, 0x89737300,
|
||||
0xbef80372, 0xbef90373, 0xbef21f00, 0x80728872, 0xbe802078, 0xbeef0377, 0xbeee0376, 0x8771ff71,
|
||||
0x0000ffff, 0xbe802270};
|
||||
|
||||
|
||||
/// shader codes with "asic(VI)" instruction
|
||||
static const uint32_t RuntimeTrapCodeVi [] = {
|
||||
0x7e006a00, 0xbf8c0000,
|
||||
0xbef8006c, 0x8679ff6d,
|
||||
0x0000ffff, 0x8779ff79,
|
||||
0x01000000, 0xbefa00ff,
|
||||
0x00002000, 0xbefb00ff,
|
||||
0x00024fac, 0x80f8ff78,
|
||||
0x00000100, 0xbef70000,
|
||||
0xc022003c, 0x00000000,
|
||||
0xbf8c0000, 0xbeee0000,
|
||||
0xc022003c, 0x00000004,
|
||||
0xbf8c0000, 0xbeef0000,
|
||||
0xbe800077, 0xbef60098,
|
||||
0x8078766e, 0x8679ff6f,
|
||||
0x0000ffff, 0x8779ff79,
|
||||
0x00680000, 0xbefa00ff,
|
||||
0x00002000, 0xbefb00ff,
|
||||
0x00024fac, 0xbef6006e,
|
||||
0xbef7006f, 0xbef30000,
|
||||
0xc022003c, 0x00000008,
|
||||
0xbf8c0000, 0xbeee0000,
|
||||
0xc022003c, 0x0000000c,
|
||||
0xbf8c0000, 0xbeef0000,
|
||||
0xc022003c, 0x00000000,
|
||||
0xbf8c0000, 0xbef20000,
|
||||
0xc022003c, 0x00000004,
|
||||
0xbf8c0000, 0x88737300,
|
||||
0x88007300, 0x88737300,
|
||||
0xbef80072, 0xbef90073,
|
||||
0xbef21c00, 0x80728872,
|
||||
0xbe801d78, 0xbeef0077,
|
||||
0xbeee0076, 0x8671ff71,
|
||||
0x0000ffff, 0xbe801f70
|
||||
};
|
||||
|
||||
static const uint32_t RuntimeTrapCodeVi[] = {
|
||||
0x7e006a00, 0xbf8c0000, 0xbef8006c, 0x8679ff6d, 0x0000ffff, 0x8779ff79, 0x01000000, 0xbefa00ff,
|
||||
0x00002000, 0xbefb00ff, 0x00024fac, 0x80f8ff78, 0x00000100, 0xbef70000, 0xc022003c, 0x00000000,
|
||||
0xbf8c0000, 0xbeee0000, 0xc022003c, 0x00000004, 0xbf8c0000, 0xbeef0000, 0xbe800077, 0xbef60098,
|
||||
0x8078766e, 0x8679ff6f, 0x0000ffff, 0x8779ff79, 0x00680000, 0xbefa00ff, 0x00002000, 0xbefb00ff,
|
||||
0x00024fac, 0xbef6006e, 0xbef7006f, 0xbef30000, 0xc022003c, 0x00000008, 0xbf8c0000, 0xbeee0000,
|
||||
0xc022003c, 0x0000000c, 0xbf8c0000, 0xbeef0000, 0xc022003c, 0x00000000, 0xbf8c0000, 0xbef20000,
|
||||
0xc022003c, 0x00000004, 0xbf8c0000, 0x88737300, 0x88007300, 0x88737300, 0xbef80072, 0xbef90073,
|
||||
0xbef21c00, 0x80728872, 0xbe801d78, 0xbeef0077, 0xbeee0076, 0x8671ff71, 0x0000ffff, 0xbe801f70};
|
||||
File diff suppressed because it is too large.
Load diff
@@ -34,515 +34,481 @@ class ThreadTrace;
|
||||
class HSAILKernel;
|
||||
|
||||
//! Virtual GPU
|
||||
class VirtualGPU : public device::VirtualDevice, public CALGSLContext
|
||||
{
|
||||
public:
|
||||
struct CommandBatch : public amd::HeapObject
|
||||
{
|
||||
amd::Command* head_; //!< Command batch head
|
||||
GpuEvent events_[AllEngines]; //!< Last known GPU events
|
||||
TimeStamp* lastTS_; //!< TS associated with command batch
|
||||
class VirtualGPU : public device::VirtualDevice, public CALGSLContext {
|
||||
public:
|
||||
struct CommandBatch : public amd::HeapObject {
|
||||
amd::Command* head_; //!< Command batch head
|
||||
GpuEvent events_[AllEngines]; //!< Last known GPU events
|
||||
TimeStamp* lastTS_; //!< TS associated with command batch
|
||||
|
||||
//! Constructor
|
||||
CommandBatch(
|
||||
amd::Command* head, //!< Command batch head
|
||||
const GpuEvent* events, //!< HW events on all engines
|
||||
TimeStamp* lastTS //!< Last TS in command batch
|
||||
): head_(head), lastTS_(lastTS)
|
||||
{
|
||||
memcpy(&events_, events, AllEngines * sizeof(GpuEvent));
|
||||
}
|
||||
//! Constructor
|
||||
CommandBatch(amd::Command* head, //!< Command batch head
|
||||
const GpuEvent* events, //!< HW events on all engines
|
||||
TimeStamp* lastTS //!< Last TS in command batch
|
||||
)
|
||||
: head_(head), lastTS_(lastTS) {
|
||||
memcpy(&events_, events, AllEngines * sizeof(GpuEvent));
|
||||
}
|
||||
};
|
||||
|
||||
//! The virtual GPU states
|
||||
union State {
|
||||
struct {
|
||||
uint boundGlobal_ : 1; //!< Global buffer was bound
|
||||
uint profiling_ : 1; //!< Profiling is enabled
|
||||
uint forceWait_ : 1; //!< Forces wait in flush()
|
||||
uint boundCb_ : 1; //!< Constant buffer was bound
|
||||
uint boundPrintf_ : 1; //!< Printf buffer was bound
|
||||
uint hsailKernel_ : 1; //!< True if HSAIL kernel was used
|
||||
};
|
||||
uint value_;
|
||||
State() : value_(0) {}
|
||||
};
|
||||
|
||||
//! CAL descriptor for the GPU virtual device
|
||||
struct CalVirtualDesc : public amd::EmbeddedObject {
|
||||
gslDomain3D gridBlock; //!< size of a block of data
|
||||
gslDomain3D gridSize; //!< size of 'blocks' to execute
|
||||
gslDomain3D partialGridBlock; //!< Partial grid block
|
||||
CALuint localSize; //!< size of OpenCL Local Memory in bytes
|
||||
uint memCount_; //!< Memory objects count
|
||||
GpuEvent events_[AllEngines]; //!< Last known GPU events
|
||||
uint iterations_; //!< Number of iterations for the execution
|
||||
TimeStamp* lastTS_; //!< Last timestamp executed on Virtual GPU
|
||||
gslMemObject constBuffers_[MaxConstBuffers]; //!< Constant buffer names
|
||||
gslMemObject uavs_[MaxUavArguments]; //!< UAV bindings
|
||||
gslMemObject readImages_[MaxReadImage]; //!< Read images
|
||||
uint32_t samplersState_[MaxSamplers]; //!< State of all samplers
|
||||
};
|
||||
|
||||
typedef std::vector<ConstBuffer*> constbufs_t;
|
||||
|
||||
//! GSL descriptor for the GPU kernel, specific to the virtual device
|
||||
struct GslKernelDesc : public amd::HeapObject {
|
||||
CALimage image_; //!< CAL image for the program
|
||||
gslProgramObject func_; //!< GSL program object
|
||||
gslMemObject intCb_; //!< Internal constant buffer
|
||||
};
|
||||
|
||||
struct ResourceSlot {
|
||||
union State {
|
||||
struct {
|
||||
uint bound_ : 1; //!< Resource is bound
|
||||
uint constant_ : 1; //!< Resource is a constant
|
||||
};
|
||||
uint value_;
|
||||
State() : value_(0) {}
|
||||
};
|
||||
|
||||
//! The virtual GPU states
|
||||
union State
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint boundGlobal_ : 1; //!< Global buffer was bound
|
||||
uint profiling_ : 1; //!< Profiling is enabled
|
||||
uint forceWait_ : 1; //!< Forces wait in flush()
|
||||
uint boundCb_ : 1; //!< Constant buffer was bound
|
||||
uint boundPrintf_ : 1; //!< Printf buffer was bound
|
||||
uint hsailKernel_ : 1; //!< True if HSAIL kernel was used
|
||||
};
|
||||
uint value_;
|
||||
State(): value_(0) {}
|
||||
State state_; //!< slot's state
|
||||
const Memory* memory_; //!< GPU memory object
|
||||
|
||||
ResourceSlot() : memory_(NULL) {}
|
||||
|
||||
//! Copy constructor for the kernel argument
|
||||
ResourceSlot(const ResourceSlot& data) { *this = data; }
|
||||
|
||||
//! Overloads operator=
|
||||
ResourceSlot& operator=(const ResourceSlot& data) {
|
||||
state_.value_ = data.state_.value_;
|
||||
memory_ = data.memory_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class MemoryDependency : public amd::EmbeddedObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
MemoryDependency()
|
||||
: memObjectsInQueue_(NULL), numMemObjectsInQueue_(0), maxMemObjectsInQueue_(0) {}
|
||||
|
||||
~MemoryDependency() { delete[] memObjectsInQueue_; }
|
||||
|
||||
//! Creates memory dependecy structure
|
||||
bool create(size_t numMemObj);
|
||||
|
||||
//! Notify the tracker about new kernel
|
||||
void newKernel() { endMemObjectsInQueue_ = numMemObjectsInQueue_; }
|
||||
|
||||
//! Validates memory object on dependency
|
||||
void validate(VirtualGPU& gpu, const Memory* memory, bool readOnly);
|
||||
|
||||
//! Clear memory dependency
|
||||
void clear(bool all = true);
|
||||
|
||||
private:
|
||||
struct MemoryState {
|
||||
uint64_t start_; //! Busy memory start address
|
||||
uint64_t end_; //! Busy memory end address
|
||||
bool readOnly_; //! Current GPU state in the queue
|
||||
};
|
||||
|
||||
//! CAL descriptor for the GPU virtual device
|
||||
struct CalVirtualDesc : public amd::EmbeddedObject
|
||||
{
|
||||
gslDomain3D gridBlock; //!< size of a block of data
|
||||
gslDomain3D gridSize; //!< size of 'blocks' to execute
|
||||
gslDomain3D partialGridBlock;//!< Partial grid block
|
||||
CALuint localSize; //!< size of OpenCL Local Memory in bytes
|
||||
uint memCount_; //!< Memory objects count
|
||||
GpuEvent events_[AllEngines]; //!< Last known GPU events
|
||||
uint iterations_; //!< Number of iterations for the execution
|
||||
TimeStamp* lastTS_; //!< Last timestamp executed on Virtual GPU
|
||||
gslMemObject constBuffers_[MaxConstBuffers];//!< Constant buffer names
|
||||
gslMemObject uavs_[MaxUavArguments]; //!< UAV bindings
|
||||
gslMemObject readImages_[MaxReadImage]; //!< Read images
|
||||
uint32_t samplersState_[MaxSamplers]; //!< State of all samplers
|
||||
};
|
||||
|
||||
typedef std::vector<ConstBuffer*> constbufs_t;
|
||||
|
||||
//! GSL descriptor for the GPU kernel, specific to the virtual device
|
||||
struct GslKernelDesc : public amd::HeapObject
|
||||
{
|
||||
CALimage image_; //!< CAL image for the program
|
||||
gslProgramObject func_; //!< GSL program object
|
||||
gslMemObject intCb_; //!< Internal constant buffer
|
||||
};
|
||||
|
||||
struct ResourceSlot
|
||||
{
|
||||
union State
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint bound_ : 1; //!< Resource is bound
|
||||
uint constant_ : 1; //!< Resource is a constant
|
||||
};
|
||||
uint value_;
|
||||
State(): value_(0) {}
|
||||
};
|
||||
|
||||
State state_; //!< slot's state
|
||||
const Memory* memory_; //!< GPU memory object
|
||||
|
||||
ResourceSlot(): memory_(NULL) {}
|
||||
|
||||
//! Copy constructor for the kernel argument
|
||||
ResourceSlot(const ResourceSlot& data) { *this = data; }
|
||||
|
||||
//! Overloads operator=
|
||||
ResourceSlot& operator=(const ResourceSlot& data)
|
||||
{
|
||||
state_.value_ = data.state_.value_;
|
||||
memory_ = data.memory_;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class MemoryDependency : public amd::EmbeddedObject
|
||||
{
|
||||
public:
|
||||
//! Default constructor
|
||||
MemoryDependency()
|
||||
: memObjectsInQueue_(NULL)
|
||||
, numMemObjectsInQueue_(0)
|
||||
, maxMemObjectsInQueue_(0) {}
|
||||
|
||||
~MemoryDependency() { delete [] memObjectsInQueue_; }
|
||||
|
||||
//! Creates memory dependecy structure
|
||||
bool create(size_t numMemObj);
|
||||
|
||||
//! Notify the tracker about new kernel
|
||||
void newKernel() { endMemObjectsInQueue_ = numMemObjectsInQueue_; }
|
||||
|
||||
//! Validates memory object on dependency
|
||||
void validate(VirtualGPU& gpu, const Memory* memory, bool readOnly);
|
||||
|
||||
//! Clear memory dependency
|
||||
void clear(bool all = true);
|
||||
|
||||
private:
|
||||
struct MemoryState {
|
||||
uint64_t start_; //! Busy memory start address
|
||||
uint64_t end_; //! Busy memory end address
|
||||
bool readOnly_; //! Current GPU state in the queue
|
||||
};
|
||||
|
||||
MemoryState* memObjectsInQueue_; //!< Memory object state in the queue
|
||||
size_t endMemObjectsInQueue_; //!< End of mem objects in the queue
|
||||
size_t numMemObjectsInQueue_; //!< Number of mem objects in the queue
|
||||
size_t maxMemObjectsInQueue_; //!< Maximum number of mem objects in the queue
|
||||
};
|
||||
|
||||
|
||||
class DmaFlushMgmt : public amd::EmbeddedObject
|
||||
{
|
||||
public:
|
||||
DmaFlushMgmt(const Device& dev);
|
||||
|
||||
// Resets DMA command buffer workload
|
||||
void resetCbWorkload(const Device& dev);
|
||||
|
||||
// Finds split size for the current dispatch
|
||||
void findSplitSize(
|
||||
const Device& dev, //!< GPU device object
|
||||
uint64_t threads, //!< Total number of execution threads
|
||||
uint instructions //!< Number of ALU instructions
|
||||
);
|
||||
|
||||
// Returns TRUE if DMA command buffer is ready for a flush
|
||||
bool isCbReady(
|
||||
VirtualGPU& gpu, //!< Virtual GPU object
|
||||
uint64_t threads, //!< Total number of execution threads
|
||||
uint instructions //!< Number of ALU instructions
|
||||
);
|
||||
|
||||
// Returns dispatch split size
|
||||
uint dispatchSplitSize() const { return dispatchSplitSize_; }
|
||||
|
||||
private:
|
||||
uint64_t maxDispatchWorkload_; //!< Maximum number of operations for a single dispatch
|
||||
uint64_t maxCbWorkload_; //!< Maximum number of operations for DMA command buffer
|
||||
uint64_t cbWorkload_; //!< Current number of operations in DMA command buffer
|
||||
uint aluCnt_; //!< All ALUs on the chip
|
||||
uint dispatchSplitSize_; //!< Dispath split size in elements
|
||||
};
|
||||
|
||||
typedef std::vector<ResourceSlot> ResourceSlots;
|
||||
|
||||
public:
|
||||
VirtualGPU(Device& device);
|
||||
bool create(bool profiling, uint rtCUs = amd::CommandQueue::RealTimeDisabled,
|
||||
uint deviceQueueSize = 0,
|
||||
amd::CommandQueue::Priority priority = amd::CommandQueue::Priority::Normal);
|
||||
~VirtualGPU();
|
||||
|
||||
void submitReadMemory(amd::ReadMemoryCommand& vcmd);
|
||||
void submitWriteMemory(amd::WriteMemoryCommand& vcmd);
|
||||
void submitCopyMemory(amd::CopyMemoryCommand& vcmd);
|
||||
void submitMapMemory(amd::MapMemoryCommand& vcmd);
|
||||
void submitUnmapMemory(amd::UnmapMemoryCommand& vcmd);
|
||||
void submitKernel(amd::NDRangeKernelCommand& vcmd);
|
||||
bool submitKernelInternal(
|
||||
const amd::NDRangeContainer& sizes, //!< Workload sizes
|
||||
const amd::Kernel& kernel, //!< Kernel for execution
|
||||
const_address parameters, //!< Parameters for the kernel
|
||||
bool nativeMem = true, //!< Native memory objects
|
||||
amd::Event* enqueueEvent = NULL //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
bool submitKernelInternalHSA(
|
||||
const amd::NDRangeContainer& sizes, //!< Workload sizes
|
||||
const amd::Kernel& kernel, //!< Kernel for execution
|
||||
const_address parameters, //!< Parameters for the kernel
|
||||
bool nativeMem = true, //!< Native memory objects
|
||||
amd::Event* enqueueEvent = NULL //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
void submitNativeFn(amd::NativeFnCommand& vcmd);
|
||||
void submitFillMemory(amd::FillMemoryCommand& vcmd);
|
||||
void submitMigrateMemObjects(amd::MigrateMemObjectsCommand& cmd);
|
||||
void submitMarker(amd::Marker& vcmd);
|
||||
void submitAcquireExtObjects(amd::AcquireExtObjectsCommand& vcmd);
|
||||
void submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& vcmd);
|
||||
void submitPerfCounter(amd::PerfCounterCommand& vcmd);
|
||||
void submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand& cmd);
|
||||
void submitThreadTrace(amd::ThreadTraceCommand& vcmd);
|
||||
void submitSignal(amd::SignalCommand & vcmd);
|
||||
void submitMakeBuffersResident(amd::MakeBuffersResidentCommand & vcmd);
|
||||
virtual void submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd);
|
||||
virtual void submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd);
|
||||
virtual void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
|
||||
virtual void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
|
||||
virtual void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
|
||||
virtual void submitTransferBufferFromFile(amd::TransferBufferFileCommand& cmd);
|
||||
|
||||
void releaseMemory(gslMemObject gslResource, bool wait = true);
|
||||
void releaseKernel(CALimage calImage);
|
||||
|
||||
void flush(amd::Command* list = NULL, bool wait = false);
|
||||
bool terminate() { return true; }
|
||||
|
||||
//! Returns GPU device object associated with this kernel
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Returns CAL descriptor of the virtual device
|
||||
const CalVirtualDesc* cal() const { return &cal_; }
|
||||
|
||||
//! Returns active kernel descriptor for this virtual device
|
||||
const GslKernelDesc* gslKernelDesc() const { return activeKernelDesc_; }
|
||||
|
||||
//! Returns a GPU event, associated with GPU memory
|
||||
GpuEvent* getGpuEvent(
|
||||
const gslMemObject gslMem //!< GSL mem object
|
||||
) { return &gpuEvents_[gslMem]; }
|
||||
|
||||
//! Assigns a GPU event, associated with GPU memory
|
||||
void assignGpuEvent(
|
||||
const gslMemObject gslMem, //!< GSL mem object
|
||||
GpuEvent gpuEvent
|
||||
) { gpuEvents_[gslMem] = gpuEvent; }
|
||||
|
||||
//! Set the kernel as active
|
||||
bool setActiveKernelDesc(
|
||||
const amd::NDRangeContainer& sizes, //!< kernel execution work sizes
|
||||
const Kernel* kernel //!< GPU kernel object
|
||||
);
|
||||
|
||||
//! Set the last known GPU event
|
||||
void setGpuEvent(
|
||||
GpuEvent gpuEvent, //!< GPU event for tracking
|
||||
bool flush = false //!< TRUE if flush is required
|
||||
);
|
||||
|
||||
//! Flush DMA buffer on the specified engine
|
||||
void flushDMA(
|
||||
uint engineID //!< Engine ID for DMA flush
|
||||
);
|
||||
|
||||
//! Wait for all engines on this Virtual GPU
|
||||
//! Returns TRUE if CPU didn't wait for GPU
|
||||
bool waitAllEngines(
|
||||
CommandBatch* cb = NULL //!< Command batch
|
||||
);
|
||||
|
||||
//! Waits for the latest GPU event with a lock to prevent multiple entries
|
||||
void waitEventLock(
|
||||
CommandBatch* cb //!< Command batch
|
||||
);
|
||||
|
||||
//! Returns a resource associated with the constant buffer
|
||||
const ConstBuffer* cb(uint idx) const { return constBufs_[idx]; }
|
||||
|
||||
//! Adds CAL objects into the constant buffer vector
|
||||
void addConstBuffer(ConstBuffer* cb) { constBufs_.push_back(cb); }
|
||||
|
||||
constbufs_t constBufs_; //!< constant buffers
|
||||
|
||||
//! Start the command profiling
|
||||
void profilingBegin(
|
||||
amd::Command& command, //!< Command queue object
|
||||
bool drmProfiling = false //!< Measure DRM time
|
||||
);
|
||||
|
||||
//! End the command profiling
|
||||
void profilingEnd(amd::Command& command);
|
||||
|
||||
//! Collect the profiling results
|
||||
bool profilingCollectResults(
|
||||
CommandBatch* cb, //!< Command batch
|
||||
const amd::Event* waitingEvent //!< Waiting event
|
||||
);
|
||||
|
||||
//! Adds a memory handle into the GSL memory array for Virtual Heap
|
||||
bool addVmMemory(
|
||||
const Memory* memory //!< GPU memory object
|
||||
);
|
||||
|
||||
//! Adds a stage write buffer into a list
|
||||
void addXferWrite(Memory& memory);
|
||||
|
||||
//! Adds a pinned memory object into a map
|
||||
void addPinnedMem(amd::Memory* mem);
|
||||
|
||||
//! Release pinned memory objects
|
||||
void releasePinnedMem();
|
||||
|
||||
//! Finds if pinned memory is cached
|
||||
amd::Memory* findPinnedMem(void* addr, size_t size);
|
||||
|
||||
//! Returns gsl memory object for VM
|
||||
const gslMemObject* vmMems() const { return vmMems_; }
|
||||
|
||||
//! Returns the monitor object for execution access by VirtualGPU
|
||||
amd::Monitor& execution() { return execution_; }
|
||||
MemoryState* memObjectsInQueue_; //!< Memory object state in the queue
|
||||
size_t endMemObjectsInQueue_; //!< End of mem objects in the queue
|
||||
size_t numMemObjectsInQueue_; //!< Number of mem objects in the queue
|
||||
size_t maxMemObjectsInQueue_; //!< Maximum number of mem objects in the queue
|
||||
};
|
||||
|
||||
|
||||
class DmaFlushMgmt : public amd::EmbeddedObject {
|
||||
public:
|
||||
DmaFlushMgmt(const Device& dev);
|
||||
|
||||
// Resets DMA command buffer workload
|
||||
void resetCbWorkload(const Device& dev);
|
||||
|
||||
// Finds split size for the current dispatch
|
||||
void findSplitSize(const Device& dev, //!< GPU device object
|
||||
uint64_t threads, //!< Total number of execution threads
|
||||
uint instructions //!< Number of ALU instructions
|
||||
);
|
||||
|
||||
// Returns TRUE if DMA command buffer is ready for a flush
|
||||
bool isCbReady(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
uint64_t threads, //!< Total number of execution threads
|
||||
uint instructions //!< Number of ALU instructions
|
||||
);
|
||||
|
||||
// Returns dispatch split size
|
||||
uint dispatchSplitSize() const { return dispatchSplitSize_; }
|
||||
|
||||
private:
|
||||
uint64_t maxDispatchWorkload_; //!< Maximum number of operations for a single dispatch
|
||||
uint64_t maxCbWorkload_; //!< Maximum number of operations for DMA command buffer
|
||||
uint64_t cbWorkload_; //!< Current number of operations in DMA command buffer
|
||||
uint aluCnt_; //!< All ALUs on the chip
|
||||
uint dispatchSplitSize_; //!< Dispath split size in elements
|
||||
};
|
||||
|
||||
typedef std::vector<ResourceSlot> ResourceSlots;
|
||||
|
||||
public:
|
||||
VirtualGPU(Device& device);
|
||||
bool create(bool profiling, uint rtCUs = amd::CommandQueue::RealTimeDisabled,
|
||||
uint deviceQueueSize = 0,
|
||||
amd::CommandQueue::Priority priority = amd::CommandQueue::Priority::Normal);
|
||||
~VirtualGPU();
|
||||
|
||||
void submitReadMemory(amd::ReadMemoryCommand& vcmd);
|
||||
void submitWriteMemory(amd::WriteMemoryCommand& vcmd);
|
||||
void submitCopyMemory(amd::CopyMemoryCommand& vcmd);
|
||||
void submitMapMemory(amd::MapMemoryCommand& vcmd);
|
||||
void submitUnmapMemory(amd::UnmapMemoryCommand& vcmd);
|
||||
void submitKernel(amd::NDRangeKernelCommand& vcmd);
|
||||
bool submitKernelInternal(
|
||||
const amd::NDRangeContainer& sizes, //!< Workload sizes
|
||||
const amd::Kernel& kernel, //!< Kernel for execution
|
||||
const_address parameters, //!< Parameters for the kernel
|
||||
bool nativeMem = true, //!< Native memory objects
|
||||
amd::Event* enqueueEvent = NULL //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
bool submitKernelInternalHSA(
|
||||
const amd::NDRangeContainer& sizes, //!< Workload sizes
|
||||
const amd::Kernel& kernel, //!< Kernel for execution
|
||||
const_address parameters, //!< Parameters for the kernel
|
||||
bool nativeMem = true, //!< Native memory objects
|
||||
amd::Event* enqueueEvent = NULL //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
void submitNativeFn(amd::NativeFnCommand& vcmd);
|
||||
void submitFillMemory(amd::FillMemoryCommand& vcmd);
|
||||
void submitMigrateMemObjects(amd::MigrateMemObjectsCommand& cmd);
|
||||
void submitMarker(amd::Marker& vcmd);
|
||||
void submitAcquireExtObjects(amd::AcquireExtObjectsCommand& vcmd);
|
||||
void submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& vcmd);
|
||||
void submitPerfCounter(amd::PerfCounterCommand& vcmd);
|
||||
void submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand& cmd);
|
||||
void submitThreadTrace(amd::ThreadTraceCommand& vcmd);
|
||||
void submitSignal(amd::SignalCommand& vcmd);
|
||||
void submitMakeBuffersResident(amd::MakeBuffersResidentCommand& vcmd);
|
||||
virtual void submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd);
|
||||
virtual void submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd);
|
||||
virtual void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
|
||||
virtual void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
|
||||
virtual void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
|
||||
virtual void submitTransferBufferFromFile(amd::TransferBufferFileCommand& cmd);
|
||||
|
||||
void releaseMemory(gslMemObject gslResource, bool wait = true);
|
||||
void releaseKernel(CALimage calImage);
|
||||
|
||||
void flush(amd::Command* list = NULL, bool wait = false);
|
||||
bool terminate() { return true; }
|
||||
|
||||
//! Returns GPU device object associated with this kernel
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Returns CAL descriptor of the virtual device
|
||||
const CalVirtualDesc* cal() const { return &cal_; }
|
||||
|
||||
//! Returns active kernel descriptor for this virtual device
|
||||
const GslKernelDesc* gslKernelDesc() const { return activeKernelDesc_; }
|
||||
|
||||
//! Returns a GPU event, associated with GPU memory
|
||||
GpuEvent* getGpuEvent(const gslMemObject gslMem //!< GSL mem object
|
||||
) {
|
||||
return &gpuEvents_[gslMem];
|
||||
}
|
||||
|
||||
//! Assigns a GPU event, associated with GPU memory
|
||||
void assignGpuEvent(const gslMemObject gslMem, //!< GSL mem object
|
||||
GpuEvent gpuEvent) {
|
||||
gpuEvents_[gslMem] = gpuEvent;
|
||||
}
|
||||
|
||||
//! Set the kernel as active
|
||||
bool setActiveKernelDesc(const amd::NDRangeContainer& sizes, //!< kernel execution work sizes
|
||||
const Kernel* kernel //!< GPU kernel object
|
||||
);
|
||||
|
||||
//! Set the last known GPU event
|
||||
void setGpuEvent(GpuEvent gpuEvent, //!< GPU event for tracking
|
||||
bool flush = false //!< TRUE if flush is required
|
||||
);
|
||||
|
||||
//! Flush DMA buffer on the specified engine
|
||||
void flushDMA(uint engineID //!< Engine ID for DMA flush
|
||||
);
|
||||
|
||||
//! Wait for all engines on this Virtual GPU
|
||||
//! Returns TRUE if CPU didn't wait for GPU
|
||||
bool waitAllEngines(CommandBatch* cb = NULL //!< Command batch
|
||||
);
|
||||
|
||||
//! Waits for the latest GPU event with a lock to prevent multiple entries
|
||||
void waitEventLock(CommandBatch* cb //!< Command batch
|
||||
);
|
||||
|
||||
//! Returns a resource associated with the constant buffer
|
||||
const ConstBuffer* cb(uint idx) const { return constBufs_[idx]; }
|
||||
|
||||
//! Adds CAL objects into the constant buffer vector
|
||||
void addConstBuffer(ConstBuffer* cb) { constBufs_.push_back(cb); }
|
||||
|
||||
constbufs_t constBufs_; //!< constant buffers
|
||||
|
||||
//! Start the command profiling
|
||||
void profilingBegin(amd::Command& command, //!< Command queue object
|
||||
bool drmProfiling = false //!< Measure DRM time
|
||||
);
|
||||
|
||||
//! End the command profiling
|
||||
void profilingEnd(amd::Command& command);
|
||||
|
||||
//! Collect the profiling results
|
||||
bool profilingCollectResults(CommandBatch* cb, //!< Command batch
|
||||
const amd::Event* waitingEvent //!< Waiting event
|
||||
);
|
||||
|
||||
//! Adds a memory handle into the GSL memory array for Virtual Heap
|
||||
bool addVmMemory(const Memory* memory //!< GPU memory object
|
||||
);
|
||||
|
||||
//! Adds a stage write buffer into a list
|
||||
void addXferWrite(Memory& memory);
|
||||
|
||||
//! Adds a pinned memory object into a map
|
||||
void addPinnedMem(amd::Memory* mem);
|
||||
|
||||
//! Release pinned memory objects
|
||||
void releasePinnedMem();
|
||||
|
||||
//! Finds if pinned memory is cached
|
||||
amd::Memory* findPinnedMem(void* addr, size_t size);
|
||||
|
||||
//! Returns gsl memory object for VM
|
||||
const gslMemObject* vmMems() const { return vmMems_; }
|
||||
|
||||
//! Returns the virtual gpu unique index
|
||||
uint index() const { return index_; }
|
||||
//! Returns the monitor object for execution access by VirtualGPU
|
||||
amd::Monitor& execution() { return execution_; }
|
||||
|
||||
//! Get the PrintfDbg object
|
||||
PrintfDbg& printfDbg() const { return *printfDbg_; }
|
||||
//! Returns the virtual gpu unique index
|
||||
uint index() const { return index_; }
|
||||
|
||||
//! Get the PrintfDbgHSA object
|
||||
PrintfDbgHSA& printfDbgHSA() const { return *printfDbgHSA_; }
|
||||
//! Get the PrintfDbg object
|
||||
PrintfDbg& printfDbg() const { return *printfDbg_; }
|
||||
|
||||
//! Enables synchronized transfers
|
||||
void enableSyncedBlit() const;
|
||||
|
||||
//! Checks if profiling is enabled
|
||||
bool profiling() const { return state_.profiling_; }
|
||||
|
||||
//! Returns memory dependency class
|
||||
MemoryDependency& memoryDependency() { return memoryDependency_; }
|
||||
|
||||
//! Returns hsaQueueMem_
|
||||
const Memory* hsaQueueMem() const { return hsaQueueMem_;}
|
||||
|
||||
//! Returns DMA flush management structure
|
||||
const DmaFlushMgmt& dmaFlushMgmt() const { return dmaFlushMgmt_; }
|
||||
|
||||
//! Releases GSL memory objects allocated on this queue
|
||||
void releaseMemObjects(bool scratch = true);
|
||||
|
||||
//! Returns the HW ring used on this virtual device
|
||||
uint hwRing() const { return hwRing_; }
|
||||
|
||||
//! Returns current timestamp object for profiling
|
||||
TimeStamp* currTs() const { return cal_.lastTS_; }
|
||||
|
||||
//! Returns virtual queue object for device enqueuing
|
||||
Memory* vQueue() const { return virtualQueue_; }
|
||||
|
||||
//! Update virtual queue header
|
||||
void writeVQueueHeader(VirtualGPU& hostQ, uint64_t kernelTable);
|
||||
|
||||
//! Returns TRUE if virtual queue was successfully allocatted
|
||||
bool createVirtualQueue(
|
||||
uint deviceQueueSize //!< Device queue size
|
||||
);
|
||||
|
||||
EngineType engineID_; //!< Engine ID for this VirtualGPU
|
||||
ResourceSlots slots_; //!< Resource slots for kernel arguments
|
||||
State state_; //!< virtual GPU current state
|
||||
CalVirtualDesc cal_; //!< CAL virtual device descriptor
|
||||
|
||||
void flushCuCaches(HwDbgGpuCacheMask cache_mask); //!< flush/invalidate SQ cache
|
||||
|
||||
protected:
|
||||
virtual void profileEvent(EngineType engine, bool type) const;
|
||||
|
||||
//! Creates buffer object from image
|
||||
amd::Memory* createBufferFromImage(
|
||||
amd::Memory& amdImage //! The parent image object(untiled images only)
|
||||
) const;
|
||||
|
||||
private:
|
||||
typedef std::map<CALimage, GslKernelDesc*> GslKernels;
|
||||
typedef std::map<gslMemObject, GpuEvent> GpuEvents;
|
||||
|
||||
//! Finds total amount of necessary iterations
|
||||
inline void findIterations(
|
||||
const amd::NDRangeContainer& sizes, //!< Original workload sizes
|
||||
const amd::NDRange& local, //!< Local workgroup size
|
||||
amd::NDRange& groups, //!< Calculated workgroup sizes
|
||||
amd::NDRange& remainder, //!< Calculated remainder sizes
|
||||
size_t& extra //!< Amount of extra executions for remainder
|
||||
);
|
||||
|
||||
//! Setups workloads for the current iteration
|
||||
inline void setupIteration(
|
||||
uint iteration, //!< Current iteration
|
||||
const amd::NDRangeContainer& sizes, //!< Original workload sizes
|
||||
Kernel& gpuKernel, //!< GPU kernel
|
||||
amd::NDRange& global, //!< Global size for the current iteration
|
||||
amd::NDRange& offsets, //!< Offsets for the current iteration
|
||||
amd::NDRange& local, //!< Local sizes for the current iteration
|
||||
amd::NDRange& groups, //!< Group sizes for the current iteration
|
||||
amd::NDRange& groupOffset, //!< Group offsets for the current iteration
|
||||
amd::NDRange& divider, //!< Group divider
|
||||
amd::NDRange& remainder, //!< Remain workload
|
||||
size_t extra //!< Extra groups
|
||||
);
|
||||
|
||||
//! Allocates constant buffers
|
||||
bool allocConstantBuffers();
|
||||
|
||||
//! Allocates CAL kernel descriptor of the virtual device
|
||||
GslKernelDesc* allocKernelDesc(
|
||||
const Kernel* kernel, //!< Kernel object
|
||||
CALimage calImage); //!< CAL image
|
||||
|
||||
//! Frees CAL kernel descriptor of the virtual device
|
||||
void freeKernelDesc(GslKernelDesc* desc);
|
||||
|
||||
bool gslOpen(uint nEngines, gslEngineDescriptor *engines, uint32_t rtCUs);
|
||||
void gslDestroy();
|
||||
|
||||
//! Releases stage write buffers
|
||||
void releaseXferWrite();
|
||||
|
||||
//! Allocate hsaQueueMem_
|
||||
bool allocHsaQueueMem();
|
||||
|
||||
//! Awaits a command batch with a waiting event
|
||||
bool awaitCompletion(
|
||||
CommandBatch* cb, //!< Command batch for to wait
|
||||
const amd::Event* waitingEvent = NULL //!< A waiting event
|
||||
);
|
||||
|
||||
//! Validates the scratch buffer memory for a specified kernel
|
||||
void validateScratchBuffer(
|
||||
const Kernel* kernel //!< Kernel for validaiton
|
||||
);
|
||||
|
||||
//! Detects memory dependency for HSAIL kernels and flushes caches
|
||||
bool processMemObjectsHSA(
|
||||
const amd::Kernel& kernel, //!< AMD kernel object for execution
|
||||
const_address params, //!< Pointer to the param's store
|
||||
bool nativeMem, //!< Native memory objects
|
||||
std::vector<const Memory*>* memList //!< Memory list for KMD tracking
|
||||
);
|
||||
|
||||
//! Common function for fill memory used by both svm Fill and non-svm fill
|
||||
bool fillMemory(
|
||||
cl_command_type type, //!< the command type
|
||||
amd::Memory* amdMemory, //!< memory object to fill
|
||||
const void* pattern, //!< pattern to fill the memory
|
||||
size_t patternSize, //!< pattern size
|
||||
const amd::Coord3D& origin, //!< memory origin
|
||||
const amd::Coord3D& size //!< memory size for filling
|
||||
);
|
||||
|
||||
bool copyMemory(
|
||||
cl_command_type type, //!< the command type
|
||||
amd::Memory& srcMem, //!< source memory object
|
||||
amd::Memory& dstMem, //!< destination memory object
|
||||
bool entire, //!< flag of entire memory copy
|
||||
const amd::Coord3D& srcOrigin, //!< source memory origin
|
||||
const amd::Coord3D& dstOrigin, //!< destination memory object
|
||||
const amd::Coord3D& size, //!< copy size
|
||||
const amd::BufferRect& srcRect, //!< region of source for copy
|
||||
const amd::BufferRect& dstRect //!< region of destination for copy
|
||||
);
|
||||
|
||||
void buildKernelInfo(
|
||||
const HSAILKernel& hsaKernel, //!< hsa kernel
|
||||
hsa_kernel_dispatch_packet_t* aqlPkt, //!< aql packet for dispatch
|
||||
HwDbgKernelInfo& kernelInfo, //!< kernel info for the dispatch
|
||||
amd::Event* enqueueEvent //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
|
||||
void assignDebugTrapHandler(
|
||||
const DebugToolInfo& dbgSetting, //!< debug settings
|
||||
HwDbgKernelInfo& kernelInfo //!< kernel info for the dispatch
|
||||
);
|
||||
|
||||
GslKernels gslKernels_; //!< GSL kernel descriptors
|
||||
GslKernelDesc* activeKernelDesc_; //!< active GSL kernel descriptors
|
||||
GpuEvents gpuEvents_; //!< GPU events
|
||||
|
||||
Device& gpuDevice_; //!< physical GPU device
|
||||
amd::Monitor execution_; //!< Lock to serialise access to all device objects
|
||||
uint index_; //!< The virtual device unique index
|
||||
|
||||
PrintfDbg* printfDbg_; //!< GPU printf implemenation
|
||||
PrintfDbgHSA* printfDbgHSA_; //!< HSAIL printf implemenation
|
||||
|
||||
TimeStampCache* tsCache_; //!< TimeStamp cache
|
||||
MemoryDependency memoryDependency_; //!< Memory dependency class
|
||||
|
||||
gslMemObject* vmMems_; //!< Array of GSL memories for VM mode
|
||||
uint numVmMems_; //!< Number of entries in VM mem array
|
||||
|
||||
DmaFlushMgmt dmaFlushMgmt_; //!< DMA flush management
|
||||
|
||||
std::list<Memory*> xferWriteBuffers_; //!< Stage write buffers
|
||||
std::list<amd::Memory*> pinnedMems_;//!< Pinned memory list
|
||||
|
||||
typedef std::list<CommandBatch*> CommandBatchList;
|
||||
CommandBatchList cbList_; //!< List of command batches
|
||||
|
||||
uint hwRing_; //!< HW ring used on this virtual device
|
||||
|
||||
uint64_t readjustTimeGPU_; //!< Readjust time between GPU and CPU timestamps
|
||||
TimeStamp* currTs_; //!< current timestamp for command
|
||||
|
||||
AmdVQueueHeader* vqHeader_; //!< Sysmem copy for virtual queue header
|
||||
Memory* virtualQueue_; //!< Virtual device queue
|
||||
Memory* schedParams_; //!< The scheduler parameters
|
||||
uint schedParamIdx_; //!< Index in the scheduler parameters buffer
|
||||
uint deviceQueueSize_; //!< Device queue size
|
||||
uint maskGroups_; //!< The number of mask groups processed in the scheduler by one thread
|
||||
|
||||
Memory* hsaQueueMem_; //!< Memory for the amd_queue_t object
|
||||
bool profileEnabled_;//!< Profiling is enabled
|
||||
//! Get the PrintfDbgHSA object
|
||||
PrintfDbgHSA& printfDbgHSA() const { return *printfDbgHSA_; }
|
||||
|
||||
//! Enables synchronized transfers
|
||||
void enableSyncedBlit() const;
|
||||
|
||||
//! Checks if profiling is enabled
|
||||
bool profiling() const { return state_.profiling_; }
|
||||
|
||||
//! Returns memory dependency class
|
||||
MemoryDependency& memoryDependency() { return memoryDependency_; }
|
||||
|
||||
//! Returns hsaQueueMem_
|
||||
const Memory* hsaQueueMem() const { return hsaQueueMem_; }
|
||||
|
||||
//! Returns DMA flush management structure
|
||||
const DmaFlushMgmt& dmaFlushMgmt() const { return dmaFlushMgmt_; }
|
||||
|
||||
//! Releases GSL memory objects allocated on this queue
|
||||
void releaseMemObjects(bool scratch = true);
|
||||
|
||||
//! Returns the HW ring used on this virtual device
|
||||
uint hwRing() const { return hwRing_; }
|
||||
|
||||
//! Returns current timestamp object for profiling
|
||||
TimeStamp* currTs() const { return cal_.lastTS_; }
|
||||
|
||||
//! Returns virtual queue object for device enqueuing
|
||||
Memory* vQueue() const { return virtualQueue_; }
|
||||
|
||||
//! Update virtual queue header
|
||||
void writeVQueueHeader(VirtualGPU& hostQ, uint64_t kernelTable);
|
||||
|
||||
//! Returns TRUE if virtual queue was successfully allocatted
|
||||
bool createVirtualQueue(uint deviceQueueSize //!< Device queue size
|
||||
);
|
||||
|
||||
EngineType engineID_; //!< Engine ID for this VirtualGPU
|
||||
ResourceSlots slots_; //!< Resource slots for kernel arguments
|
||||
State state_; //!< virtual GPU current state
|
||||
CalVirtualDesc cal_; //!< CAL virtual device descriptor
|
||||
|
||||
void flushCuCaches(HwDbgGpuCacheMask cache_mask); //!< flush/invalidate SQ cache
|
||||
|
||||
protected:
|
||||
virtual void profileEvent(EngineType engine, bool type) const;
|
||||
|
||||
//! Creates buffer object from image
|
||||
amd::Memory* createBufferFromImage(
|
||||
amd::Memory& amdImage //! The parent image object(untiled images only)
|
||||
) const;
|
||||
|
||||
private:
|
||||
typedef std::map<CALimage, GslKernelDesc*> GslKernels;
|
||||
typedef std::map<gslMemObject, GpuEvent> GpuEvents;
|
||||
|
||||
//! Finds total amount of necessary iterations
|
||||
inline void findIterations(const amd::NDRangeContainer& sizes, //!< Original workload sizes
|
||||
const amd::NDRange& local, //!< Local workgroup size
|
||||
amd::NDRange& groups, //!< Calculated workgroup sizes
|
||||
amd::NDRange& remainder, //!< Calculated remainder sizes
|
||||
size_t& extra //!< Amount of extra executions for remainder
|
||||
);
|
||||
|
||||
//! Setups workloads for the current iteration
|
||||
inline void setupIteration(
|
||||
uint iteration, //!< Current iteration
|
||||
const amd::NDRangeContainer& sizes, //!< Original workload sizes
|
||||
Kernel& gpuKernel, //!< GPU kernel
|
||||
amd::NDRange& global, //!< Global size for the current iteration
|
||||
amd::NDRange& offsets, //!< Offsets for the current iteration
|
||||
amd::NDRange& local, //!< Local sizes for the current iteration
|
||||
amd::NDRange& groups, //!< Group sizes for the current iteration
|
||||
amd::NDRange& groupOffset, //!< Group offsets for the current iteration
|
||||
amd::NDRange& divider, //!< Group divider
|
||||
amd::NDRange& remainder, //!< Remain workload
|
||||
size_t extra //!< Extra groups
|
||||
);
|
||||
|
||||
//! Allocates constant buffers
|
||||
bool allocConstantBuffers();
|
||||
|
||||
//! Allocates CAL kernel descriptor of the virtual device
|
||||
GslKernelDesc* allocKernelDesc(const Kernel* kernel, //!< Kernel object
|
||||
CALimage calImage); //!< CAL image
|
||||
|
||||
//! Frees CAL kernel descriptor of the virtual device
|
||||
void freeKernelDesc(GslKernelDesc* desc);
|
||||
|
||||
bool gslOpen(uint nEngines, gslEngineDescriptor* engines, uint32_t rtCUs);
|
||||
void gslDestroy();
|
||||
|
||||
//! Releases stage write buffers
|
||||
void releaseXferWrite();
|
||||
|
||||
//! Allocate hsaQueueMem_
|
||||
bool allocHsaQueueMem();
|
||||
|
||||
//! Awaits a command batch with a waiting event
|
||||
bool awaitCompletion(CommandBatch* cb, //!< Command batch for to wait
|
||||
const amd::Event* waitingEvent = NULL //!< A waiting event
|
||||
);
|
||||
|
||||
//! Validates the scratch buffer memory for a specified kernel
|
||||
void validateScratchBuffer(const Kernel* kernel //!< Kernel for validaiton
|
||||
);
|
||||
|
||||
//! Detects memory dependency for HSAIL kernels and flushes caches
|
||||
bool processMemObjectsHSA(const amd::Kernel& kernel, //!< AMD kernel object for execution
|
||||
const_address params, //!< Pointer to the param's store
|
||||
bool nativeMem, //!< Native memory objects
|
||||
std::vector<const Memory*>* memList //!< Memory list for KMD tracking
|
||||
);
|
||||
|
||||
//! Common function for fill memory used by both svm Fill and non-svm fill
|
||||
bool fillMemory(cl_command_type type, //!< the command type
|
||||
amd::Memory* amdMemory, //!< memory object to fill
|
||||
const void* pattern, //!< pattern to fill the memory
|
||||
size_t patternSize, //!< pattern size
|
||||
const amd::Coord3D& origin, //!< memory origin
|
||||
const amd::Coord3D& size //!< memory size for filling
|
||||
);
|
||||
|
||||
bool copyMemory(cl_command_type type, //!< the command type
|
||||
amd::Memory& srcMem, //!< source memory object
|
||||
amd::Memory& dstMem, //!< destination memory object
|
||||
bool entire, //!< flag of entire memory copy
|
||||
const amd::Coord3D& srcOrigin, //!< source memory origin
|
||||
const amd::Coord3D& dstOrigin, //!< destination memory object
|
||||
const amd::Coord3D& size, //!< copy size
|
||||
const amd::BufferRect& srcRect, //!< region of source for copy
|
||||
const amd::BufferRect& dstRect //!< region of destination for copy
|
||||
);
|
||||
|
||||
void buildKernelInfo(const HSAILKernel& hsaKernel, //!< hsa kernel
|
||||
hsa_kernel_dispatch_packet_t* aqlPkt, //!< aql packet for dispatch
|
||||
HwDbgKernelInfo& kernelInfo, //!< kernel info for the dispatch
|
||||
amd::Event* enqueueEvent //!< Event provided in the enqueue kernel command
|
||||
);
|
||||
|
||||
void assignDebugTrapHandler(const DebugToolInfo& dbgSetting, //!< debug settings
|
||||
HwDbgKernelInfo& kernelInfo //!< kernel info for the dispatch
|
||||
);
|
||||
|
||||
GslKernels gslKernels_; //!< GSL kernel descriptors
|
||||
GslKernelDesc* activeKernelDesc_; //!< active GSL kernel descriptors
|
||||
GpuEvents gpuEvents_; //!< GPU events
|
||||
|
||||
Device& gpuDevice_; //!< physical GPU device
|
||||
amd::Monitor execution_; //!< Lock to serialise access to all device objects
|
||||
uint index_; //!< The virtual device unique index
|
||||
|
||||
PrintfDbg* printfDbg_; //!< GPU printf implemenation
|
||||
PrintfDbgHSA* printfDbgHSA_; //!< HSAIL printf implemenation
|
||||
|
||||
TimeStampCache* tsCache_; //!< TimeStamp cache
|
||||
MemoryDependency memoryDependency_; //!< Memory dependency class
|
||||
|
||||
gslMemObject* vmMems_; //!< Array of GSL memories for VM mode
|
||||
uint numVmMems_; //!< Number of entries in VM mem array
|
||||
|
||||
DmaFlushMgmt dmaFlushMgmt_; //!< DMA flush management
|
||||
|
||||
std::list<Memory*> xferWriteBuffers_; //!< Stage write buffers
|
||||
std::list<amd::Memory*> pinnedMems_; //!< Pinned memory list
|
||||
|
||||
typedef std::list<CommandBatch*> CommandBatchList;
|
||||
CommandBatchList cbList_; //!< List of command batches
|
||||
|
||||
uint hwRing_; //!< HW ring used on this virtual device
|
||||
|
||||
uint64_t readjustTimeGPU_; //!< Readjust time between GPU and CPU timestamps
|
||||
TimeStamp* currTs_; //!< current timestamp for command
|
||||
|
||||
AmdVQueueHeader* vqHeader_; //!< Sysmem copy for virtual queue header
|
||||
Memory* virtualQueue_; //!< Virtual device queue
|
||||
Memory* schedParams_; //!< The scheduler parameters
|
||||
uint schedParamIdx_; //!< Index in the scheduler parameters buffer
|
||||
uint deviceQueueSize_; //!< Device queue size
|
||||
uint maskGroups_; //!< The number of mask groups processed in the scheduler by one thread
|
||||
|
||||
Memory* hsaQueueMem_; //!< Memory for the amd_queue_t object
|
||||
bool profileEnabled_; //!< Profiling is enabled
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
@@ -19,336 +19,317 @@ uint WLAlgorithmSmooth::AdaptCount;
|
||||
uint WLAlgorithmSmooth::AbandonThresh;
|
||||
uint WLAlgorithmSmooth::DscThresh;
|
||||
|
||||
WaveLimiter::WaveLimiter(
|
||||
WaveLimiterManager* manager,
|
||||
uint seqNum,
|
||||
bool enable,
|
||||
bool enableDump):
|
||||
manager_(manager),
|
||||
dumper_(manager_->name() + "_" + std::to_string(seqNum), enableDump) {
|
||||
WaveLimiter::WaveLimiter(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump)
|
||||
: manager_(manager), dumper_(manager_->name() + "_" + std::to_string(seqNum), enableDump) {
|
||||
setIfNotDefault(SIMDPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, manager->getSimdPerSH());
|
||||
MaxWave = GPU_WAVE_LIMIT_MAX_WAVE;
|
||||
WarmUpCount = GPU_WAVE_LIMIT_WARMUP;
|
||||
RunCount = GPU_WAVE_LIMIT_RUN * MaxWave;
|
||||
|
||||
setIfNotDefault(SIMDPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, manager->getSimdPerSH());
|
||||
MaxWave = GPU_WAVE_LIMIT_MAX_WAVE;
|
||||
WarmUpCount = GPU_WAVE_LIMIT_WARMUP;
|
||||
RunCount = GPU_WAVE_LIMIT_RUN * MaxWave;
|
||||
state_ = WARMUP;
|
||||
if (!flagIsDefault(GPU_WAVE_LIMIT_TRACE)) {
|
||||
traceStream_.open(std::string(GPU_WAVE_LIMIT_TRACE) + manager_->name() + ".txt");
|
||||
}
|
||||
|
||||
state_ = WARMUP;
|
||||
if (!flagIsDefault(GPU_WAVE_LIMIT_TRACE)) {
|
||||
traceStream_.open(std::string(GPU_WAVE_LIMIT_TRACE) + manager_->name() +
|
||||
".txt");
|
||||
}
|
||||
|
||||
waves_ = MaxWave;
|
||||
currWaves_ = MaxWave;
|
||||
bestWave_ = MaxWave;
|
||||
enable_ = enable;
|
||||
waves_ = MaxWave;
|
||||
currWaves_ = MaxWave;
|
||||
bestWave_ = MaxWave;
|
||||
enable_ = enable;
|
||||
}
|
||||
|
||||
WaveLimiter::~WaveLimiter() {
|
||||
if (traceStream_.is_open()) {
|
||||
traceStream_.close();
|
||||
}
|
||||
if (traceStream_.is_open()) {
|
||||
traceStream_.close();
|
||||
}
|
||||
}
|
||||
|
||||
uint WaveLimiter::getWavesPerSH(){
|
||||
currWaves_ = waves_;
|
||||
return waves_ * SIMDPerSH_;
|
||||
uint WaveLimiter::getWavesPerSH() {
|
||||
currWaves_ = waves_;
|
||||
return waves_ * SIMDPerSH_;
|
||||
}
|
||||
|
||||
WLAlgorithmSmooth::WLAlgorithmSmooth(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump):
|
||||
WaveLimiter(manager, seqNum, enable, enableDump) {
|
||||
AdaptCount = 2 * MaxWave + 1;
|
||||
AbandonThresh = GPU_WAVE_LIMIT_ABANDON;
|
||||
DscThresh = GPU_WAVE_LIMIT_DSC_THRESH;
|
||||
WLAlgorithmSmooth::WLAlgorithmSmooth(WaveLimiterManager* manager, uint seqNum, bool enable,
|
||||
bool enableDump)
|
||||
: WaveLimiter(manager, seqNum, enable, enableDump) {
|
||||
AdaptCount = 2 * MaxWave + 1;
|
||||
AbandonThresh = GPU_WAVE_LIMIT_ABANDON;
|
||||
DscThresh = GPU_WAVE_LIMIT_DSC_THRESH;
|
||||
|
||||
dynRunCount_ = RunCount;
|
||||
measure_.resize(MaxWave + 1);
|
||||
reference_.resize(MaxWave + 1);
|
||||
trial_.resize(MaxWave + 1);
|
||||
ratio_.resize(MaxWave + 1);
|
||||
dynRunCount_ = RunCount;
|
||||
measure_.resize(MaxWave + 1);
|
||||
reference_.resize(MaxWave + 1);
|
||||
trial_.resize(MaxWave + 1);
|
||||
ratio_.resize(MaxWave + 1);
|
||||
|
||||
clearData();
|
||||
clearData();
|
||||
}
|
||||
|
||||
WLAlgorithmSmooth::~WLAlgorithmSmooth() {
|
||||
|
||||
}
|
||||
WLAlgorithmSmooth::~WLAlgorithmSmooth() {}
|
||||
|
||||
void WLAlgorithmSmooth::clearData() {
|
||||
waves_ = MaxWave;
|
||||
countAll_ = 0;
|
||||
clear(measure_);
|
||||
clear(reference_);
|
||||
clear(trial_);
|
||||
clear(ratio_);
|
||||
discontinuous_ = false;
|
||||
dataCount_ = 0;
|
||||
waves_ = MaxWave;
|
||||
countAll_ = 0;
|
||||
clear(measure_);
|
||||
clear(reference_);
|
||||
clear(trial_);
|
||||
clear(ratio_);
|
||||
discontinuous_ = false;
|
||||
dataCount_ = 0;
|
||||
}
|
||||
|
||||
void WLAlgorithmSmooth::updateData(ulong time) {
|
||||
auto count = dataCount_ - 1;
|
||||
assert(count < 2 * MaxWave + 1);
|
||||
assert(time > 0);
|
||||
assert(currWaves_ == waves_);
|
||||
if (count % 2 == 0) {
|
||||
assert(waves_ == MaxWave);
|
||||
auto pos = count / 2;
|
||||
measure_[pos] = time;
|
||||
if (pos > 0) {
|
||||
auto wave = MaxWave + 1 - pos;
|
||||
if (abs(static_cast<long>(measure_[pos - 1]) -
|
||||
static_cast<long>(measure_[pos])) * 100 / measure_[pos] >
|
||||
DscThresh) {
|
||||
discontinuous_ = true;
|
||||
}
|
||||
reference_[wave] = (time + measure_[pos - 1]) / 2;
|
||||
ratio_[wave] = trial_[wave] * 100 / reference_[wave];
|
||||
if (ratio_[bestWave_] > ratio_[wave] && !discontinuous_) {
|
||||
bestWave_ = wave;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(waves_ == MaxWave - count / 2);
|
||||
trial_[waves_] = time;
|
||||
auto count = dataCount_ - 1;
|
||||
assert(count < 2 * MaxWave + 1);
|
||||
assert(time > 0);
|
||||
assert(currWaves_ == waves_);
|
||||
if (count % 2 == 0) {
|
||||
assert(waves_ == MaxWave);
|
||||
auto pos = count / 2;
|
||||
measure_[pos] = time;
|
||||
if (pos > 0) {
|
||||
auto wave = MaxWave + 1 - pos;
|
||||
if (abs(static_cast<long>(measure_[pos - 1]) - static_cast<long>(measure_[pos])) * 100 /
|
||||
measure_[pos] >
|
||||
DscThresh) {
|
||||
discontinuous_ = true;
|
||||
}
|
||||
reference_[wave] = (time + measure_[pos - 1]) / 2;
|
||||
ratio_[wave] = trial_[wave] * 100 / reference_[wave];
|
||||
if (ratio_[bestWave_] > ratio_[wave] && !discontinuous_) {
|
||||
bestWave_ = wave;
|
||||
}
|
||||
}
|
||||
outputTrace();
|
||||
} else {
|
||||
assert(waves_ == MaxWave - count / 2);
|
||||
trial_[waves_] = time;
|
||||
}
|
||||
outputTrace();
|
||||
}
|
||||
|
||||
void WLAlgorithmSmooth::outputTrace() {
|
||||
if (!traceStream_.is_open()) {
|
||||
return;
|
||||
}
|
||||
if (!traceStream_.is_open()) {
|
||||
return;
|
||||
}
|
||||
|
||||
traceStream_ << "[WaveLimiter] " << manager_->name() << " state=" << state_
|
||||
<< " currWaves=" << currWaves_ << " waves=" << waves_
|
||||
<< " bestWave=" << bestWave_ << '\n';
|
||||
output(traceStream_, "\n measure = ", measure_);
|
||||
output(traceStream_, "\n reference = ", reference_);
|
||||
output(traceStream_, "\n ratio = ", ratio_);
|
||||
traceStream_ << "\n\n";
|
||||
traceStream_ << "[WaveLimiter] " << manager_->name() << " state=" << state_
|
||||
<< " currWaves=" << currWaves_ << " waves=" << waves_ << " bestWave=" << bestWave_
|
||||
<< '\n';
|
||||
output(traceStream_, "\n measure = ", measure_);
|
||||
output(traceStream_, "\n reference = ", reference_);
|
||||
output(traceStream_, "\n ratio = ", ratio_);
|
||||
traceStream_ << "\n\n";
|
||||
}
|
||||
|
||||
|
||||
void WLAlgorithmSmooth::callback(ulong duration) {
|
||||
dumper_.addData(duration, currWaves_, static_cast<char>(state_));
|
||||
dumper_.addData(duration, currWaves_, static_cast<char>(state_));
|
||||
|
||||
if (!enable_ || (duration == 0)) {
|
||||
return;
|
||||
}
|
||||
if (!enable_ || (duration == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
countAll_++;
|
||||
countAll_++;
|
||||
|
||||
switch (state_) {
|
||||
switch (state_) {
|
||||
case WARMUP:
|
||||
if (countAll_ < WarmUpCount) {
|
||||
return;
|
||||
}
|
||||
state_ = ADAPT;
|
||||
bestWave_ = MaxWave;
|
||||
clearData();
|
||||
if (countAll_ < WarmUpCount) {
|
||||
return;
|
||||
}
|
||||
state_ = ADAPT;
|
||||
bestWave_ = MaxWave;
|
||||
clearData();
|
||||
return;
|
||||
case ADAPT:
|
||||
assert(duration > 0);
|
||||
if (waves_ == currWaves_) {
|
||||
dataCount_++;
|
||||
updateData(duration);
|
||||
waves_ = MaxWave + 1 - dataCount_ / 2;
|
||||
if (dataCount_ == 1 || (dataCount_ < AdaptCount &&
|
||||
!discontinuous_ && (dataCount_ % 2 == 0 ||
|
||||
ratio_[waves_] < AbandonThresh))) {
|
||||
if (dataCount_ % 2 == 1) {
|
||||
--waves_;
|
||||
} else {
|
||||
waves_ = MaxWave;
|
||||
}
|
||||
return;
|
||||
}
|
||||
waves_ = bestWave_;
|
||||
if (dataCount_ >= AdaptCount) {
|
||||
dynRunCount_ = RunCount;
|
||||
} else {
|
||||
dynRunCount_ = AdaptCount;
|
||||
}
|
||||
countAll_ = rand() % MaxWave;
|
||||
state_ = RUN;
|
||||
assert(duration > 0);
|
||||
if (waves_ == currWaves_) {
|
||||
dataCount_++;
|
||||
updateData(duration);
|
||||
waves_ = MaxWave + 1 - dataCount_ / 2;
|
||||
if (dataCount_ == 1 || (dataCount_ < AdaptCount && !discontinuous_ &&
|
||||
(dataCount_ % 2 == 0 || ratio_[waves_] < AbandonThresh))) {
|
||||
if (dataCount_ % 2 == 1) {
|
||||
--waves_;
|
||||
} else {
|
||||
waves_ = MaxWave;
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
waves_ = bestWave_;
|
||||
if (dataCount_ >= AdaptCount) {
|
||||
dynRunCount_ = RunCount;
|
||||
} else {
|
||||
dynRunCount_ = AdaptCount;
|
||||
}
|
||||
countAll_ = rand() % MaxWave;
|
||||
state_ = RUN;
|
||||
}
|
||||
return;
|
||||
case RUN:
|
||||
if (countAll_ < dynRunCount_) {
|
||||
return;
|
||||
}
|
||||
state_ = ADAPT;
|
||||
bestWave_ = MaxWave;
|
||||
clearData();
|
||||
if (countAll_ < dynRunCount_) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
state_ = ADAPT;
|
||||
bestWave_ = MaxWave;
|
||||
clearData();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WaveLimiter::DataDumper::DataDumper(const std::string &kernelName, bool enable) {
|
||||
enable_ = enable;
|
||||
if (enable_) {
|
||||
fileName_ = std::string(GPU_WAVE_LIMIT_DUMP) + kernelName + ".csv";
|
||||
}
|
||||
WaveLimiter::DataDumper::DataDumper(const std::string& kernelName, bool enable) {
|
||||
enable_ = enable;
|
||||
if (enable_) {
|
||||
fileName_ = std::string(GPU_WAVE_LIMIT_DUMP) + kernelName + ".csv";
|
||||
}
|
||||
}
|
||||
|
||||
WaveLimiter::DataDumper::~DataDumper() {
|
||||
if (!enable_) {
|
||||
return;
|
||||
}
|
||||
if (!enable_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::ofstream OFS(fileName_);
|
||||
for (size_t i = 0, e = time_.size(); i != e; ++i) {
|
||||
OFS << i << ',' << time_[i] << ',' << wavePerSIMD_[i] << ','
|
||||
<< static_cast<uint>(state_[i]) << '\n';
|
||||
}
|
||||
OFS.close();
|
||||
std::ofstream OFS(fileName_);
|
||||
for (size_t i = 0, e = time_.size(); i != e; ++i) {
|
||||
OFS << i << ',' << time_[i] << ',' << wavePerSIMD_[i] << ',' << static_cast<uint>(state_[i])
|
||||
<< '\n';
|
||||
}
|
||||
OFS.close();
|
||||
}
|
||||
|
||||
void WaveLimiter::DataDumper::addData(ulong time, uint wave, char state) {
|
||||
if (!enable_) {
|
||||
return;
|
||||
}
|
||||
if (!enable_) {
|
||||
return;
|
||||
}
|
||||
|
||||
time_.push_back(time);
|
||||
wavePerSIMD_.push_back(wave);
|
||||
state_.push_back(state);
|
||||
time_.push_back(time);
|
||||
wavePerSIMD_.push_back(wave);
|
||||
state_.push_back(state);
|
||||
}
|
||||
|
||||
WLAlgorithmAvrg::WLAlgorithmAvrg(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump):
|
||||
WaveLimiter(manager, seqNum, enable, enableDump) {
|
||||
|
||||
measure_.resize(MaxWave + 1);
|
||||
clear(measure_);
|
||||
countAll_ = 0;
|
||||
WLAlgorithmAvrg::WLAlgorithmAvrg(WaveLimiterManager* manager, uint seqNum, bool enable,
|
||||
bool enableDump)
|
||||
: WaveLimiter(manager, seqNum, enable, enableDump) {
|
||||
measure_.resize(MaxWave + 1);
|
||||
clear(measure_);
|
||||
countAll_ = 0;
|
||||
}
|
||||
|
||||
WLAlgorithmAvrg::~WLAlgorithmAvrg() {
|
||||
|
||||
}
|
||||
WLAlgorithmAvrg::~WLAlgorithmAvrg() {}
|
||||
|
||||
void WLAlgorithmAvrg::outputTrace() {
|
||||
if (!traceStream_.is_open()) {
|
||||
return;
|
||||
}
|
||||
if (!traceStream_.is_open()) {
|
||||
return;
|
||||
}
|
||||
|
||||
traceStream_ << "[WaveLimiter] " << manager_->name() << " state=" << state_
|
||||
<< " currWaves=" << currWaves_ << " waves=" << waves_
|
||||
<< " bestWave=" << bestWave_ << '\n';
|
||||
output(traceStream_, "\n measure = ", measure_);
|
||||
traceStream_ << "\n\n";
|
||||
traceStream_ << "[WaveLimiter] " << manager_->name() << " state=" << state_
|
||||
<< " currWaves=" << currWaves_ << " waves=" << waves_ << " bestWave=" << bestWave_
|
||||
<< '\n';
|
||||
output(traceStream_, "\n measure = ", measure_);
|
||||
traceStream_ << "\n\n";
|
||||
}
|
||||
|
||||
|
||||
void WLAlgorithmAvrg::callback(ulong duration) {
|
||||
dumper_.addData(duration, currWaves_, static_cast<char>(state_));
|
||||
dumper_.addData(duration, currWaves_, static_cast<char>(state_));
|
||||
|
||||
if (!enable_) {
|
||||
return;
|
||||
}
|
||||
if (!enable_) {
|
||||
return;
|
||||
}
|
||||
|
||||
countAll_++;
|
||||
countAll_++;
|
||||
|
||||
switch (state_) {
|
||||
switch (state_) {
|
||||
case WARMUP:
|
||||
state_ = ADAPT;
|
||||
state_ = ADAPT;
|
||||
case ADAPT:
|
||||
measure_[waves_] += duration;
|
||||
if (countAll_ <= MaxWave * 5) {
|
||||
waves_--;
|
||||
if (waves_ == 0) {
|
||||
waves_ = MaxWave;
|
||||
}
|
||||
measure_[waves_] += duration;
|
||||
if (countAll_ <= MaxWave * 5) {
|
||||
waves_--;
|
||||
if (waves_ == 0) {
|
||||
waves_ = MaxWave;
|
||||
}
|
||||
else {
|
||||
bestWave_ = MaxWave;
|
||||
for (uint i=1; i<MaxWave; i++ ) {
|
||||
if (measure_[i] < measure_[bestWave_]) {
|
||||
bestWave_ = i;
|
||||
}
|
||||
}
|
||||
waves_ = bestWave_;
|
||||
state_ = RUN;
|
||||
} else {
|
||||
bestWave_ = MaxWave;
|
||||
for (uint i = 1; i < MaxWave; i++) {
|
||||
if (measure_[i] < measure_[bestWave_]) {
|
||||
bestWave_ = i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
waves_ = bestWave_;
|
||||
state_ = RUN;
|
||||
}
|
||||
break;
|
||||
case RUN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WaveLimiterManager::WaveLimiterManager(device::Kernel* kernel, const uint simdPerSH):
|
||||
owner_(kernel),
|
||||
enable_(false),
|
||||
enableDump_(!flagIsDefault(GPU_WAVE_LIMIT_DUMP)) {
|
||||
setIfNotDefault(simdPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, simdPerSH);
|
||||
fixed_ = GPU_WAVES_PER_SIMD * simdPerSH_;
|
||||
WaveLimiterManager::WaveLimiterManager(device::Kernel* kernel, const uint simdPerSH)
|
||||
: owner_(kernel), enable_(false), enableDump_(!flagIsDefault(GPU_WAVE_LIMIT_DUMP)) {
|
||||
setIfNotDefault(simdPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, simdPerSH);
|
||||
fixed_ = GPU_WAVES_PER_SIMD * simdPerSH_;
|
||||
}
|
||||
|
||||
WaveLimiterManager::~WaveLimiterManager() {
|
||||
for (auto &I: limiters_) {
|
||||
delete I.second;
|
||||
}
|
||||
for (auto& I : limiters_) {
|
||||
delete I.second;
|
||||
}
|
||||
}
|
||||
|
||||
uint WaveLimiterManager::getWavesPerSH(const device::VirtualDevice *vdev) const {
|
||||
if (fixed_ > 0) {
|
||||
return fixed_;
|
||||
}
|
||||
if (!enable_) {
|
||||
return 0;
|
||||
}
|
||||
auto loc = limiters_.find(vdev);
|
||||
if (loc == limiters_.end()) {
|
||||
return 0;
|
||||
}
|
||||
assert(loc->second != NULL);
|
||||
return loc->second->getWavesPerSH();
|
||||
uint WaveLimiterManager::getWavesPerSH(const device::VirtualDevice* vdev) const {
|
||||
if (fixed_ > 0) {
|
||||
return fixed_;
|
||||
}
|
||||
if (!enable_) {
|
||||
return 0;
|
||||
}
|
||||
auto loc = limiters_.find(vdev);
|
||||
if (loc == limiters_.end()) {
|
||||
return 0;
|
||||
}
|
||||
assert(loc->second != NULL);
|
||||
return loc->second->getWavesPerSH();
|
||||
}
|
||||
|
||||
amd::ProfilingCallback* WaveLimiterManager::getProfilingCallback(
|
||||
const device::VirtualDevice *vdev) {
|
||||
assert(vdev != NULL);
|
||||
if (!enable_ && !enableDump_) {
|
||||
return NULL;
|
||||
}
|
||||
const device::VirtualDevice* vdev) {
|
||||
assert(vdev != NULL);
|
||||
if (!enable_ && !enableDump_) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
amd::ScopedLock SL(monitor_);
|
||||
auto loc = limiters_.find(vdev);
|
||||
if (loc != limiters_.end()) {
|
||||
return loc->second;
|
||||
}
|
||||
amd::ScopedLock SL(monitor_);
|
||||
auto loc = limiters_.find(vdev);
|
||||
if (loc != limiters_.end()) {
|
||||
return loc->second;
|
||||
}
|
||||
|
||||
auto limiter = new WLAlgorithmSmooth(this, limiters_.size(), enable_,
|
||||
enableDump_);
|
||||
if (limiter == NULL) {
|
||||
enable_ = false;
|
||||
return NULL;
|
||||
}
|
||||
limiters_[vdev] = limiter;
|
||||
return limiter;
|
||||
auto limiter = new WLAlgorithmSmooth(this, limiters_.size(), enable_, enableDump_);
|
||||
if (limiter == NULL) {
|
||||
enable_ = false;
|
||||
return NULL;
|
||||
}
|
||||
limiters_[vdev] = limiter;
|
||||
return limiter;
|
||||
}
|
||||
|
||||
void WaveLimiterManager::enable(const bool isCiPlus) {
|
||||
if (fixed_ > 0) {
|
||||
return;
|
||||
}
|
||||
if (fixed_ > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable it only for CI+, unless GPU_WAVE_LIMIT_ENABLE is set to 1
|
||||
// Disabled for SI due to bug #10817
|
||||
if (!flagIsDefault(GPU_WAVE_LIMIT_ENABLE)) {
|
||||
enable_ = GPU_WAVE_LIMIT_ENABLE;
|
||||
}
|
||||
else {
|
||||
if (isCiPlus) {
|
||||
if (owner_->workGroupInfo()->wavesPerSimdHint_ == 0) {
|
||||
enable_ = true;
|
||||
}
|
||||
else if (owner_->workGroupInfo()->wavesPerSimdHint_ <= GPU_WAVE_LIMIT_MAX_WAVE) {
|
||||
fixed_ = owner_->workGroupInfo()->wavesPerSimdHint_ * getSimdPerSH();
|
||||
}
|
||||
}
|
||||
// Enable it only for CI+, unless GPU_WAVE_LIMIT_ENABLE is set to 1
|
||||
// Disabled for SI due to bug #10817
|
||||
if (!flagIsDefault(GPU_WAVE_LIMIT_ENABLE)) {
|
||||
enable_ = GPU_WAVE_LIMIT_ENABLE;
|
||||
} else {
|
||||
if (isCiPlus) {
|
||||
if (owner_->workGroupInfo()->wavesPerSimdHint_ == 0) {
|
||||
enable_ = true;
|
||||
} else if (owner_->workGroupInfo()->wavesPerSimdHint_ <= GPU_WAVE_LIMIT_MAX_WAVE) {
|
||||
fixed_ = owner_->workGroupInfo()->wavesPerSimdHint_ * getSimdPerSH();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,144 +19,146 @@ namespace gpu {
|
||||
class WaveLimiterManager;
|
||||
|
||||
// Adaptively limit the number of waves per SIMD based on kernel execution time
|
||||
class WaveLimiter: public amd::ProfilingCallback {
|
||||
public:
|
||||
explicit WaveLimiter(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump);
|
||||
virtual ~WaveLimiter();
|
||||
class WaveLimiter : public amd::ProfilingCallback {
|
||||
public:
|
||||
explicit WaveLimiter(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump);
|
||||
virtual ~WaveLimiter();
|
||||
|
||||
//! Get waves per shader array to be used for kernel execution.
|
||||
uint getWavesPerSH();
|
||||
//! Get waves per shader array to be used for kernel execution.
|
||||
uint getWavesPerSH();
|
||||
|
||||
protected:
|
||||
enum StateKind {
|
||||
WARMUP, ADAPT, RUN
|
||||
};
|
||||
protected:
|
||||
enum StateKind { WARMUP, ADAPT, RUN };
|
||||
|
||||
class DataDumper {
|
||||
public:
|
||||
explicit DataDumper(const std::string &kernelName, bool enable);
|
||||
~DataDumper();
|
||||
class DataDumper {
|
||||
public:
|
||||
explicit DataDumper(const std::string& kernelName, bool enable);
|
||||
~DataDumper();
|
||||
|
||||
//! Record execution time, waves/simd and state of wave limiter.
|
||||
void addData(ulong time, uint wave, char state);
|
||||
//! Record execution time, waves/simd and state of wave limiter.
|
||||
void addData(ulong time, uint wave, char state);
|
||||
|
||||
//! Whether this data dumper is enabled.
|
||||
bool enabled() const { return enable_;}
|
||||
private:
|
||||
bool enable_;
|
||||
std::string fileName_;
|
||||
std::vector<ulong> time_;
|
||||
std::vector<uint> wavePerSIMD_;
|
||||
std::vector<char> state_;
|
||||
};
|
||||
//! Whether this data dumper is enabled.
|
||||
bool enabled() const { return enable_; }
|
||||
|
||||
std::vector<uint64_t> measure_;
|
||||
private:
|
||||
bool enable_;
|
||||
uint SIMDPerSH_; // Number of SIMDs per SH
|
||||
uint waves_; // Waves per SIMD to be set
|
||||
uint bestWave_; // Optimal waves per SIMD
|
||||
uint countAll_; // Number of kernel executions
|
||||
StateKind state_;
|
||||
WaveLimiterManager* manager_;
|
||||
DataDumper dumper_;
|
||||
std::ofstream traceStream_;
|
||||
uint currWaves_; // Current waves per SIMD
|
||||
std::string fileName_;
|
||||
std::vector<ulong> time_;
|
||||
std::vector<uint> wavePerSIMD_;
|
||||
std::vector<char> state_;
|
||||
};
|
||||
|
||||
static uint MaxWave; // Maximum number of waves per SIMD
|
||||
static uint WarmUpCount; // Number of kernel executions for warm up
|
||||
static uint RunCount; // Number of kernel executions for normal run
|
||||
std::vector<uint64_t> measure_;
|
||||
bool enable_;
|
||||
uint SIMDPerSH_; // Number of SIMDs per SH
|
||||
uint waves_; // Waves per SIMD to be set
|
||||
uint bestWave_; // Optimal waves per SIMD
|
||||
uint countAll_; // Number of kernel executions
|
||||
StateKind state_;
|
||||
WaveLimiterManager* manager_;
|
||||
DataDumper dumper_;
|
||||
std::ofstream traceStream_;
|
||||
uint currWaves_; // Current waves per SIMD
|
||||
|
||||
//! Call back from Event::recordProfilingInfo to get execution time.
|
||||
virtual void callback(ulong duration)=0;
|
||||
static uint MaxWave; // Maximum number of waves per SIMD
|
||||
static uint WarmUpCount; // Number of kernel executions for warm up
|
||||
static uint RunCount; // Number of kernel executions for normal run
|
||||
|
||||
//! Output trace of measurement/adaptation.
|
||||
virtual void outputTrace()=0;
|
||||
//! Call back from Event::recordProfilingInfo to get execution time.
|
||||
virtual void callback(ulong duration) = 0;
|
||||
|
||||
template<class T> void clear(T& A) {
|
||||
for (auto &I : A) {
|
||||
I = 0;
|
||||
}
|
||||
//! Output trace of measurement/adaptation.
|
||||
virtual void outputTrace() = 0;
|
||||
|
||||
template <class T> void clear(T& A) {
|
||||
for (auto& I : A) {
|
||||
I = 0;
|
||||
}
|
||||
template<class T> void output(std::ofstream &ofs, const std::string &prompt,
|
||||
T& A) {
|
||||
ofs << prompt;
|
||||
for (auto &I : A) {
|
||||
ofs << ' ' << static_cast<ulong>(I);
|
||||
}
|
||||
}
|
||||
template <class T> void output(std::ofstream& ofs, const std::string& prompt, T& A) {
|
||||
ofs << prompt;
|
||||
for (auto& I : A) {
|
||||
ofs << ' ' << static_cast<ulong>(I);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class WLAlgorithmSmooth: public WaveLimiter {
|
||||
public:
|
||||
explicit WLAlgorithmSmooth(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump);
|
||||
virtual ~WLAlgorithmSmooth();
|
||||
private:
|
||||
std::vector<uint64_t> reference_;
|
||||
std::vector<uint64_t> trial_;
|
||||
std::vector<uint64_t> ratio_;
|
||||
bool discontinuous_; // Measured data is discontinuous
|
||||
uint dynRunCount_;
|
||||
uint dataCount_;
|
||||
class WLAlgorithmSmooth : public WaveLimiter {
|
||||
public:
|
||||
explicit WLAlgorithmSmooth(WaveLimiterManager* manager, uint seqNum, bool enable,
|
||||
bool enableDump);
|
||||
virtual ~WLAlgorithmSmooth();
|
||||
|
||||
static uint AdaptCount; // Number of kernel executions for adapting
|
||||
static uint AbandonThresh; // Threshold to abandon adaptation
|
||||
static uint DscThresh; // Threshold for identifying discontinuities
|
||||
private:
|
||||
std::vector<uint64_t> reference_;
|
||||
std::vector<uint64_t> trial_;
|
||||
std::vector<uint64_t> ratio_;
|
||||
bool discontinuous_; // Measured data is discontinuous
|
||||
uint dynRunCount_;
|
||||
uint dataCount_;
|
||||
|
||||
//! Update measurement data and optimal waves/simd with execution time.
|
||||
void updateData(ulong time);
|
||||
static uint AdaptCount; // Number of kernel executions for adapting
|
||||
static uint AbandonThresh; // Threshold to abandon adaptation
|
||||
static uint DscThresh; // Threshold for identifying discontinuities
|
||||
|
||||
//! Clear measurement data for the next adaptation.
|
||||
void clearData();
|
||||
//! Update measurement data and optimal waves/simd with execution time.
|
||||
void updateData(ulong time);
|
||||
|
||||
//! Call back from Event::recordProfilingInfo to get execution time.
|
||||
void callback(ulong duration);
|
||||
//! Clear measurement data for the next adaptation.
|
||||
void clearData();
|
||||
|
||||
//! Output trace of measurement/adaptation.
|
||||
void outputTrace();
|
||||
//! Call back from Event::recordProfilingInfo to get execution time.
|
||||
void callback(ulong duration);
|
||||
|
||||
//! Output trace of measurement/adaptation.
|
||||
void outputTrace();
|
||||
};
|
||||
|
||||
class WLAlgorithmAvrg: public WaveLimiter {
|
||||
public:
|
||||
explicit WLAlgorithmAvrg(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump);
|
||||
virtual ~WLAlgorithmAvrg();
|
||||
private:
|
||||
//! Call back from Event::recordProfilingInfo to get execution time.
|
||||
void callback(ulong duration);
|
||||
class WLAlgorithmAvrg : public WaveLimiter {
|
||||
public:
|
||||
explicit WLAlgorithmAvrg(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump);
|
||||
virtual ~WLAlgorithmAvrg();
|
||||
|
||||
//! Output trace of measurement/adaptation.
|
||||
void outputTrace();
|
||||
private:
|
||||
//! Call back from Event::recordProfilingInfo to get execution time.
|
||||
void callback(ulong duration);
|
||||
|
||||
//! Output trace of measurement/adaptation.
|
||||
void outputTrace();
|
||||
};
|
||||
|
||||
// Create wave limiter for each virtual device for a kernel and manages the wave limiters.
|
||||
class WaveLimiterManager {
|
||||
public:
|
||||
explicit WaveLimiterManager(device::Kernel* owner, const uint simdPerSH);
|
||||
virtual ~WaveLimiterManager();
|
||||
public:
|
||||
explicit WaveLimiterManager(device::Kernel* owner, const uint simdPerSH);
|
||||
virtual ~WaveLimiterManager();
|
||||
|
||||
//! Get waves per shader array for a specific virtual device.
|
||||
uint getWavesPerSH(const device::VirtualDevice *) const;
|
||||
//! Get waves per shader array for a specific virtual device.
|
||||
uint getWavesPerSH(const device::VirtualDevice*) const;
|
||||
|
||||
//! Provide call back function for a specific virtual device.
|
||||
amd::ProfilingCallback* getProfilingCallback(const device::VirtualDevice *);
|
||||
//! Provide call back function for a specific virtual device.
|
||||
amd::ProfilingCallback* getProfilingCallback(const device::VirtualDevice*);
|
||||
|
||||
//! Enable wave limiter manager by kernel metadata and flags.
|
||||
void enable(const bool isCiPlus);
|
||||
//! Enable wave limiter manager by kernel metadata and flags.
|
||||
void enable(const bool isCiPlus);
|
||||
|
||||
//! Returns the kernel name
|
||||
const std::string& name() const { return owner_->name(); }
|
||||
//! Returns the kernel name
|
||||
const std::string& name() const { return owner_->name(); }
|
||||
|
||||
//! Get SimdPerSH.
|
||||
uint getSimdPerSH() const {return simdPerSH_;}
|
||||
//! Get SimdPerSH.
|
||||
uint getSimdPerSH() const { return simdPerSH_; }
|
||||
|
||||
private:
|
||||
device::Kernel *owner_; // The kernel which owns this object
|
||||
uint simdPerSH_; // Simd Per SH
|
||||
std::unordered_map<const device::VirtualDevice *,
|
||||
WaveLimiter*> limiters_; // Maps virtual device to wave limiter
|
||||
bool enable_; // Whether the adaptation is enabled
|
||||
bool enableDump_; // Whether the data dumper is enabled
|
||||
uint fixed_; // The fixed waves/simd value if not zero
|
||||
amd::Monitor monitor_; // The mutex for updating the wave limiter map
|
||||
private:
|
||||
device::Kernel* owner_; // The kernel which owns this object
|
||||
uint simdPerSH_; // Simd Per SH
|
||||
std::unordered_map<const device::VirtualDevice*,
|
||||
WaveLimiter*>
|
||||
limiters_; // Maps virtual device to wave limiter
|
||||
bool enable_; // Whether the adaptation is enabled
|
||||
bool enableDump_; // Whether the data dumper is enabled
|
||||
uint fixed_; // The fixed waves/simd value if not zero
|
||||
amd::Monitor monitor_; // The mutex for updating the wave limiter map
|
||||
};
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user