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
This commit is contained in:
1 bovenliggende
a615e4fbb6
commit
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_
|
||||
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_
|
||||
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
File diff suppressed because it is too large.
Load diff
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