SWDEV-286150 - Remove GSL backend
Change-Id: Iba9a997ee7d5ff6ac00d5888ff189a4514958fe9
Este commit está contenido en:
@@ -44,5 +44,5 @@ find_package_handle_standard_args(AMD_UGL
|
||||
AMD_UGL_INCLUDE_DIR)
|
||||
mark_as_advanced(AMD_UGL_INCLUDE_DIR)
|
||||
|
||||
set(AMD_UGL_INCLUDE_DIRS ${AMD_UGL_INCLUDE_DIR} ${ROCCLR_SRC_DIR}/device/gpu/gslbe/src/rt)
|
||||
set(AMD_UGL_INCLUDE_DIRS ${AMD_UGL_INCLUDE_DIR})
|
||||
mark_as_advanced(AMD_UGL_INCLUDE_DIRS)
|
||||
|
||||
+79
-95
@@ -40,11 +40,6 @@ extern void PalDeviceUnload();
|
||||
//}
|
||||
#endif // WITH_PAL_DEVICE
|
||||
|
||||
#if defined(WITH_GPU_DEVICE)
|
||||
extern bool DeviceLoad();
|
||||
extern void DeviceUnload();
|
||||
#endif // WITH_GPU_DEVICE
|
||||
|
||||
#include "platform/runtime.hpp"
|
||||
#include "platform/program.hpp"
|
||||
#include "thread/monitor.hpp"
|
||||
@@ -112,86 +107,85 @@ std::pair<const Isa*, const Isa*> Isa::supportedIsas() {
|
||||
// If the HSAIL or AMD IL compilers do not support the target, then use
|
||||
// nullptr for the ID.
|
||||
//
|
||||
// -------------------- Compiler -------------------- ------- Runtime ----- ---- IP ---- --- Target --- ---------- Target Properties ----------
|
||||
// Supported Version Features Mem
|
||||
// SIMD Channel LDS LDS
|
||||
// SIMD/ SIMD Instr Bank Size/ Mem
|
||||
// Target ID HSAIL ID ROC PAL GSL Maj/Min/Stp SRAMECC XNACK CU Width Width Width CU Banks
|
||||
{"gfx700", "Kaveri", true, false, true, 7, 0, 0, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Also Spectre, Spooky, Kalindi
|
||||
{"gfx701", "Hawaii", true, false, true, 7, 0, 1, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Actually Hawaiipro
|
||||
{"gfx702", "gfx702", true, false, true, 7, 0, 2, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Actually Hawaii (can execute Hawiipro code)
|
||||
{"gfx703", nullptr, false, false, true, 7, 0, 3, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Mullins
|
||||
{"gfx704", "Bonaire", false, false, true, 7, 0, 4, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx705", "Mullins", false, false, true, 7, 0, 5, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Actually Godavari
|
||||
{"gfx801", nullptr, true, true, true, 8, 0, 1, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx801:xnack-", nullptr, true, false, true, 8, 0, 1, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx801:xnack+", "Carrizo", true, true, true, 8, 0, 1, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx802", "Tonga", true, true, true, 8, 0, 2, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Also Iceland
|
||||
{"gfx803", "Fiji", true, true, true, 8, 0, 3, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Also Ellesmere/Polaris10, Baffin/Polaris11, Polaris12, Polaris22/VegaM
|
||||
{"gfx805", nullptr, true, true, true, 8, 0, 5, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Tongapro
|
||||
{"gfx810", nullptr, true, true, true, 8, 1, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx810:xnack-", nullptr, true, false, true, 8, 1, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx810:xnack+", "Stoney", true, true, true, 8, 1, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx900", "gfx901", true, true, false, 9, 0, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Greenland
|
||||
{"gfx900:xnack-", "gfx900", true, true, false, 9, 0, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx900:xnack+", "gfx901", true, true, false, 9, 0, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx902", "gfx903", true, true, false, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Raven
|
||||
{"gfx902:xnack-", "gfx902", true, true, false, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx902:xnack+", "gfx903", true, true, false, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx904", "gfx905", true, true, false, 9, 0, 4, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Vega12
|
||||
{"gfx904:xnack-", "gfx904", true, true, false, 9, 0, 4, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx904:xnack+", "gfx905", true, true, false, 9, 0, 4, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906", "gfx907", true, true, false, 9, 0, 6, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Vega20
|
||||
{"gfx906:sramecc-", "gfx907", true, true, false, 9, 0, 6, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc+", nullptr, true, true, false, 9, 0, 6, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:xnack-", "gfx906", true, true, false, 9, 0, 6, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:xnack+", "gfx907", true, true, false, 9, 0, 6, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc-:xnack-", "gfx906", true, true, false, 9, 0, 6, OFF, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc-:xnack+", "gfx907", true, true, false, 9, 0, 6, OFF, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc+:xnack-", nullptr, true, true, false, 9, 0, 6, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc+:xnack+", nullptr, true, true, false, 9, 0, 6, ON, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908", nullptr, true, false, false, 9, 0, 8, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc-", nullptr, true, false, false, 9, 0, 8, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc+", nullptr, true, false, false, 9, 0, 8, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:xnack-", nullptr, true, false, false, 9, 0, 8, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:xnack+", nullptr, true, false, false, 9, 0, 8, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc-:xnack-", nullptr, true, false, false, 9, 0, 8, OFF, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc-:xnack+", nullptr, true, false, false, 9, 0, 8, OFF, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc+:xnack-", nullptr, true, false, false, 9, 0, 8, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc+:xnack+", nullptr, true, false, false, 9, 0, 8, ON, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx909", nullptr, false, true, false, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Raven2 (can execute Raven code)
|
||||
{"gfx909:xnack-", nullptr, false, true, false, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx909:xnack+", nullptr, false, true, false, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a", nullptr, true, false, false, 9, 0, 10, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc-", nullptr, true, false, false, 9, 0, 10, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc+", nullptr, true, false, false, 9, 0, 10, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:xnack-", nullptr, true, false, false, 9, 0, 10, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:xnack+", nullptr, true, false, false, 9, 0, 10, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc-:xnack-", nullptr, true, false, false, 9, 0, 10, OFF, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc-:xnack+", nullptr, true, false, false, 9, 0, 10, OFF, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc+:xnack-", nullptr, true, false, false, 9, 0, 10, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc+:xnack+", nullptr, true, false, false, 9, 0, 10, ON, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90c", nullptr, true, true, false, 9, 0, 12, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Renoir
|
||||
{"gfx90c:xnack-", "gfx90c", true, true, false, 9, 0, 12, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90c:xnack+", "gfx90d", true, true, false, 9, 0, 12, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1010", "gfx1010", true, true, false, 10, 1, 0, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1010:xnack-", "gfx1010", true, true, false, 10, 1, 0, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1010:xnack+", nullptr, true, true, false, 10, 1, 0, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1011", "gfx1011", true, true, false, 10, 1, 1, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1011:xnack-", "gfx1011", true, true, false, 10, 1, 1, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1011:xnack+", nullptr, true, true, false, 10, 1, 1, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1012", "gfx1012", true, true, false, 10, 1, 2, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1012:xnack-", "gfx1012", true, true, false, 10, 1, 2, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1012:xnack+", nullptr, true, true, false, 10, 1, 2, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1013", "gfx1013", true, false, false, 10, 1, 3, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1013:xnack-", "gfx1013", true, false, false, 10, 1, 3, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1013:xnack+", nullptr, true, false, false, 10, 1, 3, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1030", "gfx1030", true, true, false, 10, 3, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1031", "gfx1031", true, true, false, 10, 3, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1032", "gfx1032", true, true, false, 10, 3, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1033", "gfx1033", true, false, false, 10, 3, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1034", "gfx1034", true, true, false, 10, 3, 4, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1035", "gfx1035", true, true, false, 10, 3, 5, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
// -------------- Compiler ---------- - Runtime - ---- IP ---- -- Target -- ---------- Target Properties ----------
|
||||
// Supported Version Features
|
||||
// SIMD/ SIMD Instr Bank LDS Mem
|
||||
// Target ID HSAIL ID ROC PAL Maj/Min/Stp SRAMECC XNACK CU Width Width Width Size Banks
|
||||
{"gfx700", "Kaveri", true, false, 7, 0, 0, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Also Spectre, Spooky, Kalindi
|
||||
{"gfx701", "Hawaii", true, false, 7, 0, 1, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Actually Hawaiipro
|
||||
{"gfx702", "gfx702", true, false, 7, 0, 2, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Actually Hawaii (can execute Hawiipro code)
|
||||
{"gfx703", nullptr, false, false, 7, 0, 3, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Mullins
|
||||
{"gfx704", "Bonaire", false, false, 7, 0, 4, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx705", "Mullins", false, false, 7, 0, 5, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Actually Godavari
|
||||
{"gfx801", nullptr, true, true, 8, 0, 1, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx801:xnack-", nullptr, true, false, 8, 0, 1, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx801:xnack+", "Carrizo", true, true, 8, 0, 1, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx802", "Tonga", true, true, 8, 0, 2, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Also Iceland
|
||||
{"gfx803", "Fiji", true, true, 8, 0, 3, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Also Ellesmere/Polaris10, Baffin/Polaris11, Polaris12, Polaris22/VegaM
|
||||
{"gfx805", nullptr, true, true, 8, 0, 5, NONE, NONE, 4, 16, 1, 256, 64 * Ki, 32}, // Tongapro
|
||||
{"gfx810", nullptr, true, true, 8, 1, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx810:xnack-", nullptr, true, false, 8, 1, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx810:xnack+", "Stoney", true, true, 8, 1, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx900", "gfx901", true, true, 9, 0, 0, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Greenland
|
||||
{"gfx900:xnack-", "gfx900", true, true, 9, 0, 0, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx900:xnack+", "gfx901", true, true, 9, 0, 0, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx902", "gfx903", true, true, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Raven
|
||||
{"gfx902:xnack-", "gfx902", true, true, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx902:xnack+", "gfx903", true, true, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx904", "gfx905", true, true, 9, 0, 4, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Vega12
|
||||
{"gfx904:xnack-", "gfx904", true, true, 9, 0, 4, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx904:xnack+", "gfx905", true, true, 9, 0, 4, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906", "gfx907", true, true, 9, 0, 6, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Vega20
|
||||
{"gfx906:sramecc-", "gfx907", true, true, 9, 0, 6, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc+", nullptr, true, true, 9, 0, 6, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:xnack-", "gfx906", true, true, 9, 0, 6, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:xnack+", "gfx907", true, true, 9, 0, 6, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc-:xnack-", "gfx906", true, true, 9, 0, 6, OFF, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc-:xnack+", "gfx907", true, true, 9, 0, 6, OFF, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc+:xnack-", nullptr, true, true, 9, 0, 6, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx906:sramecc+:xnack+", nullptr, true, true, 9, 0, 6, ON, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908", nullptr, true, false, 9, 0, 8, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc-", nullptr, true, false, 9, 0, 8, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc+", nullptr, true, false, 9, 0, 8, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:xnack-", nullptr, true, false, 9, 0, 8, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:xnack+", nullptr, true, false, 9, 0, 8, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc-:xnack-", nullptr, true, false, 9, 0, 8, OFF, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc-:xnack+", nullptr, true, false, 9, 0, 8, OFF, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc+:xnack-", nullptr, true, false, 9, 0, 8, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx908:sramecc+:xnack+", nullptr, true, false, 9, 0, 8, ON, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx909", nullptr, false, true, 9, 0, 2, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Raven2 (can execute Raven code)
|
||||
{"gfx909:xnack-", nullptr, false, true, 9, 0, 2, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx909:xnack+", nullptr, false, true, 9, 0, 2, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a", nullptr, true, false, 9, 0, 10, ANY, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc-", nullptr, true, false, 9, 0, 10, OFF, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc+", nullptr, true, false, 9, 0, 10, ON, ANY, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:xnack-", nullptr, true, false, 9, 0, 10, ANY, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:xnack+", nullptr, true, false, 9, 0, 10, ANY, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc-:xnack-", nullptr, true, false, 9, 0, 10, OFF, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc-:xnack+", nullptr, true, false, 9, 0, 10, OFF, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc+:xnack-", nullptr, true, false, 9, 0, 10, ON, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90a:sramecc+:xnack+", nullptr, true, false, 9, 0, 10, ON, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90c", nullptr, true, true, 9, 0, 12, NONE, ANY, 4, 16, 1, 256, 64 * Ki, 32}, // Also Renoir
|
||||
{"gfx90c:xnack-", "gfx90c", true, true, 9, 0, 12, NONE, OFF, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx90c:xnack+", "gfx90d", true, true, 9, 0, 12, NONE, ON, 4, 16, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1010", "gfx1010", true, true, 10, 1, 0, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1010:xnack-", "gfx1010", true, true, 10, 1, 0, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1010:xnack+", nullptr, true, true, 10, 1, 0, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1011", "gfx1011", true, true, 10, 1, 1, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1011:xnack-", "gfx1011", true, true, 10, 1, 1, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1011:xnack+", nullptr, true, true, 10, 1, 1, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1012", "gfx1012", true, true, 10, 1, 2, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1012:xnack-", "gfx1012", true, true, 10, 1, 2, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1012:xnack+", nullptr, true, true, 10, 1, 2, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1013", "gfx1013", true, false, 10, 1, 3, NONE, ANY, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1013:xnack-", "gfx1013", true, false, 10, 1, 3, NONE, OFF, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1013:xnack+", nullptr, true, false, 10, 1, 3, NONE, ON, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1030", "gfx1030", true, true, 10, 3, 0, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1031", "gfx1031", true, true, 10, 3, 1, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1032", "gfx1032", true, true, 10, 3, 2, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1033", "gfx1033", true, false, 10, 3, 3, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1034", "gfx1034", true, true, 10, 3, 4, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
{"gfx1035", "gfx1035", true, true, 10, 3, 5, NONE, NONE, 2, 32, 1, 256, 64 * Ki, 32},
|
||||
};
|
||||
return std::make_pair(std::begin(supportedIsas_), std::end(supportedIsas_));
|
||||
}
|
||||
@@ -431,11 +425,6 @@ bool Device::init() {
|
||||
}
|
||||
}
|
||||
#endif // WITH_HSA_DEVICE
|
||||
#if defined(WITH_GPU_DEVICE)
|
||||
if (GPU_ENABLE_PAL != 1) {
|
||||
ret |= DeviceLoad();
|
||||
}
|
||||
#endif // WITH_GPU_DEVICE
|
||||
#if defined(WITH_PAL_DEVICE)
|
||||
if (GPU_ENABLE_PAL != 0) {
|
||||
ret |= PalDeviceLoad();
|
||||
@@ -455,11 +444,6 @@ void Device::tearDown() {
|
||||
#if defined(WITH_HSA_DEVICE)
|
||||
roc::Device::tearDown();
|
||||
#endif // WITH_HSA_DEVICE
|
||||
#if defined(WITH_GPU_DEVICE)
|
||||
if (GPU_ENABLE_PAL != 1) {
|
||||
DeviceUnload();
|
||||
}
|
||||
#endif // WITH_GPU_DEVICE
|
||||
#if defined(WITH_PAL_DEVICE)
|
||||
if (GPU_ENABLE_PAL != 0) {
|
||||
PalDeviceUnload();
|
||||
|
||||
@@ -1351,11 +1351,6 @@ class Isa {
|
||||
return runtimePalSupported_;
|
||||
}
|
||||
|
||||
/// @returns If the GSL runtime supports the ISA.
|
||||
bool runtimeGslSupported() const {
|
||||
return runtimeGslSupported_;
|
||||
}
|
||||
|
||||
/// @returns SRAM ECC feature status.
|
||||
const Feature &sramecc() const {
|
||||
return sramecc_;
|
||||
@@ -1441,7 +1436,7 @@ class Isa {
|
||||
private:
|
||||
|
||||
constexpr Isa(const char* targetId, const char* hsailId,
|
||||
bool runtimeRocSupported, bool runtimePalSupported, bool runtimeGslSupported,
|
||||
bool runtimeRocSupported, bool runtimePalSupported,
|
||||
uint32_t versionMajor, uint32_t versionMinor, uint32_t versionStepping,
|
||||
Feature sramecc, Feature xnack, uint32_t simdPerCU, uint32_t simdWidth,
|
||||
uint32_t simdInstructionWidth, uint32_t memChannelBankWidth,
|
||||
@@ -1450,7 +1445,6 @@ class Isa {
|
||||
hsailId_(hsailId),
|
||||
runtimeRocSupported_(runtimeRocSupported),
|
||||
runtimePalSupported_(runtimePalSupported),
|
||||
runtimeGslSupported_(runtimeGslSupported),
|
||||
versionMajor_(versionMajor),
|
||||
versionMinor_(versionMinor),
|
||||
versionStepping_(versionStepping),
|
||||
@@ -1477,7 +1471,6 @@ class Isa {
|
||||
|
||||
bool runtimeRocSupported_; //!< ROCm runtime is supported.
|
||||
bool runtimePalSupported_; //!< PAL runtime is supported.
|
||||
bool runtimeGslSupported_; //!< GSL runtime is supported.
|
||||
uint32_t versionMajor_; //!< Isa's major version.
|
||||
uint32_t versionMinor_; //!< Isa's minor version.
|
||||
uint32_t versionStepping_; //!< Isa's stepping version.
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Copyright (c) 2014 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "top.hpp"
|
||||
#include "utils/debug.hpp"
|
||||
#include "device/appprofile.hpp"
|
||||
#include "device/gpu/gpuappprofile.hpp"
|
||||
|
||||
namespace gpu {
|
||||
|
||||
AppProfile::AppProfile()
|
||||
: amd::AppProfile(), enableHighPerformanceState_(true), reportAsOCL12Device_(false) {
|
||||
propertyDataMap_.insert({"HighPerfState", PropertyData(DataType_Boolean, &enableHighPerformanceState_)});
|
||||
propertyDataMap_.insert({"OCL12Device", PropertyData(DataType_Boolean, &reportAsOCL12Device_)});
|
||||
propertyDataMap_.insert({"SclkThreshold", PropertyData(DataType_String, &sclkThreshold_)});
|
||||
propertyDataMap_.insert({"DownHysteresis", PropertyData(DataType_String, &downHysteresis_)});
|
||||
propertyDataMap_.insert({"UpHysteresis", PropertyData(DataType_String, &upHysteresis_)});
|
||||
propertyDataMap_.insert({"PowerLimit", PropertyData(DataType_String, &powerLimit_)});
|
||||
propertyDataMap_.insert({"MclkThreshold", PropertyData(DataType_String, &mclkThreshold_)});
|
||||
propertyDataMap_.insert({"MclkUpHyst", PropertyData(DataType_String, &mclkUpHyst_)});
|
||||
propertyDataMap_.insert({"MclkDownHyst", PropertyData(DataType_String, &mclkDownHyst_)});
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Copyright (c) 2014 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUAPPPROFILE_HPP_
|
||||
#define GPUAPPPROFILE_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class AppProfile : public amd::AppProfile {
|
||||
public:
|
||||
AppProfile();
|
||||
|
||||
//! return the value of enableHighPerformanceState_
|
||||
bool enableHighPerformanceState() const { return enableHighPerformanceState_; }
|
||||
bool reportAsOCL12Device() const { return reportAsOCL12Device_; }
|
||||
const std::string& GetSclkThreshold() const { return sclkThreshold_; }
|
||||
const std::string& GetDownHysteresis() const { return downHysteresis_; }
|
||||
const std::string& GetUpHysteresis() const { return upHysteresis_; }
|
||||
const std::string& GetPowerLimit() const { return powerLimit_; }
|
||||
const std::string& GetMclkThreshold() const { return mclkThreshold_; }
|
||||
const std::string& GetMclkUpHyst() const { return mclkUpHyst_; }
|
||||
const std::string& GetMclkDownHyst() const { return mclkDownHyst_; }
|
||||
|
||||
private:
|
||||
bool enableHighPerformanceState_;
|
||||
bool reportAsOCL12Device_;
|
||||
std::string sclkThreshold_;
|
||||
std::string downHysteresis_;
|
||||
std::string upHysteresis_;
|
||||
std::string powerLimit_;
|
||||
std::string mclkThreshold_;
|
||||
std::string mclkUpHyst_;
|
||||
std::string mclkDownHyst_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,513 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "device/gpu/gpubinary.hpp"
|
||||
#include "device/gpu/gpuprogram.hpp"
|
||||
#include "utils/options.hpp"
|
||||
#include "os/os.hpp"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
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::Elf::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";
|
||||
|
||||
*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::Elf::ElfPlatform platform;
|
||||
if (!elfIn()->getTarget(elf_target, platform)) {
|
||||
LogError("The OCL binary image loading failed: incorrect format");
|
||||
return false;
|
||||
}
|
||||
if (platform == amd::Elf::COMPLIB_PLATFORM) {
|
||||
// BIF 3.0
|
||||
uint32_t flag;
|
||||
aclTargetInfo tgtInfo = amd::Hsail::GetTargetInfo("amdil", nullptr, 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;
|
||||
}
|
||||
} else {
|
||||
if (((platform != amd::Elf::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::unordered_map<std::string, ElfSymbol_t*> functionNameMap;
|
||||
|
||||
// Keep all kernel ILs if -use-debugil is present (gpu debugging)
|
||||
std::unordered_map<std::string, std::string> kernelILs;
|
||||
|
||||
~TempWrapper() {
|
||||
for (const auto& it : functionNameMap) {
|
||||
delete it.second;
|
||||
}
|
||||
|
||||
kernelILs.clear();
|
||||
}
|
||||
} tempObj;
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
int num = elfIn()->getSymbolNum();
|
||||
for (int ndx = 0; ndx < num; ndx++) {
|
||||
amd::Elf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(ndx, &symInfo)) {
|
||||
LogError("LoadKernelFromElf: getSymbolInfo() fails");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string elfSymName(symInfo.sym_name);
|
||||
const size_t offset = sizeof(__OpenCL_) - 1;
|
||||
if (elfSymName.compare(0, offset, __OpenCL_) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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::Elf::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]);
|
||||
tempObj.functionNameMap[FName] = elfsymbol;
|
||||
|
||||
elfsymbol->IsKernel = isKernel;
|
||||
}
|
||||
sinfo[index] = symInfo;
|
||||
}
|
||||
}
|
||||
|
||||
std::string programil;
|
||||
if (usedebugil) {
|
||||
char* section;
|
||||
size_t sz;
|
||||
|
||||
if (elfIn_->getSection(amd::Elf::ILDEBUG, §ion, &sz)) {
|
||||
// Get debugIL
|
||||
programil.append(section, sz);
|
||||
} else {
|
||||
LogError("LoadKernelFromElf(): reading .debugil failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Append all function metadata to debugIL
|
||||
for (const auto& it : tempObj.functionNameMap) {
|
||||
ElfSymbol_t* elfsymbol = it.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[]
|
||||
for (const auto& it : tempObj.kernelILs) {
|
||||
const std::string& kn = it.first;
|
||||
const std::string& ilstr = it.second;
|
||||
|
||||
ElfSymbol_t* elfsymbol = tempObj.functionNameMap[kn];
|
||||
if (elfsymbol == NULL) {
|
||||
elfsymbol = new ElfSymbol_t();
|
||||
tempObj.functionNameMap[kn] = elfsymbol;
|
||||
}
|
||||
amd::Elf::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
|
||||
}
|
||||
}
|
||||
|
||||
bool recompiled = false;
|
||||
bool hasKernels = false;
|
||||
for (const auto& it : tempObj.functionNameMap) {
|
||||
ElfSymbol_t* elfsymbol = it.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 (false && (elfsymbol->SymInfo[NDX_METADATA].size > 0)) {
|
||||
std::string fmetadata = "__OpenCL_";
|
||||
fmetadata.append(it.first);
|
||||
fmetadata.append("_fmetadata");
|
||||
|
||||
if (!elfOut()->addSymbol(amd::Elf::RODATA, fmetadata.c_str(),
|
||||
elfsymbol->SymInfo[NDX_METADATA].address,
|
||||
elfsymbol->SymInfo[NDX_METADATA].size)) {
|
||||
LogError("AddSymbol() failed to add fmetadata");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
amd::Elf::SymbolInfo* sinfo = &(elfsymbol->SymInfo[0]);
|
||||
std::string FName = it.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::Elf::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;
|
||||
}
|
||||
}
|
||||
|
||||
*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()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// should we save kernel metadata only under saveAMDIL()?
|
||||
bool kernelMetaStored = false;
|
||||
|
||||
if (false && (ilSource.size() > 0)) {
|
||||
// Save IL (this is the per-kernel IL)
|
||||
std::string ilName = "__OpenCL_" + name + "_amdil";
|
||||
if (!elfOut()->addSymbol(amd::Elf::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::Elf::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::Elf::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::Elf::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::Elf::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";
|
||||
|
||||
int num = elfIn()->getSymbolNum();
|
||||
for (int ndx = 0; ndx < num; ndx++) {
|
||||
amd::Elf::SymbolInfo symInfo;
|
||||
if (!elfIn()->getSymbolInfo(ndx, &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::Elf::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
|
||||
@@ -1,114 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUBINARY_HPP_
|
||||
#define GPUBINARY_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "device/gpu/gpudevice.hpp"
|
||||
#include "device/gpu/gpukernel.hpp"
|
||||
|
||||
namespace gpu {
|
||||
|
||||
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 };
|
||||
|
||||
/* 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
|
||||
|
||||
/* New entries can be added here, do not change the previous entries */
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//! Constructor
|
||||
ClBinary(const NullDevice& dev, BinaryImageFormat bifVer = BIF_VERSION2)
|
||||
: device::ClBinary(dev, bifVer) {}
|
||||
|
||||
//! 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.
|
||||
);
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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::Elf::CAL_PLATFORM);
|
||||
}
|
||||
|
||||
//! Clear elf out.
|
||||
bool clearElfOut();
|
||||
|
||||
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_); }
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUBINARY_HPP_
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,427 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUBLIT_HPP_
|
||||
#define GPUBLIT_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "platform/command.hpp"
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/device.hpp"
|
||||
#include "device/blit.hpp"
|
||||
|
||||
/*! \addtogroup GPU Blit Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! GPU Blit Manager Implementation
|
||||
namespace gpu {
|
||||
|
||||
class Device;
|
||||
class Kernel;
|
||||
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
|
||||
);
|
||||
|
||||
//! Destructor
|
||||
virtual ~DmaBlitManager() {}
|
||||
|
||||
//! 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 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 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 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 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 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;
|
||||
|
||||
protected:
|
||||
static constexpr uint MaxPinnedBuffers = 4;
|
||||
|
||||
//! 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 GPU device object
|
||||
const Device& dev() const { return static_cast<const Device&>(dev_); };
|
||||
|
||||
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;
|
||||
|
||||
const size_t MinSizeForPinnedTransfer;
|
||||
bool completeOperation_; //!< DMA blit manager must complete operation
|
||||
amd::Context* context_; //!< A dummy context
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
DmaBlitManager(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;
|
||||
|
||||
//! 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,
|
||||
FillBufferAligned,
|
||||
FillImage,
|
||||
Scheduler,
|
||||
BlitTotal
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
KernelBlitManager(VirtualGPU& gpu, //!< Virtual GPU to be used for blits
|
||||
Setup setup = Setup() //!< Specifies HW accelerated blits
|
||||
);
|
||||
|
||||
//! Destructor
|
||||
virtual ~KernelBlitManager();
|
||||
|
||||
//! 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 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 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 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 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 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;
|
||||
|
||||
//! 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 fill region
|
||||
bool entire = false, //!< Entire buffer will be updated
|
||||
bool forceBlit = false //!< Force GPU Blit for fill
|
||||
) 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;
|
||||
|
||||
private:
|
||||
static constexpr size_t MaxXferBuffers = 2;
|
||||
static constexpr 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 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 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 operator=
|
||||
KernelBlitManager& operator=(const KernelBlitManager&);
|
||||
|
||||
amd::Program* program_; //!< GPU program object
|
||||
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] = {
|
||||
"__amd_rocclr_copyImage", "__amd_rocclr_copyImage1DA", "__amd_rocclr_copyImageToBuffer",
|
||||
"__amd_rocclr_copyBufferToImage", "__amd_rocclr_copyBufferRect",
|
||||
"__amd_rocclr_copyBufferRectAligned", "__amd_rocclr_copyBuffer",
|
||||
"__amd_rocclr_copyBufferAligned", "__amd_rocclr_fillBufferAligned",
|
||||
"__amd_rocclr_fillImage", "__amd_rocclr_scheduler"
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUBLIT_HPP_*/
|
||||
@@ -1,348 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "os/os.hpp"
|
||||
#include "device/gpu/gpudevice.hpp"
|
||||
#include "device/gpu/gpuprogram.hpp"
|
||||
#include "device/gpu/gpukernel.hpp"
|
||||
#include "utils/options.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
// 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;
|
||||
|
||||
if (gpuNullDevice().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();
|
||||
|
||||
if (gpuNullDevice().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();
|
||||
|
||||
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 (auto& it : headerIncludeName) {
|
||||
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();
|
||||
}
|
||||
|
||||
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 = amd::Hsail::BinaryInit(sizeof(aclBinary), &targInfo, &binOpts, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclBinaryInit failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ACL_SUCCESS !=
|
||||
amd::Hsail::InsertSection(gpuNullDevice().amdilCompiler(), bin, sourceCode.c_str(), sourceCode.size(), aclSOURCE)) {
|
||||
LogWarning("aclInsertSection failed");
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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 (gpuNullDevice().settings().oclVersion_) {
|
||||
case OpenCL10:
|
||||
opts << " -cl-std=CL1.0";
|
||||
break;
|
||||
case OpenCL11:
|
||||
opts << " -cl-std=CL1.1";
|
||||
break;
|
||||
case OpenCL20:
|
||||
case OpenCL21:
|
||||
default:
|
||||
case OpenCL12:
|
||||
opts << " -cl-std=CL1.2";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 (!gpuNullDevice().settings().imageSupport_) {
|
||||
opts << " -fno-image-support";
|
||||
}
|
||||
|
||||
if (gpuNullDevice().settings().reportFMAF_) {
|
||||
opts << " -mfast-fmaf";
|
||||
}
|
||||
|
||||
if (gpuNullDevice().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 = amd::Hsail::Compile(gpuNullDevice().amdilCompiler(), bin, newOpt.c_str(), ACL_TYPE_OPENCL, ACL_TYPE_LLVMIR_BINARY,
|
||||
NULL);
|
||||
|
||||
buildLog_ += amd::Hsail::GetCompilerLog(gpuNullDevice().amdilCompiler());
|
||||
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
const void* ir = amd::Hsail::ExtractSection(gpuNullDevice().amdilCompiler(), bin, &len, aclLLVMIR, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclExtractSection failed");
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
return false;
|
||||
}
|
||||
|
||||
llvmBinary_.assign(reinterpret_cast<const char*>(ir), len);
|
||||
elfSectionType_ = amd::Elf::LLVMIR;
|
||||
amd::Hsail::BinaryFini(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);
|
||||
#endif
|
||||
|
||||
if (clBinary()->saveSOURCE()) {
|
||||
clBinary()->elfOut()->addSection(amd::Elf::SOURCE, sourceCode.data(), sourceCode.size());
|
||||
}
|
||||
if (clBinary()->saveLLVMIR()) {
|
||||
clBinary()->elfOut()->addSection(amd::Elf::LLVMIR, llvmBinary_.data(), llvmBinary_.size());
|
||||
// store the original compile options
|
||||
clBinary()->storeCompileOptions(compileOptions_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
aclBinary* bin = amd::Hsail::BinaryInit(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::Elf::SPIRV) {
|
||||
spirFlag = aclSPIRV;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIRV_BINARY;
|
||||
} else if (std::string::npos != options->clcOptions.find("--spir") ||
|
||||
elfSectionType_ == amd::Elf::SPIR) {
|
||||
spirFlag = aclSPIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_SPIR_BINARY;
|
||||
} else {
|
||||
spirFlag = aclLLVMIR;
|
||||
aclTypeBinaryUsed = ACL_TYPE_LLVMIR_BINARY;
|
||||
}
|
||||
|
||||
if (ACL_SUCCESS !=
|
||||
amd::Hsail::InsertSection(gpuNullDevice().amdilCompiler(), bin, llvmBinary_.data(), llvmBinary_.size(), spirFlag)) {
|
||||
LogWarning("aclInsertSection failed");
|
||||
amd::Hsail::BinaryFini(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", gpuNullDevice().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 = amd::Hsail::Compile(gpuNullDevice().amdilCompiler(), bin, optionStr.c_str(), aclTypeBinaryUsed, type, NULL);
|
||||
buildLog_ += amd::Hsail::GetCompilerLog(gpuNullDevice().amdilCompiler());
|
||||
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclCompile failed");
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
if (options->oVariables->BinBIF30) {
|
||||
acl_error err;
|
||||
char* binaryIn = nullptr;
|
||||
size_t size;
|
||||
err = amd::Hsail::WriteToMem(bin, reinterpret_cast<void**>(&binaryIn), &size);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclWriteToMem failed");
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
clBinary()->saveBIFBinary(binaryIn, size);
|
||||
amd::Hsail::FreeMem(bin, binaryIn);
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
const void* amdil = amd::Hsail::ExtractSection(gpuNullDevice().amdilCompiler(), bin, &len, aclCODEGEN, &err);
|
||||
if (err != ACL_SUCCESS) {
|
||||
LogWarning("aclExtractSection failed");
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
return CL_BUILD_PROGRAM_FAILURE;
|
||||
}
|
||||
|
||||
ilProgram_.assign(reinterpret_cast<const char*>(amdil), len);
|
||||
amd::Hsail::BinaryFini(bin);
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,98 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "device/gpu/gpuconstbuf.hpp"
|
||||
#include "device/gpu/gpuvirtual.hpp"
|
||||
#include "device/gpu/gpudevice.hpp"
|
||||
#include "device/gpu/gpusettings.hpp"
|
||||
|
||||
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() {
|
||||
if (wrtAddress_ != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1,83 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUCONSTBUF_HPP_
|
||||
#define GPUCONSTBUF_HPP_
|
||||
|
||||
#include "device/gpu/gpumemory.hpp"
|
||||
|
||||
//! \namespace gpu GPU Resource Implementation
|
||||
namespace gpu {
|
||||
|
||||
//! Cconstant buffer
|
||||
class ConstBuffer : public Memory {
|
||||
public:
|
||||
//! Vector size of the constant buffer
|
||||
static constexpr 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
|
||||
);
|
||||
|
||||
//! Destructor for the ConstBuffer class
|
||||
~ConstBuffer();
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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 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_; }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ConstBuffer(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
|
||||
};
|
||||
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUCONSTBUF_HPP_*/
|
||||
@@ -1,97 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpucounters.hpp"
|
||||
#include "device/gpu/gpuvirtual.hpp"
|
||||
#include "query/PerformanceQueryObject.h"
|
||||
|
||||
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());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
PerfCounter::~PerfCounter() {
|
||||
if (calRef_ == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Release the counter reference object
|
||||
calRef_->release();
|
||||
}
|
||||
|
||||
bool PerfCounter::create(CalCounterReference* calRef) {
|
||||
assert(&gpu() == &calRef->gpu());
|
||||
|
||||
calRef_ = calRef;
|
||||
counter_ = calRef->gslCounter();
|
||||
index_ = calRef->retain() - 2;
|
||||
calRef->growResultArray(index_);
|
||||
|
||||
// Initialize the counter
|
||||
gslCounter()->getAsPerformanceQueryObject()->setCounterState(
|
||||
info()->blockIndex_, info()->counterIndex_, info()->eventIndex_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t PerfCounter::getInfo(uint64_t infoType) const {
|
||||
switch (infoType) {
|
||||
case CL_PERFCOUNTER_GPU_BLOCK_INDEX: {
|
||||
// Return the GPU block index
|
||||
return info()->blockIndex_;
|
||||
}
|
||||
case CL_PERFCOUNTER_GPU_COUNTER_INDEX: {
|
||||
// Return the GPU counter index
|
||||
return info()->counterIndex_;
|
||||
}
|
||||
case CL_PERFCOUNTER_GPU_EVENT_INDEX: {
|
||||
// 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_];
|
||||
}
|
||||
default:
|
||||
LogError("Wrong PerfCounter::getInfo parameter");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,140 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUCOUNTERS_HPP_
|
||||
#define GPUCOUNTERS_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "device/device.hpp"
|
||||
#include "device/gpu/gpudevice.hpp"
|
||||
|
||||
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) {}
|
||||
|
||||
//! Get CAL counter
|
||||
gslQueryObject gslCounter() const { return counter_; }
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! Returns the CAL counter results
|
||||
uint64_t* results() const { return results_; }
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalCounterReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalCounterReference(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
|
||||
};
|
||||
|
||||
//! 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
|
||||
};
|
||||
|
||||
//! 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
|
||||
uint32_t blockIndex, //!< HW block index
|
||||
uint32_t counterIndex, //!< Counter index within the block
|
||||
uint32_t 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();
|
||||
|
||||
//! 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 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 CAL performance counter descriptor
|
||||
const Info* info() const { return &info_; }
|
||||
|
||||
//! Returns the Info structure for performance counter
|
||||
gslQueryObject gslCounter() const { return counter_; }
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
PerfCounter(const PerfCounter&);
|
||||
|
||||
//! Disable default operator=
|
||||
PerfCounter& operator=(const PerfCounter&);
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUCOUNTERS_HPP_
|
||||
@@ -1,133 +0,0 @@
|
||||
/* Copyright (c) 2014 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef HWDBG_GPUDEBGGER_H_
|
||||
#define HWDBG_GPUDEBGGER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "hsa.h"
|
||||
#include "amd_hsa_kernel_code.h"
|
||||
#include "device/device.hpp"
|
||||
#include "device/hwdebug.hpp"
|
||||
#include "hsailctx.hpp"
|
||||
|
||||
static constexpr int NumberReserveVgprs = 4;
|
||||
|
||||
namespace gpu {
|
||||
|
||||
/**
|
||||
* \defgroup Services_API OCL Runtime Services API
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*! \brief Dispatch packet information
|
||||
*
|
||||
* 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
|
||||
};
|
||||
|
||||
/*! \brief Cache mask for invalidation
|
||||
*/
|
||||
struct HwDbgGpuCacheMask {
|
||||
HwDbgGpuCacheMask() : ui32All_(0) {}
|
||||
|
||||
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_;
|
||||
};
|
||||
};
|
||||
|
||||
/*! \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)
|
||||
};
|
||||
|
||||
/*! \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
|
||||
};
|
||||
|
||||
/*! \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
|
||||
};
|
||||
|
||||
/*! \brief Kernel code information
|
||||
*
|
||||
* 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
|
||||
};
|
||||
|
||||
/**@}*/
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // HWDBG_GPUDEBGGER_H_
|
||||
@@ -1,354 +0,0 @@
|
||||
/* Copyright (c) 2014 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "gpudebugmanager.hpp"
|
||||
#include "gpudevice.hpp"
|
||||
#include "platform/commandqueue.hpp"
|
||||
|
||||
#include "device/device.hpp"
|
||||
#include "device/gpu/gpumemory.hpp"
|
||||
#include "device/gpu/gputrap.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class VirtualGPU;
|
||||
class Device;
|
||||
class Memory;
|
||||
|
||||
/*
|
||||
***************************************************************************
|
||||
* Implementation of GPU Debug Manager class
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
execMode_.ui32All = 0;
|
||||
|
||||
rtTrapHandlerInfo_.trap_.trapHandler_ = NULL;
|
||||
rtTrapHandlerInfo_.trap_.trapBuffer_ = NULL;
|
||||
|
||||
aqlPacket_ = (hsa_kernel_dispatch_packet_t*)NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GpuDebugManager::~GpuDebugManager() {
|
||||
if (NULL != addressWatch_) {
|
||||
delete[] addressWatch_;
|
||||
}
|
||||
}
|
||||
|
||||
void GpuDebugManager::executePreDispatchCallBack(void* aqlPacket, void* toolInfo) {
|
||||
DebugToolInfo* info = reinterpret_cast<DebugToolInfo*>(toolInfo);
|
||||
|
||||
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_);
|
||||
|
||||
// Build the global memory descriptor
|
||||
device()->gslCtx()->BuildHeapBufferResource(debugInfo_.globalMemoryDescriptor_,
|
||||
info->globalAddress_);
|
||||
|
||||
// // for invalidate cache (BuildEndOfKernelNotifyCommands)
|
||||
// aqlPacket->release_fence_scope = 2;
|
||||
|
||||
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_);
|
||||
}
|
||||
|
||||
// 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_);
|
||||
}
|
||||
}
|
||||
|
||||
//! Map the kernel code for host access
|
||||
void GpuDebugManager::mapKernelCode(void* aqlCodeInfo) const {
|
||||
AqlCodeInfo* codeInfo = reinterpret_cast<AqlCodeInfo*>(aqlCodeInfo);
|
||||
|
||||
codeInfo->aqlCode_ = reinterpret_cast<amd_kernel_code_t*>(aqlCodeAddr_);
|
||||
codeInfo->aqlCodeSize_ = aqlCodeSize_;
|
||||
}
|
||||
|
||||
int32_t 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
|
||||
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t GpuDebugManager::waitDebugEvent(DebugEvent pEvent, uint32_t timeOut) const {
|
||||
if (osEventTimedWait(pEvent, timeOut)) {
|
||||
return CL_SUCCESS;
|
||||
} else {
|
||||
return CL_EVENT_TIMEOUT_AMD;
|
||||
}
|
||||
}
|
||||
|
||||
void GpuDebugManager::destroyDebugEvent(DebugEvent* pEvent) {
|
||||
osEventDestroy(*pEvent);
|
||||
*pEvent = 0;
|
||||
|
||||
device()->gslCtx()->exceptionNotification(0);
|
||||
}
|
||||
|
||||
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* pEvent) {
|
||||
size_t requiredSize = numWatchPoints * sizeof(HwDbgAddressWatch);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
int32_t 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;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,130 +0,0 @@
|
||||
/* Copyright (c) 2014 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef HWDBG_DEBUGMANAGER_H__
|
||||
#define HWDBG_DEBUGMANAGER_H__
|
||||
|
||||
#include "gpuvirtual.hpp"
|
||||
#include "gpudebugger.hpp"
|
||||
|
||||
namespace gpu {
|
||||
|
||||
class GpuDebugManager;
|
||||
class Device;
|
||||
class Memory;
|
||||
|
||||
|
||||
/*! \brief Debug Manager Class
|
||||
*
|
||||
* The debug manager class is used to pass all the trap info to the
|
||||
* kernel dispatch and then the kernel execution can use such trap information
|
||||
* for kernel execution. This class contains the trap handler and shader event
|
||||
* objects. The trap handler is setup by users and passed to the kernel dispatch.
|
||||
* The shader event is to receive interrupts from the GPU and then users can
|
||||
* perform various operations.
|
||||
*
|
||||
* This class also provides the interface for setting up the pre-dispatch
|
||||
* callback functions used by the profiler and debugger. It also provides
|
||||
* a way to retrieve various debug information for the kernel execution.
|
||||
*
|
||||
*/
|
||||
class GpuDebugManager : public amd::HwDebugManager {
|
||||
public:
|
||||
//! Constructor of the debug manager class
|
||||
GpuDebugManager(amd::Device* device);
|
||||
|
||||
//! Destructor of the debug manager class
|
||||
~GpuDebugManager();
|
||||
|
||||
//! Get the single instance of the GpuDebugManager class
|
||||
static GpuDebugManager* getDefaultInstance();
|
||||
|
||||
//! Destroy the GpuDebugManager class object
|
||||
static void destroyInstances();
|
||||
|
||||
//! Flush cache
|
||||
void flushCache(uint32_t mask);
|
||||
|
||||
//! Create the debug event
|
||||
DebugEvent createDebugEvent(const bool autoReset);
|
||||
|
||||
//! Wait for the debug event
|
||||
int32_t waitDebugEvent(DebugEvent pEvent, uint32_t timeOut) const;
|
||||
|
||||
//! Destroy the debug event
|
||||
void destroyDebugEvent(DebugEvent* pEvent);
|
||||
|
||||
//! Register the debugger
|
||||
int32_t registerDebugger(amd::Context* context, uintptr_t messageStorage);
|
||||
|
||||
//! Unregister the debugger
|
||||
void unregisterDebugger();
|
||||
|
||||
//! 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);
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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 pre-dispatch callback function
|
||||
void executePreDispatchCallBack(void* aqlPacket, void* toolInfo);
|
||||
|
||||
private:
|
||||
//! Setup trap handler info for kernel execution
|
||||
void setupTrapInformation(DebugToolInfo* toolInfo);
|
||||
|
||||
//! Create runtime trap handler
|
||||
int32_t createRuntimeTrapHandler();
|
||||
|
||||
protected:
|
||||
const VirtualGPU* vGpu() const { return vGpu_; }
|
||||
|
||||
private:
|
||||
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
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // HWDBG_DEBUGMANAGER_H__
|
||||
@@ -1,354 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUDEFS_HPP_
|
||||
#define GPUDEFS_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
|
||||
#include "gsl_types.h"
|
||||
#include "gsl_config.h"
|
||||
#include "gsl_ctx.h"
|
||||
#include "backend.h"
|
||||
#include "GSLDevice.h"
|
||||
#include "GSLContext.h"
|
||||
|
||||
extern bool getFuncInfoFromImage(CALimage image, CALfuncInfo* pFuncInfo);
|
||||
|
||||
/*! \addtogroup GPU
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! GPU Device Implementation
|
||||
|
||||
namespace gpu {
|
||||
|
||||
//! Maximum number of the supported global atomic counters
|
||||
static constexpr uint MaxAtomicCounters = 8;
|
||||
//! Maximum number of the supported samplers
|
||||
static constexpr uint MaxSamplers = 16;
|
||||
//! Maximum number of supported read images
|
||||
static constexpr uint MaxReadImage = 128;
|
||||
//! Maximum number of supported write images
|
||||
static constexpr uint MaxWriteImage = 8;
|
||||
//! Maximum number of supported read/write images for OCL20
|
||||
static constexpr uint MaxReadWriteImage = 64;
|
||||
//! Maximum number of supported constant arguments
|
||||
static constexpr uint MaxConstArguments = 8;
|
||||
//! Maximum number of supported kernel UAV arguments
|
||||
static constexpr uint MaxUavArguments = 1024;
|
||||
//! Maximum number of pixels for a 1D image created from a buffer
|
||||
static constexpr size_t MaxImageBufferSize = 1 << 27;
|
||||
//! Maximum number of pixels for a 1D image created from a buffer
|
||||
static constexpr size_t MaxImageArraySize = 2048;
|
||||
|
||||
//! Maximum number of supported constant buffers
|
||||
static constexpr uint MaxConstBuffers = MaxConstArguments + 8;
|
||||
|
||||
//! Maximum number of constant buffers for arguments
|
||||
static constexpr uint MaxConstBuffersArguments = 2;
|
||||
|
||||
//! Define offline CAL implementation
|
||||
static constexpr uint CalOfflineImpl = 0xffffffff;
|
||||
|
||||
//! Alignment restriciton for the pinned memory
|
||||
static constexpr size_t PinnedMemoryAlignment = 4 * Ki;
|
||||
|
||||
//! HSA path specific defines for images
|
||||
static constexpr uint HsaImageObjectSize = 48;
|
||||
static constexpr uint HsaImageObjectAlignment = 16;
|
||||
static constexpr uint HsaSamplerObjectSize = 32;
|
||||
static constexpr uint HsaSamplerObjectAlignment = 16;
|
||||
|
||||
//! HSA path specific defines for images
|
||||
static constexpr uint DeviceQueueMaskSize = 32;
|
||||
|
||||
// Supported OpenCL versions
|
||||
enum OclVersion { OpenCL10, OpenCL11, OpenCL12, OpenCL20, OpenCL21 };
|
||||
|
||||
struct CalFormat {
|
||||
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
|
||||
};
|
||||
|
||||
static constexpr 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_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_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_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_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_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_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_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_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}},
|
||||
// RGBA
|
||||
{{CL_RGBA, CL_UNORM_INT_101010}, {GSL_CHANNEL_ORDER_RGBA, CM_SURF_FMT_RGB10_X2}},
|
||||
|
||||
// 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_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_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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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}},
|
||||
|
||||
// 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_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}}
|
||||
|
||||
};
|
||||
|
||||
struct MemFormatStruct {
|
||||
cmSurfFmt format_;
|
||||
uint size_;
|
||||
uint components_;
|
||||
};
|
||||
|
||||
static constexpr 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_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_RGB10_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];
|
||||
}
|
||||
}
|
||||
assert(!"Unknown GSL memory format!");
|
||||
return MemoryFormatSize[0];
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUDEFS_HPP_
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,623 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPU_HPP_
|
||||
#define GPU_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "device/device.hpp"
|
||||
#include "platform/command.hpp"
|
||||
#include "platform/program.hpp"
|
||||
#include "platform/perfctr.hpp"
|
||||
#include "platform/threadtrace.hpp"
|
||||
#include "platform/memory.hpp"
|
||||
#include "utils/concurrent.hpp"
|
||||
#include "thread/thread.hpp"
|
||||
#include "thread/monitor.hpp"
|
||||
#include "device/gpu/gpuvirtual.hpp"
|
||||
#include "device/gpu/gpumemory.hpp"
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpusettings.hpp"
|
||||
#include "device/gpu/gpuappprofile.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "hsailctx.hpp"
|
||||
#include "vaminterface.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_feature(address_sanitizer)
|
||||
#include "device/devurilocator.hpp"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*! \addtogroup GPU
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
//! A nil device object
|
||||
class NullDevice : public amd::Device {
|
||||
protected:
|
||||
static aclCompiler* compiler_;
|
||||
static aclCompiler* hsaCompiler_;
|
||||
|
||||
public:
|
||||
aclCompiler* amdilCompiler() const { return compiler_; }
|
||||
aclCompiler* hsaCompiler() const { return hsaCompiler_; }
|
||||
aclCompiler* compiler() const { return hsaCompiler_; }
|
||||
Compiler* binCompiler() const { return amdilCompiler(); }
|
||||
|
||||
static bool init(void);
|
||||
|
||||
//! Construct a new identifier
|
||||
NullDevice();
|
||||
|
||||
//! Creates an offline device with the specified target
|
||||
bool create(const char* calName, //!< GPU device name
|
||||
const amd::Isa& isa, //!< GPU device isa
|
||||
CALtarget target, //!< GPU device identifier
|
||||
bool preferPal, //!< GPU prefer to use PAL if GPU_ENABLE_PAL=2
|
||||
bool doublePrecision, //!< Use double precision
|
||||
bool openCL200 //!< Use OpenCL 2.0
|
||||
);
|
||||
|
||||
//! Instantiate a new virtual device
|
||||
virtual device::VirtualDevice* createVirtualDevice(amd::CommandQueue* queue = NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//! Create the device program.
|
||||
virtual device::Program* createProgram(amd::Program& owner, amd::option::Options* options = NULL);
|
||||
|
||||
//! Just returns NULL for the dummy device
|
||||
virtual device::Memory* createMemory(amd::Memory& owner) const { return NULL; }
|
||||
|
||||
//! Sampler object allocation
|
||||
virtual bool createSampler(const amd::Sampler& owner, //!< abstraction layer sampler object
|
||||
device::Sampler** sampler //!< device sampler object
|
||||
) const {
|
||||
ShouldNotReachHere();
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Just returns NULL for the dummy device
|
||||
virtual device::Memory* createView(
|
||||
amd::Memory& owner, //!< Owner memory object
|
||||
const device::Memory& parent //!< Parent device memory object for the view
|
||||
) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//! Signal object allocation
|
||||
virtual device::Signal* createSignal() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//! Acquire external graphics API object in the host thread
|
||||
//! Needed for OpenGL objects on CPU device
|
||||
|
||||
virtual bool bindExternalDevice(uint flags, void* const pDevice[], void* pContext,
|
||||
bool validateOnly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool unbindExternalDevice(uint flags, void* const pDevice[], void* pContext,
|
||||
bool validateOnly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Releases non-blocking map target memory
|
||||
virtual void freeMapTarget(amd::Memory& mem, void* target) {}
|
||||
|
||||
CALtarget calTarget() const { return calTarget_; }
|
||||
|
||||
CALMachineType calMachine() const { return calMachine_; }
|
||||
|
||||
//! Empty implementation on Null device
|
||||
virtual bool globalFreeMemory(size_t* freeMemory) const { return false; }
|
||||
|
||||
//! Get GPU device settings
|
||||
const gpu::Settings& settings() const { return reinterpret_cast<gpu::Settings&>(*settings_); }
|
||||
virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment,
|
||||
cl_svm_mem_flags flags, void* svmPtr) const {
|
||||
return NULL;
|
||||
}
|
||||
virtual void svmFree(void* ptr) const { return; }
|
||||
|
||||
virtual bool SetClockMode(const cl_set_device_clock_mode_input_amd setClockModeInput, cl_set_device_clock_mode_output_amd* pSetClockModeOutput) { return true; }
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_feature(address_sanitizer)
|
||||
virtual device::UriLocator* createUriLocator() const {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
protected:
|
||||
//! Answer the question: "Should HSAIL Program be created?",
|
||||
//! based on the given options.
|
||||
bool isHsailProgram(amd::option::Options* options = NULL);
|
||||
|
||||
//! Fills OpenCL device info structure
|
||||
void fillDeviceInfo(const CALdeviceattribs& calAttr, //!< CAL device attributes info
|
||||
const gslMemInfo& memInfo, //!< GSL mem info
|
||||
size_t maxTextureSize, //!< Maximum texture size supported in HW
|
||||
uint numComputeRings, //!< Number of compute rings
|
||||
uint numComputeRingsRT //!< Number of RT compute rings
|
||||
);
|
||||
|
||||
CALtarget calTarget_; //!< GPU device identifier
|
||||
CALMachineType calMachine_; //!< GPU machine identifier
|
||||
const char* calName_; //!< GPU device name
|
||||
};
|
||||
|
||||
//! Forward declarations
|
||||
class Command;
|
||||
class Device;
|
||||
class GpuCommand;
|
||||
class Heap;
|
||||
class HeapBlock;
|
||||
class Program;
|
||||
class Kernel;
|
||||
class Memory;
|
||||
class Resource;
|
||||
class VirtualDevice;
|
||||
class PrintfDbg;
|
||||
class ThreadTrace;
|
||||
|
||||
#ifndef CL_FILTER_NONE
|
||||
#define CL_FILTER_NONE 0x1142
|
||||
#endif
|
||||
|
||||
class Sampler : public device::Sampler {
|
||||
public:
|
||||
//! Constructor
|
||||
Sampler(const Device& dev) : dev_(dev) {}
|
||||
|
||||
//! Default destructor for the device memory object
|
||||
virtual ~Sampler();
|
||||
|
||||
//! Creates a device sampler from the OCL sampler state
|
||||
bool create(uint32_t oclSamplerState //!< OCL sampler state
|
||||
);
|
||||
|
||||
//! Creates a device sampler from the OCL sampler state
|
||||
bool create(const amd::Sampler& owner //!< AMD sampler object
|
||||
);
|
||||
|
||||
const void* hwState() const { return hwState_; }
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
Sampler& operator=(const Sampler&);
|
||||
|
||||
//! Disable operator=
|
||||
Sampler(const Sampler&);
|
||||
|
||||
const Device& dev_; //!< Device object associated with the sampler
|
||||
address hwState_; //!< GPU HW state (\todo legacy path)
|
||||
};
|
||||
|
||||
//! A GPU device ordinal (physical GPU device)
|
||||
class Device : public NullDevice, public CALGSLDevice {
|
||||
public:
|
||||
class Heap : public amd::EmbeddedObject {
|
||||
public:
|
||||
//! The size of a heap element in bytes
|
||||
static constexpr size_t ElementSize = 4;
|
||||
|
||||
//! The type of a heap element in bytes
|
||||
static constexpr cmSurfFmt ElementType = CM_SURF_FMT_R32I;
|
||||
|
||||
Heap() : resource_(NULL), baseAddress_(0) {}
|
||||
|
||||
bool create(Device& device //!< GPU device object
|
||||
);
|
||||
|
||||
//! Gets the GPU resource associated with the global heap
|
||||
const Memory& resource() const { return *resource_; }
|
||||
|
||||
//! Returns the base virtual address of the heap
|
||||
uint64_t baseAddress() const { return baseAddress_; }
|
||||
|
||||
protected:
|
||||
Memory* resource_; //!< GPU resource referencing the heap memory
|
||||
uint64_t baseAddress_; //!< Virtual heap base address
|
||||
};
|
||||
|
||||
//! Locks any access to the virtual GPUs
|
||||
class ScopedLockVgpus : public amd::StackObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
ScopedLockVgpus(const Device& dev);
|
||||
|
||||
//! Destructor
|
||||
~ScopedLockVgpus();
|
||||
|
||||
private:
|
||||
const Device& dev_; //! Device object
|
||||
};
|
||||
|
||||
//! Interop emulation flags
|
||||
enum InteropEmulationFlags {
|
||||
D3D10Device = 0x00000001,
|
||||
GLContext = 0x00000002,
|
||||
};
|
||||
|
||||
class Engines : public amd::EmbeddedObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
Engines() : numComputeRings_(0), numComputeRingsRT_(0), numDmaEngines_(0) {
|
||||
memset(desc_, 0xff, sizeof(desc_));
|
||||
}
|
||||
|
||||
//! Creates engine descriptor for this class
|
||||
void create(uint num, gslEngineDescriptor* desc, uint maxNumComputeRings);
|
||||
|
||||
//! Gets engine type mask
|
||||
uint getMask(gslEngineID id) const { return (1 << id); }
|
||||
|
||||
//! Gets a descriptor for the requested engines
|
||||
uint getRequested(uint engines, gslEngineDescriptor* desc) const;
|
||||
|
||||
//! Returns the number of available compute rings
|
||||
uint numComputeRings() const { return numComputeRings_; }
|
||||
|
||||
//! Returns the number of available real time compute rings
|
||||
uint numComputeRingsRT() const { return numComputeRingsRT_; }
|
||||
|
||||
//! Returns the number of available DMA engines
|
||||
uint numDMAEngines() const { return numDmaEngines_; }
|
||||
|
||||
private:
|
||||
uint numComputeRings_;
|
||||
uint numComputeRingsRT_;
|
||||
uint numDmaEngines_;
|
||||
gslEngineDescriptor desc_[GSL_ENGINEID_MAX]; //!< Engine descriptor
|
||||
};
|
||||
|
||||
//! Transfer buffers
|
||||
class XferBuffers : public amd::HeapObject {
|
||||
public:
|
||||
static constexpr size_t MaxXferBufListSize = 8;
|
||||
|
||||
//! Default constructor
|
||||
XferBuffers(const Device& device, Resource::MemoryType type, size_t bufSize)
|
||||
: type_(type), bufSize_(bufSize), acquiredCnt_(0), gpuDevice_(device) {}
|
||||
|
||||
//! Default destructor
|
||||
~XferBuffers();
|
||||
|
||||
//! Creates the xfer buffers object
|
||||
bool create();
|
||||
|
||||
//! Acquires an instance of the transfer buffers
|
||||
Memory& acquire();
|
||||
|
||||
//! Releases transfer buffer
|
||||
void release(VirtualGPU& gpu, //!< Virual GPU object used with the buffer
|
||||
Memory& buffer //!< Transfer buffer for release
|
||||
);
|
||||
|
||||
//! Returns the buffer's size for transfer
|
||||
size_t bufSize() const { return bufSize_; }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
XferBuffers(const XferBuffers&);
|
||||
|
||||
//! Disable assignment operator
|
||||
XferBuffers& operator=(const XferBuffers&);
|
||||
|
||||
//! Get device object
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
Resource::MemoryType type_; //!< The buffer's type
|
||||
size_t bufSize_; //!< Staged buffer size
|
||||
std::list<Memory*> freeBuffers_; //!< The list of free buffers
|
||||
std::atomic<uint> acquiredCnt_; //!< The total number of acquired buffers
|
||||
amd::Monitor lock_; //!< Staged buffer acquire/release lock
|
||||
const Device& gpuDevice_; //!< GPU device object
|
||||
};
|
||||
|
||||
struct ScratchBuffer : public amd::HeapObject {
|
||||
uint regNum_; //!< The number of used scratch registers
|
||||
Memory* memObj_; //!< Memory objects for scratch buffers
|
||||
uint64_t offset_; //!< Offset from the global scratch store
|
||||
uint64_t size_; //!< Scratch buffer size on this queue
|
||||
|
||||
//! Default constructor
|
||||
ScratchBuffer() : regNum_(0), memObj_(NULL), offset_(0), size_(0) {}
|
||||
|
||||
//! Default constructor
|
||||
~ScratchBuffer();
|
||||
|
||||
//! Destroys memory objects
|
||||
void destroyMemory();
|
||||
};
|
||||
|
||||
|
||||
class SrdManager : public amd::HeapObject {
|
||||
public:
|
||||
SrdManager(const Device& dev, uint srdSize, uint bufSize)
|
||||
: dev_(dev),
|
||||
numFlags_(bufSize / (srdSize * MaskBits)),
|
||||
srdSize_(srdSize),
|
||||
bufSize_(bufSize) {}
|
||||
~SrdManager();
|
||||
|
||||
//! Allocates a new SRD slot for a resource
|
||||
uint64_t allocSrdSlot(address* cpuAddr);
|
||||
|
||||
//! Frees a SRD slot
|
||||
void freeSrdSlot(uint64_t addr);
|
||||
|
||||
// Fills the memory list for VidMM KMD
|
||||
void fillResourceList(std::vector<const Memory*>& memList);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
SrdManager(const SrdManager&);
|
||||
|
||||
//! Disable assignment operator
|
||||
SrdManager& operator=(const SrdManager&);
|
||||
|
||||
struct Chunk {
|
||||
Memory* buf_;
|
||||
uint* flags_;
|
||||
Chunk() : buf_(NULL), flags_(NULL) {}
|
||||
};
|
||||
|
||||
static constexpr uint MaskBits = 32;
|
||||
const Device& dev_; //!< GPU device for the chunk manager
|
||||
amd::Monitor ml_; //!< Global lock for the SRD manager
|
||||
std::vector<Chunk> pool_; //!< Pool of SRD buffers
|
||||
uint numFlags_; //!< Total number of flags in array
|
||||
uint srdSize_; //!< SRD size
|
||||
uint bufSize_; //!< Buffer size that holds SRDs
|
||||
};
|
||||
|
||||
//! Initialise the whole GPU device subsystem (CAL init, device enumeration, etc).
|
||||
static bool init();
|
||||
|
||||
//! Shutdown the whole GPU device subsystem (CAL shutdown).
|
||||
static void tearDown();
|
||||
|
||||
//! Construct a new physical GPU device
|
||||
Device();
|
||||
|
||||
//! Initialise a device (i.e. all parts of the constructor that could
|
||||
//! potentially fail)
|
||||
bool create(CALuint ordinal, //!< GPU device ordinal index. Starts from 0
|
||||
CALuint numOfDevices //!< number of GPU devices in the system
|
||||
);
|
||||
|
||||
//! Destructor for the physical GPU device
|
||||
virtual ~Device();
|
||||
|
||||
//! Instantiate a new virtual device
|
||||
device::VirtualDevice* createVirtualDevice(amd::CommandQueue* queue = NULL);
|
||||
|
||||
//! Memory allocation
|
||||
virtual device::Memory* createMemory(amd::Memory& owner //!< abstraction layer memory object
|
||||
) const;
|
||||
|
||||
//! Sampler object allocation
|
||||
virtual bool createSampler(const amd::Sampler& owner, //!< abstraction layer sampler object
|
||||
device::Sampler** sampler //!< device sampler object
|
||||
) const;
|
||||
|
||||
//! Allocates a view object from the device memory
|
||||
virtual device::Memory* createView(
|
||||
amd::Memory& owner, //!< Owner memory object
|
||||
const device::Memory& parent //!< Parent device memory object for the view
|
||||
) const;
|
||||
|
||||
//! Signal object allocation
|
||||
virtual device::Signal* createSignal() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//! Create the device program.
|
||||
virtual device::Program* createProgram(amd::Program& owner, amd::option::Options* options = NULL);
|
||||
|
||||
//! Attempt to bind with external graphics API's device/context
|
||||
virtual bool bindExternalDevice(uint flags, void* const pDevice[], void* pContext,
|
||||
bool validateOnly);
|
||||
|
||||
//! Attempt to unbind with external graphics API's device/context
|
||||
virtual bool unbindExternalDevice(uint flags, void* const pDevice[], void* pContext,
|
||||
bool validateOnly);
|
||||
|
||||
//! Validates kernel before execution
|
||||
virtual bool validateKernel(const amd::Kernel& kernel, //!< AMD kernel object
|
||||
const device::VirtualDevice* vdev,
|
||||
bool coop_groups = false);
|
||||
|
||||
virtual bool SetClockMode(const cl_set_device_clock_mode_input_amd setClockModeInput, cl_set_device_clock_mode_output_amd* pSetClockModeOutput);
|
||||
|
||||
//! Retrieves information about free memory on a GPU device
|
||||
virtual bool globalFreeMemory(size_t* freeMemory) const;
|
||||
|
||||
//! Returns a GPU memory object from AMD memory object
|
||||
gpu::Memory* getGpuMemory(amd::Memory* mem //!< Pointer to AMD memory object
|
||||
) const;
|
||||
|
||||
//! Gets the GPU resource associated with the global heap
|
||||
const Memory& globalMem() const { return heap_.resource(); }
|
||||
|
||||
//! Gets the global heap object
|
||||
const Heap& heap() const { return heap_; }
|
||||
|
||||
//! Gets the memory object for the dummy page
|
||||
amd::Memory* dummyPage() const { return dummyPage_; }
|
||||
|
||||
amd::Monitor& lockAsyncOps() const { return *lockAsyncOps_; }
|
||||
|
||||
//! Returns the lock object for the virtual gpus list
|
||||
amd::Monitor* vgpusAccess() const { return vgpusAccess_; }
|
||||
|
||||
//! Returns the number of virtual GPUs allocated on this device
|
||||
uint numOfVgpus() const { return numOfVgpus_; }
|
||||
uint numOfVgpus_; //!< The number of virtual GPUs (lock protected)
|
||||
|
||||
typedef std::vector<VirtualGPU*> VirtualGPUs;
|
||||
|
||||
//! Returns the list of all virtual GPUs running on this device
|
||||
const VirtualGPUs& vgpus() const { return vgpus_; }
|
||||
VirtualGPUs vgpus_; //!< The list of all running virtual gpus (lock protected)
|
||||
|
||||
//! Scratch buffer allocation
|
||||
gpu::Memory* createScratchBuffer(size_t size //!< Size of buffer
|
||||
) const;
|
||||
|
||||
//! Returns transfer buffer object
|
||||
XferBuffers& xferWrite() const { return *xferWrite_; }
|
||||
|
||||
//! Returns transfer buffer object
|
||||
XferBuffers& xferRead() const { return *xferRead_; }
|
||||
|
||||
//! Finds an appropriate map target
|
||||
amd::Memory* findMapTarget(size_t size) const;
|
||||
|
||||
//! Adds a map target to the cache
|
||||
bool addMapTarget(amd::Memory* memory) const;
|
||||
|
||||
//! Returns resource cache object
|
||||
ResourceCache& resourceCache() const { return *resourceCache_; }
|
||||
|
||||
//! Returns engines object
|
||||
const Engines& engines() const { return engines_; }
|
||||
|
||||
//! Returns engines object
|
||||
const device::BlitManager& xferMgr() const;
|
||||
|
||||
VirtualGPU* xferQueue() const { return xferQueue_; }
|
||||
|
||||
//! Retrieves the internal format from the OCL format
|
||||
CalFormat getCalFormat(const amd::Image::Format& format //! OCL image format
|
||||
) const;
|
||||
|
||||
//! Retrieves the OCL format from the internal image format
|
||||
amd::Image::Format getOclFormat(const CalFormat& format //! Internal image format
|
||||
) const;
|
||||
|
||||
const ScratchBuffer* scratch(uint idx) const { return scratch_[idx]; }
|
||||
|
||||
//! Returns the global scratch buffer
|
||||
Memory* globalScratchBuf() const { return globalScratchBuf_; };
|
||||
|
||||
//! Destroys scratch buffer memory
|
||||
void destroyScratchBuffers();
|
||||
|
||||
//! Initialize heap resources if uninitialized
|
||||
bool initializeHeapResources();
|
||||
|
||||
//! Set GSL sampler to the specified state
|
||||
void fillHwSampler(uint32_t state, //!< Sampler's OpenCL state
|
||||
void* hwState, //!< Sampler's HW state
|
||||
uint32_t hwStateSize, //!< Size of sampler's HW state
|
||||
uint32_t mipFilter = CL_FILTER_NONE, //!< Mip filter
|
||||
float minLod = 0.f, //!< Min level of detail
|
||||
float maxLod = CL_MAXFLOAT //!< Max level of detail
|
||||
) const;
|
||||
|
||||
//! host memory alloc
|
||||
virtual void* hostAlloc(size_t size, size_t alignment, MemorySegment mem_seg = kNoAtomics) const;
|
||||
|
||||
//! SVM allocation
|
||||
virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment,
|
||||
cl_svm_mem_flags flags, void* svmPtr) const;
|
||||
|
||||
//! Free host SVM memory
|
||||
void hostFree(void* ptr, size_t size) const;
|
||||
|
||||
//! SVM free
|
||||
virtual void svmFree(void* ptr) const;
|
||||
|
||||
//! Returns SRD manger object
|
||||
SrdManager& srds() const { return *srdManager_; }
|
||||
|
||||
//! Initial the Hardware Debug Manager
|
||||
int32_t hwDebugManagerInit(amd::Context* context, uintptr_t messageStorage);
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_feature(address_sanitizer)
|
||||
virtual device::UriLocator* createUriLocator() const {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Device(const Device&);
|
||||
|
||||
//! Disable assignment
|
||||
Device& operator=(const Device&);
|
||||
|
||||
//! Sends the stall command to all queues
|
||||
bool stallQueues();
|
||||
|
||||
//! Buffer allocation
|
||||
gpu::Memory* createBuffer(amd::Memory& owner, //!< Abstraction layer memory object
|
||||
bool directAccess //!< Use direct host memory access
|
||||
) const;
|
||||
|
||||
//! Image allocation
|
||||
gpu::Memory* createImage(amd::Memory& owner, //!< Abstraction layer memory object
|
||||
bool directAccess //!< Use direct host memory access
|
||||
) const;
|
||||
|
||||
//! Allocates/reallocates the scratch buffer, according to the usage
|
||||
bool allocScratch(uint regNum, //!< Number of the scratch registers
|
||||
const VirtualGPU* vgpu //!< Virtual GPU for the allocation
|
||||
);
|
||||
|
||||
Heap heap_; //!< GPU global heap
|
||||
amd::Memory* dummyPage_; //!< A dummy page for NULL pointer
|
||||
|
||||
amd::Monitor* lockAsyncOps_; //!< Lock to serialise all async ops on this device
|
||||
amd::Monitor* lockAsyncOpsForInitHeap_; //!< Lock to serialise all async ops on initialization
|
||||
//!heap operation
|
||||
amd::Monitor* vgpusAccess_; //!< Lock to serialise virtual gpu list access
|
||||
amd::Monitor* scratchAlloc_; //!< Lock to serialise scratch allocation
|
||||
amd::Monitor* mapCacheOps_; //!< Lock to serialise cache for the map resources
|
||||
|
||||
XferBuffers* xferRead_; //!< Transfer buffers read
|
||||
XferBuffers* xferWrite_; //!< Transfer buffers write
|
||||
|
||||
std::vector<amd::Memory*>* mapCache_; //!< Map cache info structure
|
||||
ResourceCache* resourceCache_; //!< Resource cache
|
||||
Engines engines_; //!< Available engines on device
|
||||
bool heapInitComplete_; //!< Keep track of initialization status of heap resources
|
||||
VirtualGPU* xferQueue_; //!< Transfer queue
|
||||
std::vector<ScratchBuffer*> scratch_; //!< Scratch buffers for kernels
|
||||
Memory* globalScratchBuf_; //!< Global scratch buffer
|
||||
SrdManager* srdManager_; //!< SRD manager object
|
||||
|
||||
static AppProfile appProfile_; //!< application profile
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPU_HPP_*/
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,877 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUKERNEL_HPP_
|
||||
#define GPUKERNEL_HPP_
|
||||
|
||||
#include "device/device.hpp"
|
||||
#include "utils/macros.hpp"
|
||||
#include "platform/command.hpp"
|
||||
#include "platform/program.hpp"
|
||||
#include "platform/kernel.hpp"
|
||||
#include "platform/sampler.hpp"
|
||||
#include "device/gpu/gpudevice.hpp"
|
||||
#include "device/gpu/gpuvirtual.hpp"
|
||||
#include "amd_hsa_kernel_code.h"
|
||||
#include "device/gpu/gpuprintf.hpp"
|
||||
#include "device/devwavelimiter.hpp"
|
||||
#include "hsa.h"
|
||||
|
||||
namespace amd {
|
||||
namespace hsa {
|
||||
namespace loader {
|
||||
class Symbol;
|
||||
} // loader
|
||||
} // hsa
|
||||
} // amd
|
||||
|
||||
//! \namespace gpu GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
class VirtualGPU;
|
||||
class Device;
|
||||
class NullDevice;
|
||||
class HSAILProgram;
|
||||
|
||||
struct HWSHADER_Helper {
|
||||
template <typename S, typename T> static T Get(S base, T offset) {
|
||||
return reinterpret_cast<T>(reinterpret_cast<intptr_t>(base) + reinterpret_cast<size_t>(offset));
|
||||
}
|
||||
};
|
||||
|
||||
#define HWSHADER_Get(shader, field) HWSHADER_Helper::Get((shader), (shader)->field)
|
||||
|
||||
template <typename D, typename S>
|
||||
static void CalcPtr(D& dst, const S src, size_t structSize, size_t size) {
|
||||
dst = reinterpret_cast<D>(reinterpret_cast<const intptr_t>(src) + structSize * size);
|
||||
}
|
||||
|
||||
/*! \addtogroup GPU GPU Device Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! \brief Helper function for the std::string processing.
|
||||
* Finds the name in the std::string
|
||||
*
|
||||
* \return True if we found the entry of the symbols
|
||||
*/
|
||||
bool expect(const std::string& str, //!< The original std::string
|
||||
size_t* pos, //!< Position to start
|
||||
const std::string& sym //!< The sympols to expect
|
||||
);
|
||||
|
||||
/*! \brief Helper function for the std::string processing.
|
||||
* Gets a word from the std::string
|
||||
*
|
||||
* \return True if we successfully received a word
|
||||
*/
|
||||
bool getword(const std::string& str, //!< The original std::string
|
||||
size_t* pos, //!< Position to start
|
||||
std::string& sym //!< Returned word
|
||||
);
|
||||
|
||||
/*! \brief Helper function for the std::string processing.
|
||||
* Loads numbers from the metadata
|
||||
*
|
||||
* \return True if we loaded a number
|
||||
*/
|
||||
bool getuint(const std::string& str, //!< The original std::string
|
||||
size_t* pos, //!< Position to start
|
||||
uint* val //!< Returned number
|
||||
);
|
||||
|
||||
/*! \brief Helper function for the std::string processing.
|
||||
* Loads numbers from the metadata in HEX format
|
||||
*
|
||||
* \return True if we loaded a number
|
||||
*/
|
||||
bool getuintHex(const std::string& str, //!< The original std::string
|
||||
size_t* pos, //!< Position to start
|
||||
uint* val //!< Returned number
|
||||
);
|
||||
|
||||
/*! \brief Helper function for the std::string processing.
|
||||
* Loads numbers from the metadata in HEX format
|
||||
*
|
||||
* \return True if we loaded a number
|
||||
*/
|
||||
bool getuint64Hex(const std::string& str, //!< The original std::string
|
||||
size_t* pos, //!< Position to start
|
||||
uint64_t* val //!< Returned number
|
||||
);
|
||||
|
||||
/*! \brief Helper function for the std::string processing.
|
||||
* Converts unsigned integer to string
|
||||
*
|
||||
* \return None
|
||||
*/
|
||||
void intToStr(size_t value, //!< Value for conversion
|
||||
char* str, //!< Pointer to the converted string
|
||||
size_t size //!< String size
|
||||
);
|
||||
|
||||
//! Image constant data from ABI specification
|
||||
struct ImageConstants : public amd::EmbeddedObject {
|
||||
uint32_t width_; //!< Image surface width
|
||||
uint32_t height_; //!< Image surface height
|
||||
uint32_t depth_; //!< Image surface depth (1 for 2D images)
|
||||
uint32_t dataType_; //!< Image surface data type
|
||||
float widthFloat_; //!< Image surface width
|
||||
float heightFloat_; //!< Image surface height
|
||||
float depthFloat_; //!< Image surface depth (1 for 2D images)
|
||||
uint32_t channelOrder_; //!< Image surface texels channel order
|
||||
};
|
||||
|
||||
//! Kernel arguments
|
||||
struct KernelArg : public amd::HeapObject {
|
||||
public:
|
||||
//! \enum Kernel argument type
|
||||
enum ArgumentType {
|
||||
NoType = 0,
|
||||
PointerGlobal,
|
||||
Value,
|
||||
Image,
|
||||
PointerLocal,
|
||||
PointerHwLocal,
|
||||
PointerPrivate,
|
||||
PointerHwPrivate,
|
||||
PointerConst,
|
||||
PointerHwConst,
|
||||
Float,
|
||||
Double,
|
||||
Half,
|
||||
Char,
|
||||
UChar,
|
||||
Short,
|
||||
UShort,
|
||||
Int,
|
||||
UInt,
|
||||
Long,
|
||||
ULong,
|
||||
Struct,
|
||||
Union,
|
||||
Opaque,
|
||||
Event,
|
||||
Image1D, //!< first image
|
||||
Image2D,
|
||||
Image1DB,
|
||||
Image1DA,
|
||||
Image2DA,
|
||||
Image3D, //!< last image
|
||||
Counter,
|
||||
Sampler,
|
||||
PrivateSize,
|
||||
LocalSize,
|
||||
HwPrivateSize,
|
||||
HwLocalSize,
|
||||
Grouping,
|
||||
WrkgrpSize,
|
||||
Wavefront,
|
||||
PrivateFixed,
|
||||
ErrorMessage,
|
||||
WarningMessage,
|
||||
PrintfFormatStr,
|
||||
MetadataVersion,
|
||||
UavId,
|
||||
ABI64Bit,
|
||||
GWS,
|
||||
SWGWS,
|
||||
Reflection,
|
||||
ConstArg,
|
||||
ConstBufId,
|
||||
PrintfBufId,
|
||||
GroupingHint,
|
||||
VecTypeHint,
|
||||
WavesPerSimdHint,
|
||||
TotalTypes
|
||||
};
|
||||
|
||||
// The compiler metadata fields
|
||||
std::string name_; //!< parameters name
|
||||
ArgumentType type_; //!< type of argument
|
||||
union {
|
||||
uint size_; //!< number of arguments (for values and pointers only)
|
||||
uint location_; //!< sampler's location (for samplers only)
|
||||
};
|
||||
uint cbIdx_; //!< constant buffer index
|
||||
uint cbPos_; //!< dword address in CB for the argument
|
||||
std::string buf_; //!< buffer tag
|
||||
uint index_; //!< buffer/image/sampler index
|
||||
uint alignment_; //!< the required argument's alignment
|
||||
ArgumentType dataType_; //!< data type of the argument
|
||||
union {
|
||||
struct {
|
||||
uint uavBuf_ : 1; //!< UAV memory, no global heap
|
||||
uint realloc_ : 1; //!< argument has to be reallocatedin the global heap
|
||||
uint readOnly_ : 1; //!< Read only memory object
|
||||
uint writeOnly_ : 1; //!< Write only memory object
|
||||
uint readWrite_ : 1; //!< Read/Write memory object
|
||||
};
|
||||
uint value_;
|
||||
} memory_;
|
||||
|
||||
std::string typeName_; //!< argument's type name
|
||||
uint typeQualifier_; //!< argument's type qualifier
|
||||
|
||||
//! Default constructor for the kernel argument
|
||||
KernelArg();
|
||||
|
||||
//! Copy constructor for the kernel argument
|
||||
KernelArg(const KernelArg& data);
|
||||
|
||||
//! Overloads operator=
|
||||
KernelArg& operator=(const KernelArg& data);
|
||||
|
||||
//! Destructor of the kernel argument
|
||||
~KernelArg() { name_.clear(); }
|
||||
|
||||
/*! \brief Checks if this arguments requires a place in constant buffer
|
||||
*
|
||||
* \return True if we need CB
|
||||
*/
|
||||
bool isCbNeeded() const;
|
||||
|
||||
/*! \brief Retrieves the argument's size
|
||||
*
|
||||
* \return Size of the current argument
|
||||
*/
|
||||
size_t size(bool gpuLayer //!< True if we want the argument's size for the GPU layer
|
||||
) const;
|
||||
|
||||
/*! \brief Retrieves the argument's type for the abstraction layer
|
||||
*
|
||||
* \return The argument's type in the abstraction layer format
|
||||
*/
|
||||
clk_value_type_t type() const;
|
||||
|
||||
/*! \brief Retrieves the argument's address qualifier for the abstraction layer
|
||||
*
|
||||
* \return The argument's address qualifier in the abstraction layer format
|
||||
*/
|
||||
cl_kernel_arg_address_qualifier addressQualifier() const;
|
||||
|
||||
/*! \brief Retrieves the argument's access qualifier for the abstraction layer
|
||||
*
|
||||
* \return The argument's access qualifier in the abstraction layer format
|
||||
*/
|
||||
cl_kernel_arg_access_qualifier accessQualifier() const;
|
||||
|
||||
/*! \brief Retrieves the argument's type name for the abstraction layer
|
||||
*
|
||||
* \return The argument's type name
|
||||
*/
|
||||
const char* typeName() const { return typeName_.c_str(); }
|
||||
|
||||
/*! \brief Retrieves the argument's type qualifier for the abstraction layer
|
||||
*
|
||||
* \return The argument's type qualifier
|
||||
*/
|
||||
cl_kernel_arg_type_qualifier typeQualifier() const {
|
||||
switch (type_) {
|
||||
case PointerConst:
|
||||
case PointerHwConst:
|
||||
return static_cast<cl_kernel_arg_type_qualifier>(typeQualifier_ | CL_KERNEL_ARG_TYPE_CONST);
|
||||
default:
|
||||
return static_cast<cl_kernel_arg_type_qualifier>(typeQualifier_);
|
||||
}
|
||||
}
|
||||
|
||||
//! Special case for vectors with component size <= 16bit
|
||||
static constexpr uint VectorSizeLimit = 4;
|
||||
size_t specialVector() const;
|
||||
};
|
||||
|
||||
struct DataTypeConst {
|
||||
const char* tagName_; //!< data type's name
|
||||
KernelArg::ArgumentType type_; //!< data type
|
||||
};
|
||||
|
||||
//! Metadata description for parsing
|
||||
struct MetaDataConst {
|
||||
const char* typeName_; //!< parameters name
|
||||
KernelArg::ArgumentType type_; //!< type of argument
|
||||
struct {
|
||||
uint size_ : 1; //!< number of arguments
|
||||
uint name_ : 1; //!< argument's name
|
||||
uint resType_ : 1; //!< argument's type
|
||||
uint cbIdx_ : 1; //!< resource index CB, sampler or image
|
||||
uint cbPos_ : 1; //!< dword address in CB for the argument
|
||||
uint buf_ : 1; //!< buffer tag
|
||||
uint reserved : 26; //!< reserved
|
||||
};
|
||||
};
|
||||
|
||||
const uint DescTotal = 15;
|
||||
const uint BasicTypeTotal = 15;
|
||||
const uint ArgStateTotal = DescTotal + BasicTypeTotal;
|
||||
|
||||
//! The constant array that describes different metadata properties
|
||||
extern const MetaDataConst ArgState[ArgStateTotal];
|
||||
|
||||
extern const DataTypeConst DataType[];
|
||||
|
||||
extern const uint DataTypeTotal;
|
||||
|
||||
// Forward declaration
|
||||
class Program;
|
||||
class NullProgram;
|
||||
|
||||
class CalImageReference : public amd::ReferenceCountedObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
CalImageReference(CALimage calImage) : image_(calImage) {}
|
||||
|
||||
//! Get CAL image
|
||||
CALimage calImage() const { return image_; }
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalImageReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalImageReference(const CalImageReference&);
|
||||
|
||||
//! Disable operator=
|
||||
CalImageReference& operator=(const CalImageReference&);
|
||||
|
||||
CALimage image_; //!< CAL kernel image
|
||||
};
|
||||
|
||||
//! \class GPU NullKernel - Kernel for offline device
|
||||
class NullKernel : public device::Kernel {
|
||||
public:
|
||||
typedef std::vector<KernelArg*> arguments_t;
|
||||
|
||||
static constexpr uint UavIdUndefined = 0xffff;
|
||||
|
||||
enum Flags {
|
||||
LimitWorkgroup = 1 << 0, //!< Limits the workgroup size
|
||||
PrintfOutput = 1 << 1, //!< Kernel has printf output
|
||||
PrivateFixed = 1 << 2, //!< Kernel has printf output
|
||||
ABI64bit = 1 << 3, //!< Kernel has 64 bit ABI
|
||||
Unused0 = 1 << 4, //!< Unused
|
||||
Unused1 = 1 << 5, //!< Unused
|
||||
ImageEnable = 1 << 6, //!< Kernel uses images
|
||||
ImageWrite = 1 << 7, //!< Kernel writes images
|
||||
};
|
||||
|
||||
//! \enum Resource type for binding
|
||||
enum ResourceType {
|
||||
Undefined = 0x00000000, //!< resource type will be detected
|
||||
ConstantBuffer = 0x00000001, //!< resource is a constant buffer
|
||||
GlobalBuffer = 0x00000002, //!< resource is a global buffer
|
||||
ArgumentHeapBuffer = 0x00000004, //!< resource is an argument buffer
|
||||
ArgumentBuffer = 0x00000005, //!< resource is an argument buffer
|
||||
ArgumentImageRead = 0x00000006, //!< resource is an argument image read
|
||||
ArgumentImageWrite = 0x00000007, //!< resource is an argument image write
|
||||
ArgumentConstBuffer = 0x00000008, //!< resource is an argument const buffer
|
||||
ArgumentCounter = 0x00000009, //!< resource is a global counter
|
||||
ArgumentUavID = 0x0000000a, //!< resource is a dummy ID read
|
||||
ArgumentCbID = 0x0000000b, //!< resource is a constant buffer
|
||||
ArgumentPrintfID = 0x0000000c, //!< resource is a printf buffer
|
||||
};
|
||||
|
||||
//! GPU kernel constructor
|
||||
NullKernel(const std::string& name, //!< The kernel's name
|
||||
const NullDevice& gpuNullDev, //!< GPU device object
|
||||
const NullProgram& nullProg //!< Reference to the program
|
||||
);
|
||||
|
||||
virtual ~NullKernel();
|
||||
|
||||
/*! \brief Creates a GPU kernel in CAL
|
||||
*
|
||||
* \return True if we successfully created a kernel in CAL
|
||||
*/
|
||||
bool create(const std::string& code, //!< IL source code
|
||||
const std::string& metadata, //!< the kernel metadata structure
|
||||
const void* binaryCode = NULL, //!< binary machine code for CAL
|
||||
size_t binarySize = 0 //!< the machine code size
|
||||
);
|
||||
|
||||
//! Returns CAL function descriptor
|
||||
CALimage calImage() const { return calRef_->calImage(); }
|
||||
|
||||
//! Returns TRUE if we successfully retrieved the binary from CAL
|
||||
bool getCalBinary(void* binary, //!< ISA binary code
|
||||
size_t size //!< ISA binary size
|
||||
) const;
|
||||
|
||||
//! Returns CAL image size
|
||||
size_t getCalBinarySize() const;
|
||||
|
||||
//! Returns GPU device object, associated with this kernel
|
||||
const NullDevice& nullDev() const { return gpuDev_; }
|
||||
|
||||
//! Returns GPU device object, associated with this kernel
|
||||
const NullProgram& nullProg() const { return reinterpret_cast<const NullProgram&>(prog_); }
|
||||
|
||||
//! Returns the kernel's build error
|
||||
const int32_t buildError() const { return buildError_; }
|
||||
|
||||
//! Returns the kernel's flags
|
||||
uint flags() const { return flags_; }
|
||||
|
||||
//! Returns TRUE if ABI is for 64 bits
|
||||
bool abi64Bit() const { return (flags_ & ABI64bit) ? true : false; }
|
||||
|
||||
//! Returns the total number of all arguments
|
||||
size_t argSize() const { return arguments_.size(); }
|
||||
|
||||
//! Returns instruction count of the current kernel
|
||||
uint instructionCnt() const { return instructionCnt_; }
|
||||
|
||||
protected:
|
||||
/*! \brief Parses the metadata structure for the kernel,
|
||||
* provided by the OpenCL compiler
|
||||
*
|
||||
* \return True if we succefully parsed all arguments
|
||||
*/
|
||||
bool parseArguments(const std::string& metaData, //!< the program for parsing
|
||||
uint* uavRefCount //!< an array of reference counters for used UAVs
|
||||
);
|
||||
|
||||
//! Returns the argument for the specified index
|
||||
const KernelArg* argument(uint idx) const { return arguments_[idx]; }
|
||||
|
||||
//! Adds the kernel argument into the list
|
||||
void addArgument(KernelArg* arg) { arguments_.push_back(arg); }
|
||||
|
||||
//! Returns the argument for the specified sampler's index
|
||||
const KernelArg* sampler(uint idx) const { return intSamplers_[idx]; }
|
||||
|
||||
//! Returns the total number of all internal samplers
|
||||
size_t samplerSize() const { return intSamplers_.size(); }
|
||||
|
||||
//! Adds the kernel sampler into the sampler's list
|
||||
void addSampler(KernelArg* arg) { intSamplers_.push_back(arg); }
|
||||
|
||||
//! Returns UAV raw index for this kernel
|
||||
uint uavRaw() const { return uavRaw_; }
|
||||
|
||||
int32_t buildError_; //!< Kernel's build error
|
||||
std::string ilSource_; //!< IL source code of this kernel
|
||||
|
||||
const NullDevice& gpuDev_; //!< GPU device object
|
||||
|
||||
CalImageReference* calRef_; //!< CAL image reference for this kernel
|
||||
bool internal_; //!< Runtime internal ker
|
||||
|
||||
uint flags_; //!< kernel object flags
|
||||
arguments_t arguments_; //!< kernel arguments for the execution
|
||||
arguments_t intSamplers_; //!< predefined intenal kernel samplers
|
||||
|
||||
size_t* cbSizes_; //!< real constant buffer sizes for this kernel
|
||||
uint numCb_; //!< total number of constant buffers
|
||||
|
||||
uint uavRaw_; //!< UAV used for RAW access
|
||||
|
||||
bool rwAttributes_; //!< backend provides RW attributes for arguments
|
||||
|
||||
uint instructionCnt_; //!< Instruction count
|
||||
|
||||
uint cbId_; //!< UAV used for constant buffer access
|
||||
uint printfId_; //!< UAV used for printf buffer access
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
NullKernel(const NullKernel&);
|
||||
|
||||
//! Disable operator=
|
||||
NullKernel& operator=(const NullKernel&);
|
||||
|
||||
//! Creates a filename for ISA/IL dumps
|
||||
std::string mkDumpName(const char* extension //!< File extension to append
|
||||
) const;
|
||||
|
||||
bool createMultiBinary(uint* imageSize, //!< Multibinary image size
|
||||
void** image, //!< Multibinary image
|
||||
const void* isa //!< Kernel HW info
|
||||
);
|
||||
|
||||
//! SI HW specific setup for kernels
|
||||
bool siCreateHwInfo(const void* shader, //!< HW info shader
|
||||
AMUabiAddEncoding& encoding //!< ABI encoding structure
|
||||
);
|
||||
|
||||
//! r800 HW specific setup for kernels
|
||||
bool r800CreateHwInfo(const void* shader, //!< HW info shader
|
||||
AMUabiAddEncoding& encoding //!< ABI encoding structure
|
||||
);
|
||||
};
|
||||
|
||||
//! \class GPU kernel
|
||||
class Kernel : public NullKernel {
|
||||
public:
|
||||
struct InitData {
|
||||
uint privateSize_; //!< Private ring initial size
|
||||
uint localSize_; //!< Local ring initial size
|
||||
uint hwPrivateSize_; //!< HW private ring initial size
|
||||
uint hwLocalSize_; //!< HW local ring initial size
|
||||
uint flags_; //!< Kernel initialization flags
|
||||
};
|
||||
|
||||
//! GPU kernel constructor
|
||||
Kernel(const std::string& name, //!< The kernel's name
|
||||
const Device& gpuDev, //!< GPU device object
|
||||
const Program& prog, //!< Reference to the program
|
||||
const InitData* initData_ //!< Initialization data
|
||||
);
|
||||
|
||||
//! GPU kernel destructor
|
||||
virtual ~Kernel();
|
||||
|
||||
/*! \brief Creates a GPU kernel in CAL
|
||||
*
|
||||
* \return True if we successfully created a kernel in CAL
|
||||
*/
|
||||
bool create(const std::string& code, //!< IL source code
|
||||
const std::string& metadata, //!< the kernel metadata structure
|
||||
const void* binaryCode = NULL, //!< binary machine code for CAL
|
||||
size_t binarySize = 0 //!< the machine code size
|
||||
);
|
||||
|
||||
//! Initializes the CAL program grid for the kernel execution
|
||||
void setupProgramGrid(VirtualGPU& gpu, //!< virtual GPU device object
|
||||
size_t workDim, //!< work dimension
|
||||
const amd::NDRange& glbWorkOffset, //!< global work offset
|
||||
const amd::NDRange& gblWorkSize, //!< global work size
|
||||
amd::NDRange& lclWorkSize, //!< local work size
|
||||
const amd::NDRange& groupOffset, //!< group offsets
|
||||
const amd::NDRange& glbWorkOffsetOrg,
|
||||
const amd::NDRange& glbWorkSizeOrg //!< original global work size
|
||||
) const;
|
||||
|
||||
/*! \brief Detects if runtime has to disable cache optimization and
|
||||
* recompiles the kernel
|
||||
*
|
||||
* \return True if aliases were detected in the kernel arguments
|
||||
*/
|
||||
void processMemObjects(VirtualGPU& gpu, //!< Virtual GPU objects - queue
|
||||
const amd::Kernel& kernel, //!< AMD kernel object for execution
|
||||
const_address params, //!< pointer to the param's store
|
||||
bool nativeMem //!< Native memory objects
|
||||
) const;
|
||||
|
||||
/*! \brief Loads all kernel arguments, so we could run the kernel in HW.
|
||||
* This includes CB update and resource binding
|
||||
*
|
||||
* \return True if we succefully loaded the arguments
|
||||
*/
|
||||
bool loadParameters(VirtualGPU& gpu, //!< virtual GPU device object
|
||||
const amd::Kernel& kernel, //!< AMD kernel object for execution
|
||||
const_address params, //!< pointer to the param's store
|
||||
bool nativeMem //!< Native memory objects
|
||||
) const;
|
||||
|
||||
//! Binds the constant buffers associated with the kernel
|
||||
bool bindConstantBuffers(VirtualGPU& gpu) const;
|
||||
|
||||
/*! \brief Runs the kernel on HW
|
||||
*
|
||||
* \return True if we succefully executed the kernel
|
||||
*/
|
||||
bool run(VirtualGPU& gpu, //!< virtual GPU device object
|
||||
GpuEvent* gpuEvent, //!< Pointer to the GPU event
|
||||
bool lastRun, //!< Last run in the split execution
|
||||
bool lastDoppCmd, //!< for last dopp submission kernel dispatch
|
||||
bool pfpaDoppCmd //!< for PFPA dopp submission kernel dispatch
|
||||
) const;
|
||||
|
||||
//! Help function to debug the kernel output
|
||||
void debug(VirtualGPU& gpu //!< virtual GPU device object
|
||||
) const;
|
||||
|
||||
//! Programs internal samplers defined inside the kernel
|
||||
bool setInternalSamplers(VirtualGPU& gpu //!< Virtual GPU device object
|
||||
) const;
|
||||
|
||||
//! Returns TRUE if we successfully retrieved the binary from CAL
|
||||
bool getCalBinary(void* binary, //!< ISA binary code
|
||||
size_t size //!< ISA binary size
|
||||
) const;
|
||||
|
||||
//! Returns CAL image size
|
||||
size_t getCalBinarySize() const;
|
||||
|
||||
//! Returns GPU device object, associated with this kernel
|
||||
const Device& dev() const;
|
||||
|
||||
//! Returns GPU device object, associated with this kernel
|
||||
const Program& prog() const;
|
||||
|
||||
//! Binds global HW constant buffers
|
||||
bool bindGlobalHwCb(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
VirtualGPU::GslKernelDesc* desc //!< Kernel descriptor
|
||||
) const;
|
||||
|
||||
protected:
|
||||
//! Initializes the kernel parameters for the abstraction layer
|
||||
bool initParameters();
|
||||
|
||||
/*! \brief Creates constant buffer resources, associated with the kernel
|
||||
*
|
||||
* \return TRUE if we succefully created constant buffers
|
||||
*/
|
||||
bool initConstBuffers();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Kernel(const Kernel&);
|
||||
|
||||
//! Disable operator=
|
||||
Kernel& operator=(const Kernel&);
|
||||
|
||||
//! \enum Fixed Metadata offsets
|
||||
enum MetadataOffsets {
|
||||
GlobalWorkitemOffset = 0,
|
||||
LocalWorkitemOffset = 1,
|
||||
GroupsOffset = 2,
|
||||
PrivateRingOffset = 3,
|
||||
LocalRingOffset = 4,
|
||||
MathLibOffset = 5,
|
||||
GlobalWorkOffsetOffset = 6,
|
||||
GroupWorkOffsetOffset = 7,
|
||||
GlobalDataStoreOffset = 8,
|
||||
DebugOffset = 8,
|
||||
NDRangeGlobalWorkOffsetOffset = 9,
|
||||
|
||||
// The total number of constants reserved for ABI
|
||||
TotalABIVectors
|
||||
};
|
||||
|
||||
/*! \brief Sets the kernel argument
|
||||
*
|
||||
* \return True if we succefully updated the arguments
|
||||
*/
|
||||
bool setArgument(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
const amd::Kernel& kernel, //!< AMD kernel object
|
||||
uint idx, //!< the argument index
|
||||
const_address params,//!< the arguments data
|
||||
const amd::KernelParameterDescriptor& desc, //!< Argument's descriptor
|
||||
bool nativeMem //!< Native memory objects
|
||||
) const;
|
||||
|
||||
/*! \brief Initializes local and private buffer ranges
|
||||
*
|
||||
* \return True if we succefully initialized the ranges
|
||||
*/
|
||||
bool initLocalPrivateRanges(VirtualGPU& gpu //!< Virtual GPU device object
|
||||
) const;
|
||||
|
||||
//! Sets local and private buffer ranges
|
||||
void setLocalPrivateRanges(VirtualGPU& gpu //!< Virtual GPU device object
|
||||
) const;
|
||||
|
||||
//! Sets the sampler's parameters for the image look-up
|
||||
void setSampler(VirtualGPU& gpu, //!< virtual GPU device object
|
||||
uint32_t state, //!< sampler state
|
||||
uint physUnit //!< sampler's number
|
||||
) const;
|
||||
|
||||
/*! \brief Binds resource
|
||||
*
|
||||
* \return True if we succefully created constant buffers
|
||||
*/
|
||||
bool bindResource(VirtualGPU& gpu, //!< virtual GPU device object
|
||||
const Memory& memory, //!< memory for binding
|
||||
uint paramIdx, //!< index of the parameter
|
||||
ResourceType type, //!< resource type
|
||||
uint physUnit, //!< PhysUnit
|
||||
size_t offset = 0) const;
|
||||
|
||||
//! Unbinds all resources for the kernel
|
||||
void unbindResources(VirtualGPU& gpu, //!< virtual GPU device object
|
||||
GpuEvent gpuEvent, //!< GPU event that will be associated with the resources
|
||||
bool lastRun //!< last run in the split execution
|
||||
) const;
|
||||
|
||||
//! Copies image constants to the constant buffer
|
||||
void copyImageConstants(const amd::Image* amdImage, //!< Abstraction layer image object
|
||||
ImageConstants* imageData //!< Pointer in CB to the image constants
|
||||
) const;
|
||||
|
||||
//! Finds local workgroup size
|
||||
void findLocalWorkSize(size_t workDim, //!< Work dimension
|
||||
const amd::NDRange& gblWorkSize, //!< Global work size
|
||||
amd::NDRange& lclWorkSize //!< Local work size
|
||||
) const;
|
||||
|
||||
uint hwPrivateSize_; //!< initial HW private size
|
||||
uint hwLocalSize_; //!< initial HW local size
|
||||
};
|
||||
|
||||
enum HSAIL_ADDRESS_QUALIFIER {
|
||||
HSAIL_ADDRESS_ERROR = 0,
|
||||
HSAIL_ADDRESS_GLOBAL,
|
||||
HSAIL_ADDRESS_LOCAL,
|
||||
HSAIL_MAX_ADDRESS_QUALIFIERS
|
||||
};
|
||||
|
||||
enum HSAIL_ARG_TYPE {
|
||||
HSAIL_ARGTYPE_ERROR = 0,
|
||||
HSAIL_ARGTYPE_POINTER,
|
||||
HSAIL_ARGTYPE_VALUE,
|
||||
HSAIL_ARGTYPE_IMAGE,
|
||||
HSAIL_ARGTYPE_SAMPLER,
|
||||
HSAIL_ARGTYPE_QUEUE,
|
||||
HSAIL_ARGMAX_ARG_TYPES
|
||||
};
|
||||
|
||||
enum HSAIL_DATA_TYPE {
|
||||
HSAIL_DATATYPE_ERROR = 0,
|
||||
HSAIL_DATATYPE_B1,
|
||||
HSAIL_DATATYPE_B8,
|
||||
HSAIL_DATATYPE_B16,
|
||||
HSAIL_DATATYPE_B32,
|
||||
HSAIL_DATATYPE_B64,
|
||||
HSAIL_DATATYPE_S8,
|
||||
HSAIL_DATATYPE_S16,
|
||||
HSAIL_DATATYPE_S32,
|
||||
HSAIL_DATATYPE_S64,
|
||||
HSAIL_DATATYPE_U8,
|
||||
HSAIL_DATATYPE_U16,
|
||||
HSAIL_DATATYPE_U32,
|
||||
HSAIL_DATATYPE_U64,
|
||||
HSAIL_DATATYPE_F16,
|
||||
HSAIL_DATATYPE_F32,
|
||||
HSAIL_DATATYPE_F64,
|
||||
HSAIL_DATATYPE_STRUCT,
|
||||
HSAIL_DATATYPE_OPAQUE,
|
||||
HSAIL_DATATYPE_MAX_TYPES
|
||||
};
|
||||
|
||||
enum HSAIL_ACCESS_TYPE {
|
||||
HSAIL_ACCESS_TYPE_NONE = 0,
|
||||
HSAIL_ACCESS_TYPE_RO,
|
||||
HSAIL_ACCESS_TYPE_WO,
|
||||
HSAIL_ACCESS_TYPE_RW
|
||||
};
|
||||
|
||||
class HSAILKernel : public device::Kernel {
|
||||
public:
|
||||
struct Argument {
|
||||
std::string name_; //!< Argument's name
|
||||
std::string typeName_; //!< Argument's type name
|
||||
uint size_; //!< Size in bytes
|
||||
uint offset_; //!< Argument's offset
|
||||
uint alignment_; //!< Argument's alignment
|
||||
HSAIL_ARG_TYPE type_; //!< Type of the argument
|
||||
HSAIL_ADDRESS_QUALIFIER addrQual_; //!< Address qualifier of the argument
|
||||
HSAIL_DATA_TYPE dataType_; //!< The type of data
|
||||
uint numElem_; //!< Number of elements
|
||||
HSAIL_ACCESS_TYPE access_; //!< Access type for the argument
|
||||
};
|
||||
|
||||
// Max number of possible extra (hidden) kernel arguments
|
||||
static constexpr uint MaxExtraArgumentsNum = 6;
|
||||
|
||||
HSAILKernel(std::string name, HSAILProgram* prog, std::string compileOptions, uint extraArgsNum);
|
||||
|
||||
virtual ~HSAILKernel();
|
||||
|
||||
//! Initializes the metadata required for this kernel,
|
||||
//! finalizes the kernel if needed
|
||||
bool init(amd::hsa::loader::Symbol* sym, bool finalize = false);
|
||||
|
||||
//! Returns a pointer to the hsail argument
|
||||
const Argument* argument(size_t i) const { return arguments_[i]; }
|
||||
|
||||
//! Returns the number of hsail arguments
|
||||
size_t numArguments() const { return arguments_.size(); }
|
||||
|
||||
//! Returns GPU device object, associated with this kernel
|
||||
const Device& dev() const;
|
||||
|
||||
//! Returns HSA program associated with this kernel
|
||||
const HSAILProgram& prog() const;
|
||||
|
||||
//! Returns LDS size used in this kernel
|
||||
uint32_t ldsSize() const { return cpuAqlCode_->workgroup_group_segment_byte_size; }
|
||||
|
||||
//! Returns pointer on CPU to AQL code info
|
||||
const void* cpuAqlCode() const { return cpuAqlCode_; }
|
||||
|
||||
//! Returns memory object with AQL code
|
||||
gpu::Memory* gpuAqlCode() const { return code_; }
|
||||
|
||||
//! Returns size of AQL code
|
||||
size_t aqlCodeSize() const { return codeSize_; }
|
||||
|
||||
//! Returns the size of argument buffer
|
||||
size_t argsBufferSize() const { return cpuAqlCode_->kernarg_segment_byte_size; }
|
||||
|
||||
//! Returns spill reg size per workitem
|
||||
int spillSegSize() const { return cpuAqlCode_->workitem_private_segment_byte_size; }
|
||||
|
||||
//! Returns AQL packet in CPU memory
|
||||
//! if the kerenl arguments were successfully loaded, otherwise NULL
|
||||
hsa_kernel_dispatch_packet_t* loadArguments(
|
||||
VirtualGPU& gpu, //!< Running GPU context
|
||||
const amd::Kernel& kernel, //!< AMD kernel object
|
||||
const amd::NDRangeContainer& sizes, //!< NDrange container
|
||||
const_address parameters, //!< Application arguments for the kernel
|
||||
bool nativeMem, //!< Native memory objectes are passed
|
||||
uint64_t vmDefQueue, //!< GPU VM default queue pointer
|
||||
uint64_t* vmParentWrap, //!< GPU VM parent aql wrap object
|
||||
std::vector<const Memory*>& memList //!< Memory list for GSL/VidMM handles
|
||||
) const;
|
||||
|
||||
//! Returns the kernel index in the program
|
||||
uint index() const { return index_; }
|
||||
|
||||
//! Returns kernel's extra argument count
|
||||
uint extraArgumentsNum() const { return extraArgumentsNum_; }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
HSAILKernel(const HSAILKernel&);
|
||||
|
||||
//! Disable operator=
|
||||
HSAILKernel& operator=(const HSAILKernel&);
|
||||
|
||||
//! Creates AQL kernel HW info
|
||||
bool aqlCreateHWInfo(amd::hsa::loader::Symbol* sym);
|
||||
|
||||
//! Initializes arguments_ and the abstraction layer kernel parameters
|
||||
void initArgList(const aclArgData* aclArg //!< List of ACL arguments
|
||||
);
|
||||
|
||||
//! Initializes Hsail Argument metadata and info
|
||||
void initHsailArgs(const aclArgData* aclArg //!< List of ACL arguments
|
||||
);
|
||||
|
||||
std::vector<Argument*> arguments_; //!< Vector list of HSAIL Arguments
|
||||
std::string compileOptions_; //!< compile used for finalizing this kernel
|
||||
amd_kernel_code_t* cpuAqlCode_; //!< AQL kernel code on CPU
|
||||
uint index_; //!< Kernel index in the program
|
||||
|
||||
gpu::Memory* code_; //!< Memory object with ISA code
|
||||
size_t codeSize_; //!< Size of ISA code
|
||||
|
||||
char* hwMetaData_; //!< SI metadata
|
||||
|
||||
uint extraArgumentsNum_; //! Number of extra (hidden) kernel arguments
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUKERNEL_HPP_*/
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,286 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUMEMORY_HPP_
|
||||
#define GPUMEMORY_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "device/gpu/gpuresource.hpp"
|
||||
#include <map>
|
||||
|
||||
/*! \addtogroup GPU
|
||||
* @{
|
||||
*/
|
||||
namespace device {
|
||||
class Memory;
|
||||
}
|
||||
|
||||
//! GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
class Device;
|
||||
class Heap;
|
||||
class Resource;
|
||||
class Memory;
|
||||
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
|
||||
};
|
||||
|
||||
//! 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 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 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
|
||||
);
|
||||
|
||||
//! Default destructor
|
||||
~Memory();
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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 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
|
||||
);
|
||||
|
||||
virtual uint64_t virtualAddress() const override { return (vmAddress() + pinOffset()); }
|
||||
|
||||
//! Allocates host memory for synchronization with MGPU context
|
||||
void mgpuCacheWriteBack();
|
||||
|
||||
//! Accessors for indirect map memory object
|
||||
Memory* mapMemory() const;
|
||||
|
||||
//! 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_; }
|
||||
|
||||
//! Sets interop type for this memory object
|
||||
void setInteropType(InteropType type) { interopType_ = type; }
|
||||
|
||||
//! 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);
|
||||
|
||||
//! 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() ||
|
||||
(owner()->getMemFlags() &
|
||||
(CL_MEM_ALLOC_HOST_PTR | CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY)));
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Decrement map count
|
||||
void decIndMapCount();
|
||||
|
||||
//! Initialize the object members
|
||||
void init();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Memory(const Memory&);
|
||||
|
||||
//! Disable operator=
|
||||
Memory& operator=(const Memory&);
|
||||
|
||||
InteropType interopType_; //!< Interop type
|
||||
Memory* interopMemory_; //!< interop memory
|
||||
|
||||
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) {}
|
||||
|
||||
//! 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&);
|
||||
|
||||
//! Disable operator=
|
||||
Buffer& operator=(const Buffer&);
|
||||
|
||||
//! The size of buffer element in bytes
|
||||
static constexpr size_t ElementSize = 4;
|
||||
|
||||
//! The type of buffer element
|
||||
static constexpr 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
|
||||
)
|
||||
: 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
|
||||
)
|
||||
: 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
|
||||
);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Image(const Image&);
|
||||
|
||||
//! Disable operator=
|
||||
Image& operator=(const Image&);
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif // GPUMEMORY_HPP_
|
||||
@@ -1,657 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "top.hpp"
|
||||
#include "os/os.hpp"
|
||||
#include "device/device.hpp"
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpumemory.hpp"
|
||||
#include "device/gpu/gpukernel.hpp"
|
||||
#include "device/gpu/gpuprogram.hpp"
|
||||
#include "device/gpu/gpuprintf.hpp"
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
namespace gpu {
|
||||
|
||||
PrintfDbg::PrintfDbg(Device& device, FILE* file)
|
||||
: dbgBuffer_(NULL),
|
||||
dbgFile_(file),
|
||||
gpuDevice_(device),
|
||||
wiDbgSize_(0),
|
||||
initCntValue_(device, 4) {}
|
||||
|
||||
PrintfDbg::~PrintfDbg() { delete dbgBuffer_; }
|
||||
|
||||
bool PrintfDbg::create() {
|
||||
// Create a resource for the init count value
|
||||
if (initCntValue_.create(Resource::Remote)) {
|
||||
uint32_t* value = reinterpret_cast<uint32_t*>(initCntValue_.map(NULL));
|
||||
// The counter starts from 1
|
||||
if (NULL != value) {
|
||||
*value = 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
initCntValue_.unmap(NULL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PrintfDbg::init(VirtualGPU& gpu, bool printfEnabled, const amd::NDRange& size) {
|
||||
// Set up debug output buffer (if printf active)
|
||||
if (printfEnabled) {
|
||||
if (!allocate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure that the size isn't bigger than the reported max
|
||||
if (size.product() <= dev().settings().maxWorkGroupSize_) {
|
||||
size_t wiDbgSizeTmp;
|
||||
|
||||
// Calculate the debug buffer size per workitem
|
||||
wiDbgSizeTmp = std::min(dbgBuffer_->size() / size.product(), dev().xferRead().bufSize());
|
||||
|
||||
// Make sure the size is DWORD aligned
|
||||
wiDbgSizeTmp = amd::alignDown(wiDbgSizeTmp, sizeof(uint32_t));
|
||||
|
||||
// If the new size is different, then clear the initial values
|
||||
if (wiDbgSize_ != wiDbgSizeTmp) {
|
||||
wiDbgSize_ = wiDbgSizeTmp;
|
||||
if (!clearWorkitems(gpu, 0, size.product())) {
|
||||
wiDbgSize_ = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrintfDbg::output(VirtualGPU& gpu, bool printfEnabled, const amd::NDRange& size,
|
||||
const std::vector<device::PrintfInfo>& printfInfo) {
|
||||
// Are we expected to generate debug output?
|
||||
if (printfEnabled && !printfInfo.empty()) {
|
||||
uint32_t* workitemData;
|
||||
size_t i, j, k, z;
|
||||
bool realloc = false;
|
||||
|
||||
// Wait for kernel execution
|
||||
gpu.waitAllEngines();
|
||||
|
||||
size_t zdim = 1;
|
||||
size_t ydim = 1;
|
||||
size_t xdim = 1;
|
||||
|
||||
switch (size.dimensions()) {
|
||||
case 3:
|
||||
zdim = size[2];
|
||||
// Fall through ...
|
||||
case 2:
|
||||
ydim = size[1];
|
||||
// Fall through ...
|
||||
case 1:
|
||||
xdim = size[0];
|
||||
// Fall through ...
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (k = 0; k < zdim; ++k) {
|
||||
for (j = 0; j < ydim; ++j) {
|
||||
for (i = 0; i < xdim; ++i) {
|
||||
size_t idx = (xdim * (ydim * k + j) + i);
|
||||
workitemData = mapWorkitem(gpu, idx, &realloc);
|
||||
|
||||
if (NULL != workitemData) {
|
||||
uint32_t wp = workitemData[0]; // write pointer (i.e. first unwritten element)
|
||||
// Walk through each PrintfDbg entry
|
||||
for (z = 1; (z < (wiDbgSize() / sizeof(uint32_t))) && (z < wp);) {
|
||||
if (printfInfo.size() < workitemData[z]) {
|
||||
LogError("The format string wasn't reported");
|
||||
return false;
|
||||
}
|
||||
// Get the PrintfDbg info
|
||||
const device::PrintfInfo& info = printfInfo[workitemData[z++]];
|
||||
// There's something in this buffer
|
||||
outputDbgBuffer(info, workitemData, z);
|
||||
}
|
||||
}
|
||||
unmapWorkitem(gpu, workitemData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reallocate debug buffer if necessary
|
||||
if (!allocate(realloc)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t PrintfDbg::bufOffset() const { return dbgBuffer_->hbOffset(); }
|
||||
|
||||
bool PrintfDbg::allocate(bool realloc) {
|
||||
if (NULL == dbgBuffer_) {
|
||||
dbgBuffer_ = dev().createScratchBuffer(dev().info().printfBufferSize_);
|
||||
} else if (realloc) {
|
||||
LogWarning("Debug buffer reallocation!");
|
||||
// Double the buffer size if it's not big enough
|
||||
size_t size = dbgBuffer_->size();
|
||||
delete dbgBuffer_;
|
||||
dbgBuffer_ = dev().createScratchBuffer(size << 1);
|
||||
}
|
||||
|
||||
return (NULL != dbgBuffer_) ? true : false;
|
||||
}
|
||||
|
||||
bool PrintfDbg::checkFloat(const std::string& fmt) const {
|
||||
switch (fmt[fmt.size() - 1]) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
case 'a':
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PrintfDbg::checkString(const std::string& fmt) const {
|
||||
if (fmt[fmt.size() - 1] == 's') return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int PrintfDbg::checkVectorSpecifier(const std::string& fmt, size_t startPos, size_t& curPos) const {
|
||||
int vectorSize = 0;
|
||||
size_t pos = curPos;
|
||||
size_t size = curPos - startPos;
|
||||
|
||||
if (size >= 3) {
|
||||
size = 0;
|
||||
// no modifiers
|
||||
if (fmt[curPos - 3] == 'v') {
|
||||
size = 2;
|
||||
}
|
||||
// the modifiers are "h" or "l"
|
||||
else if (fmt[curPos - 4] == 'v') {
|
||||
size = 3;
|
||||
}
|
||||
// the modifier is "hh"
|
||||
else if ((curPos >= 5) && (fmt[curPos - 5] == 'v')) {
|
||||
size = 4;
|
||||
}
|
||||
if (size > 0) {
|
||||
curPos = size;
|
||||
pos -= curPos;
|
||||
|
||||
// Get vector size
|
||||
vectorSize = fmt[pos++] - '0';
|
||||
// PrintfDbg supports only 2, 3, 4, 8 and 16 wide vectors
|
||||
switch (vectorSize) {
|
||||
case 1:
|
||||
if ((fmt[pos++] - '0') == 6) {
|
||||
vectorSize = 16;
|
||||
} else {
|
||||
vectorSize = 0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
vectorSize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vectorSize;
|
||||
}
|
||||
|
||||
static constexpr size_t ConstStr = 0xffffffff;
|
||||
static constexpr char Separator[] = ",\0";
|
||||
|
||||
size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t size,
|
||||
const uint32_t* argument) const {
|
||||
// Serialize the output to the screen
|
||||
amd::ScopedLock k(dev().lockAsyncOps());
|
||||
|
||||
size_t copiedBytes = size;
|
||||
// Print the string argument, using standard PrintfDbg()
|
||||
if (checkString(fmt.c_str())) {
|
||||
// copiedBytes should be as number of printed chars
|
||||
copiedBytes = 0;
|
||||
//(null) should be printed
|
||||
if (*argument == 0) {
|
||||
amd::Os::printf(fmt.data(), 0);
|
||||
// copiedBytes = strlen("(null)")
|
||||
copiedBytes = 6;
|
||||
} else {
|
||||
const unsigned char* argumentStr = reinterpret_cast<const unsigned char*>(argument);
|
||||
amd::Os::printf(fmt.data(), argumentStr);
|
||||
// copiedBytes = strlen(argumentStr)
|
||||
while (argumentStr[copiedBytes++] != 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// Print the argument(except for string ), using standard PrintfDbg()
|
||||
else {
|
||||
bool hlModifier = (strstr(fmt.c_str(), "hl") != NULL);
|
||||
std::string hlFmt;
|
||||
if (hlModifier) {
|
||||
hlFmt = fmt;
|
||||
hlFmt.erase(hlFmt.find_first_of("hl"), 2);
|
||||
}
|
||||
switch (size) {
|
||||
case 0: {
|
||||
const char* str = reinterpret_cast<const char*>(argument);
|
||||
amd::Os::printf(fmt.data(), str);
|
||||
// Find the string length
|
||||
while (str[copiedBytes++] != 0)
|
||||
;
|
||||
} break;
|
||||
case 1:
|
||||
amd::Os::printf(fmt.data(), *(reinterpret_cast<const unsigned char*>(argument)));
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
if (printFloat) {
|
||||
static const char* fSpecifiers = "eEfgGa";
|
||||
std::string fmtF = fmt;
|
||||
size_t posS = fmtF.find_first_of("%");
|
||||
size_t posE = fmtF.find_first_of(fSpecifiers);
|
||||
if (posS != std::string::npos && posE != std::string::npos) {
|
||||
fmtF.replace(posS + 1, posE - posS, "s");
|
||||
}
|
||||
float fArg = *(reinterpret_cast<const float*>(argument));
|
||||
float fSign = copysign(1.0, fArg);
|
||||
if (isinf(fArg) && !isnan(fArg)) {
|
||||
if (fSign < 0) {
|
||||
amd::Os::printf(fmtF.data(), "-infinity");
|
||||
} else {
|
||||
amd::Os::printf(fmtF.data(), "infinity");
|
||||
}
|
||||
} else if (isnan(fArg)) {
|
||||
if (fSign < 0) {
|
||||
amd::Os::printf(fmtF.data(), "-nan");
|
||||
} else {
|
||||
amd::Os::printf(fmtF.data(), "nan");
|
||||
}
|
||||
} else if (hlModifier) {
|
||||
amd::Os::printf(hlFmt.data(), fArg);
|
||||
} else {
|
||||
amd::Os::printf(fmt.data(), fArg);
|
||||
}
|
||||
} else {
|
||||
bool hhModifier = (strstr(fmt.c_str(), "hh") != NULL);
|
||||
if (hhModifier) {
|
||||
// current implementation of printf in gcc 4.5.2 runtime libraries, doesn`t recognize
|
||||
// "hh" modifier ==>
|
||||
// argument should be explicitly converted to unsigned char (uchar) before printing and
|
||||
// fmt should be updated not to contain "hh" modifier
|
||||
std::string hhFmt = fmt;
|
||||
hhFmt.erase(hhFmt.find_first_of("h"), 2);
|
||||
amd::Os::printf(hhFmt.data(), *(reinterpret_cast<const unsigned char*>(argument)));
|
||||
} else if (hlModifier) {
|
||||
amd::Os::printf(hlFmt.data(), *argument);
|
||||
} else {
|
||||
amd::Os::printf(fmt.data(), *argument);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (printFloat) {
|
||||
if (hlModifier) {
|
||||
amd::Os::printf(hlFmt.data(), *(reinterpret_cast<const double*>(argument)));
|
||||
} else {
|
||||
amd::Os::printf(fmt.data(), *(reinterpret_cast<const double*>(argument)));
|
||||
}
|
||||
} else {
|
||||
std::string out = fmt;
|
||||
// Use 'll' for 64 bit printf
|
||||
out.insert((out.size() - 1), 1, 'l');
|
||||
amd::Os::printf(out.data(), *(reinterpret_cast<const uint64_t*>(argument)));
|
||||
}
|
||||
break;
|
||||
case ConstStr: {
|
||||
const char* str = reinterpret_cast<const char*>(argument);
|
||||
amd::Os::printf(fmt.data(), str);
|
||||
} break;
|
||||
default:
|
||||
amd::Os::printf("Error: Unsupported data size for PrintfDbg. %d bytes",
|
||||
static_cast<int>(size));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
return copiedBytes;
|
||||
}
|
||||
|
||||
void PrintfDbg::outputDbgBuffer(const device::PrintfInfo& info, const uint32_t* workitemData,
|
||||
size_t& i) const {
|
||||
static const char* specifiers = "cdieEfgGaosuxXp";
|
||||
static const char* modifiers = "hl";
|
||||
static const char* special = "%n";
|
||||
static const std::string sepStr = "%s";
|
||||
const uint32_t* s = workitemData;
|
||||
size_t pos = 0;
|
||||
|
||||
// Find the format string
|
||||
std::string str = info.fmtString_;
|
||||
std::string fmt;
|
||||
size_t posStart, posEnd;
|
||||
|
||||
// Print all arguments
|
||||
// Note: the following code walks through all arguments, provided by the kernel and
|
||||
// finds the corresponding specifier in the format string.
|
||||
// Then it splits the original string into substrings with a single specifier and
|
||||
// uses standard PrintfDbg() to print each argument
|
||||
for (uint j = 0; j < info.arguments_.size(); ++j) {
|
||||
do {
|
||||
posStart = str.find_first_of("%", pos);
|
||||
if (posStart != std::string::npos) {
|
||||
posStart++;
|
||||
// Erase all spaces after %
|
||||
while (str[posStart] == ' ') {
|
||||
str.erase(posStart, 1);
|
||||
}
|
||||
size_t tmp = str.find_first_of(special, posStart);
|
||||
size_t tmp2 = str.find_first_of(specifiers, posStart);
|
||||
// Special cases. Special symbol is located before any specifier
|
||||
if (tmp < tmp2) {
|
||||
posEnd = posStart + 1;
|
||||
fmt = str.substr(pos, posEnd - pos);
|
||||
fmt.erase(posStart - pos - 1, 1);
|
||||
pos = posStart = posEnd;
|
||||
outputArgument(sepStr, false, ConstStr, reinterpret_cast<const uint32_t*>(fmt.data()));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} else if (pos < str.length()) {
|
||||
outputArgument(sepStr, false, ConstStr,
|
||||
reinterpret_cast<const uint32_t*>((str.substr(pos)).data()));
|
||||
}
|
||||
} while (posStart != std::string::npos);
|
||||
|
||||
if (posStart != std::string::npos) {
|
||||
bool printFloat = false;
|
||||
int vectorSize = 0;
|
||||
size_t idPos = 0;
|
||||
|
||||
// Search for PrintfDbg specifier in the format string.
|
||||
// It will be a split point for the output
|
||||
posEnd = str.find_first_of(specifiers, posStart);
|
||||
if (posEnd == std::string::npos) {
|
||||
pos = posStart = posEnd;
|
||||
break;
|
||||
}
|
||||
posEnd++;
|
||||
|
||||
size_t curPos = posEnd;
|
||||
vectorSize = checkVectorSpecifier(str, posStart, curPos);
|
||||
|
||||
// Get substring from the last position to the current specifier
|
||||
fmt = str.substr(pos, posEnd - pos);
|
||||
|
||||
// Readjust the string pointer if PrintfDbg outputs a vector
|
||||
if (vectorSize != 0) {
|
||||
size_t posVecSpec = fmt.length() - (curPos + 1);
|
||||
size_t posVecMod = fmt.find_first_of(modifiers, posVecSpec + 1);
|
||||
size_t posMod = str.find_first_of(modifiers, posStart);
|
||||
if (posMod < posEnd) {
|
||||
fmt = fmt.erase(posVecSpec, posVecMod - posVecSpec);
|
||||
} else {
|
||||
fmt = fmt.erase(posVecSpec, curPos);
|
||||
}
|
||||
idPos = posStart - pos - 1;
|
||||
}
|
||||
pos = posStart = posEnd;
|
||||
|
||||
// Find out if the argument is a float
|
||||
printFloat = checkFloat(fmt);
|
||||
|
||||
// Is it a scalar value?
|
||||
if (vectorSize == 0) {
|
||||
size_t length = outputArgument(fmt, printFloat, info.arguments_[j], &s[i]);
|
||||
if (0 == length) {
|
||||
return;
|
||||
}
|
||||
i += amd::alignUp(length, sizeof(uint32_t)) / sizeof(uint32_t);
|
||||
} else {
|
||||
// 3-component vector's size is defined as 4 * size of each scalar component
|
||||
size_t elemSize = info.arguments_[j] / (vectorSize == 3 ? 4 : vectorSize);
|
||||
size_t k = i * sizeof(uint32_t);
|
||||
std::string elementStr = fmt.substr(idPos, fmt.size());
|
||||
|
||||
// Print first element with full string
|
||||
if (0 == outputArgument(fmt, printFloat, elemSize, &s[i])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Print other elemnts with separator if available
|
||||
for (int e = 1; e < vectorSize; ++e) {
|
||||
const char* t = reinterpret_cast<const char*>(s);
|
||||
// Output the vector separator
|
||||
outputArgument(sepStr, false, ConstStr, reinterpret_cast<const uint32_t*>(Separator));
|
||||
|
||||
// Output the next element
|
||||
outputArgument(elementStr, printFloat, elemSize,
|
||||
reinterpret_cast<const uint32_t*>(&t[k + e * elemSize]));
|
||||
}
|
||||
i += (amd::alignUp(info.arguments_[j], sizeof(uint32_t))) / sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos != std::string::npos) {
|
||||
fmt = str.substr(pos, str.size() - pos);
|
||||
outputArgument(sepStr, false, ConstStr, reinterpret_cast<const uint32_t*>(fmt.data()));
|
||||
}
|
||||
}
|
||||
|
||||
bool PrintfDbg::clearWorkitems(VirtualGPU& gpu, size_t idxStart, size_t number) const {
|
||||
// Go through all locations for every thread and copy 1
|
||||
for (uint i = idxStart; i < idxStart + number; ++i) {
|
||||
amd::Coord3D dst(i * wiDbgSize(), 0, 0);
|
||||
amd::Coord3D size(sizeof(uint32_t), 0, 0);
|
||||
|
||||
// Copy 1 into the corresponding location in the debug buffer
|
||||
if (!initCntValue_.partialMemCopyTo(gpu, amd::Coord3D(0, 0, 0), dst, size, *dbgBuffer_)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t* PrintfDbg::mapWorkitem(VirtualGPU& gpu, size_t idx, bool* realloc) {
|
||||
uint32_t wiSize = 0;
|
||||
amd::Coord3D src(idx * wiDbgSize(), 0, 0);
|
||||
xferBufRead_ = &(dev().xferRead().acquire());
|
||||
|
||||
// Copy workitem size from the corresponding location in the debug buffer
|
||||
if (!dbgBuffer_->partialMemCopyTo(gpu, src, amd::Coord3D(0, 0, 0),
|
||||
amd::Coord3D(sizeof(uint32_t), 0, 0), *xferBufRead_)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get memory pointer to the satged buffer
|
||||
uint32_t* workitem = reinterpret_cast<uint32_t*>(xferBufRead_->map(&gpu));
|
||||
if (NULL == workitem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Copy size value
|
||||
wiSize = *workitem;
|
||||
xferBufRead_->unmap(&gpu);
|
||||
|
||||
// Check if the cuurent workitem almost reached the size limit
|
||||
if ((wiDbgSize() - static_cast<size_t>(wiSize)) < 3) {
|
||||
*realloc = true;
|
||||
}
|
||||
|
||||
// If the current workitem had any output then get the data
|
||||
if ((wiSize > 1) && (wiSize <= wiDbgSize())) {
|
||||
amd::Coord3D size(wiSize * sizeof(uint32_t), 0, 0);
|
||||
|
||||
// Copy the current workitem output data to the staged buffer
|
||||
if (!dbgBuffer_->partialMemCopyTo(gpu, src, amd::Coord3D(0, 0, 0), size, *xferBufRead_) ||
|
||||
// Clear the write pointer back to index 1 for the current workitem
|
||||
!clearWorkitems(gpu, idx, 1)) {
|
||||
LogError("Reading the workitem data failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get a pointer to the workitem data
|
||||
uint32_t* workitem = reinterpret_cast<uint32_t*>(xferBufRead_->map(&gpu));
|
||||
|
||||
return workitem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PrintfDbg::unmapWorkitem(VirtualGPU& gpu, const uint32_t* workitemData) const {
|
||||
if (NULL != workitemData) {
|
||||
xferBufRead_->unmap(&gpu);
|
||||
}
|
||||
|
||||
dev().xferRead().release(gpu, *xferBufRead_);
|
||||
}
|
||||
|
||||
bool PrintfDbgHSA::init(VirtualGPU& gpu, bool printfEnabled) {
|
||||
// Set up debug output buffer (if printf active)
|
||||
if (printfEnabled) {
|
||||
if (!allocate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The first two DWORDs in the printf buffer are as follows:
|
||||
// First DWORD = Offset to where next information is to
|
||||
// be written, initialized to 0
|
||||
// Second DWORD = Number of bytes available for printf data
|
||||
// = buffer size – 2*sizeof(uint32_t)
|
||||
const uint8_t initSize = 2 * sizeof(uint32_t);
|
||||
uint8_t sysMem[initSize];
|
||||
memset(sysMem, 0, initSize);
|
||||
uint32_t dbgBufferSize = dbgBuffer_->size() - initSize;
|
||||
memcpy(&sysMem[4], &dbgBufferSize, sizeof(dbgBufferSize));
|
||||
|
||||
// Copy offset and number of bytes available for printf data
|
||||
// into the corresponding location in the debug buffer
|
||||
dbgBuffer_->writeRawData(gpu, initSize, sysMem, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrintfDbgHSA::output(VirtualGPU& gpu, bool printfEnabled,
|
||||
const std::vector<device::PrintfInfo>& printfInfo) {
|
||||
if (printfEnabled) {
|
||||
uint32_t offsetSize = 0;
|
||||
xferBufRead_ = &(dev().xferRead().acquire());
|
||||
|
||||
// Copy offset from the first DWORD in the debug buffer
|
||||
if (!dbgBuffer_->partialMemCopyTo(gpu, amd::Coord3D(0, 0, 0), amd::Coord3D(0, 0, 0),
|
||||
amd::Coord3D(sizeof(uint32_t), 0, 0), *xferBufRead_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get memory pointer to the satged buffer
|
||||
uint32_t* dbgBufferPtr = reinterpret_cast<uint32_t*>(xferBufRead_->map(&gpu));
|
||||
if (NULL == dbgBufferPtr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
offsetSize = *dbgBufferPtr;
|
||||
xferBufRead_->unmap(&gpu);
|
||||
|
||||
if (offsetSize == 0) {
|
||||
LogInfo("The printf buffer is empty!");
|
||||
dev().xferRead().release(gpu, *xferBufRead_);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t bufSize = dev().xferRead().bufSize();
|
||||
size_t copySize = offsetSize;
|
||||
while (copySize != 0) {
|
||||
// Copy the buffer data (i.e., the printfID followed by the
|
||||
// argument data for each printf call in th kernel) to the staged buffer
|
||||
if (!dbgBuffer_->partialMemCopyTo(
|
||||
gpu, amd::Coord3D(2 * sizeof(uint32_t) + offsetSize - copySize, 0, 0),
|
||||
amd::Coord3D(0, 0, 0), std::min(copySize, bufSize), *xferBufRead_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a pointer to the buffer data
|
||||
dbgBufferPtr = reinterpret_cast<uint32_t*>(xferBufRead_->map(&gpu));
|
||||
if (NULL == dbgBufferPtr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint sb = 0;
|
||||
uint sbt = 0;
|
||||
|
||||
// parse the debug buffer
|
||||
while (sbt < copySize) {
|
||||
if (*dbgBufferPtr >= printfInfo.size()) {
|
||||
LogError("Couldn't find the reported PrintfID!");
|
||||
return false;
|
||||
}
|
||||
const device::PrintfInfo& info = printfInfo[(*dbgBufferPtr)];
|
||||
sb += sizeof(uint32_t);
|
||||
for (const auto& it : info.arguments_) {
|
||||
sb += it;
|
||||
}
|
||||
|
||||
if (sbt + sb > bufSize) {
|
||||
break; // Need new portion of data in staging buffer
|
||||
}
|
||||
|
||||
size_t idx = 1;
|
||||
// There's something in the debug buffer
|
||||
outputDbgBuffer(info, dbgBufferPtr, idx);
|
||||
|
||||
sbt += sb;
|
||||
dbgBufferPtr += sb / sizeof(uint32_t);
|
||||
sb = 0;
|
||||
}
|
||||
|
||||
copySize -= sbt;
|
||||
xferBufRead_->unmap(&gpu);
|
||||
}
|
||||
|
||||
dev().xferRead().release(gpu, *xferBufRead_);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,183 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUPRINTFDBG_HPP_
|
||||
#define GPUPRINTFDBG_HPP_
|
||||
|
||||
#include "device/gpu/gpumemory.hpp"
|
||||
|
||||
/*! \addtogroup GPU GPU Device Implementation
|
||||
* @{
|
||||
*/
|
||||
#ifndef isinf
|
||||
#ifdef _MSC_VER
|
||||
#define isinf(X) (!_finite(X) && !_isnan(X))
|
||||
#endif //_MSC_VER
|
||||
#endif // isinf
|
||||
|
||||
#ifndef isnan
|
||||
#ifdef _MSC_VER
|
||||
#define isnan(X) (_isnan(X))
|
||||
#endif //_MSC_VER
|
||||
#endif // isnan
|
||||
|
||||
#ifndef copysign
|
||||
#ifdef _MSC_VER
|
||||
#define copysign(X, Y) (_copysign(X, Y))
|
||||
#endif //_MSC_VER
|
||||
#endif // copysign
|
||||
|
||||
//! GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
class Kernel;
|
||||
class VirtualGPU;
|
||||
class Memory;
|
||||
|
||||
class PrintfDbg : public amd::HeapObject {
|
||||
public:
|
||||
//! Debug buffer size per workitem
|
||||
static constexpr uint WorkitemDebugSize = 4096;
|
||||
|
||||
//! Default constructor
|
||||
PrintfDbg(Device& device, FILE* file = NULL);
|
||||
|
||||
//! Destructor
|
||||
~PrintfDbg();
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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<device::PrintfInfo>& printfInfo //!< printf info
|
||||
);
|
||||
|
||||
//! Returns the debug buffer offset
|
||||
uint64_t bufOffset() const;
|
||||
|
||||
//! Debug buffer size per workitem
|
||||
size_t wiDbgSize() const { return wiDbgSize_; }
|
||||
|
||||
//! 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
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! Displays the PrintfDbg
|
||||
void outputDbgBuffer(const device::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&);
|
||||
|
||||
//! 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
|
||||
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;
|
||||
|
||||
size_t wiDbgSize_; //!< Workitem debug size
|
||||
Memory initCntValue_; //!< Initialized count value
|
||||
};
|
||||
class PrintfDbgHSA : public PrintfDbg {
|
||||
public:
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! Prints the kernel's debug informaiton from the buffer
|
||||
bool output(VirtualGPU& gpu, //!< Virtual GPU object
|
||||
bool printfEnabled, //!< checks for printf
|
||||
const std::vector<device::PrintfInfo>& printfInfo //!< printf info
|
||||
);
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
PrintfDbgHSA(const PrintfDbgHSA&);
|
||||
|
||||
//! Disable assignment
|
||||
PrintfDbgHSA& operator=(const PrintfDbgHSA&);
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUPRINTFDBG_HPP_*/
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,535 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUPROGRAM_HPP_
|
||||
#define GPUPROGRAM_HPP_
|
||||
|
||||
#include "device/gpu/gpukernel.hpp"
|
||||
#include "device/gpu/gpubinary.hpp"
|
||||
#include "amd_hsa_loader.hpp"
|
||||
|
||||
namespace amd {
|
||||
namespace option {
|
||||
class Options;
|
||||
} // option
|
||||
namespace hsa {
|
||||
namespace loader {
|
||||
class Loader;
|
||||
class Executable;
|
||||
class Context;
|
||||
} // loader
|
||||
} // hsa
|
||||
} // amd
|
||||
|
||||
//! \namespace gpu GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
/*! \addtogroup GPU GPU Device Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! \struct ILFunc for the opencl program processing
|
||||
struct ILFunc : public amd::HeapObject {
|
||||
public:
|
||||
//! \struct CodeRange for the code ranges
|
||||
struct SourceRange : public amd::EmbeddedObject {
|
||||
size_t begin_; //!< start code position
|
||||
size_t end_; //!< end code position
|
||||
};
|
||||
|
||||
//! \enum IL function state
|
||||
enum State {
|
||||
Unknown = 0x00000000, //! unknown function
|
||||
Regular = 0x00000001, //! regular function from the program
|
||||
Kernel = 0x00000002 //! kernel function from the program
|
||||
};
|
||||
|
||||
//! Default constructor
|
||||
ILFunc()
|
||||
: name_(""),
|
||||
index_(0),
|
||||
state_(Unknown),
|
||||
privateSize_(0),
|
||||
localSize_(0),
|
||||
hwPrivateSize_(0),
|
||||
hwLocalSize_(0),
|
||||
flags_(0),
|
||||
totalHwPrivateSize_(-1) {
|
||||
code_.begin_ = code_.end_ = 0;
|
||||
metadata_.begin_ = metadata_.end_ = 0;
|
||||
}
|
||||
|
||||
//! Copy constructor
|
||||
ILFunc(const ILFunc& func) { *this = func; }
|
||||
|
||||
//! Destructor
|
||||
~ILFunc() {}
|
||||
|
||||
//! Overloads operator=
|
||||
ILFunc& operator=(const ILFunc& func) {
|
||||
name_ = func.name_;
|
||||
index_ = func.index_;
|
||||
code_ = func.code_;
|
||||
metadata_ = func.metadata_;
|
||||
state_ = func.state_;
|
||||
privateSize_ = func.privateSize_;
|
||||
localSize_ = func.localSize_;
|
||||
hwPrivateSize_ = func.hwPrivateSize_;
|
||||
hwLocalSize_ = func.hwLocalSize_;
|
||||
flags_ = func.flags_;
|
||||
totalHwPrivateSize_ = func.totalHwPrivateSize_;
|
||||
|
||||
// Note: we don't copy calls_ and macros_
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string name_; //!< kernel's name
|
||||
uint index_; //!< kernel's index
|
||||
SourceRange code_; //!< the entire function range in the source
|
||||
SourceRange metadata_; //!< the metadata range
|
||||
State state_; //!< the function is real, and not intrinsic
|
||||
uint privateSize_; //!< private ring allocation by the function
|
||||
uint localSize_; //!< local ring allocation by the function
|
||||
uint hwPrivateSize_; //!< HW private ring allocation by the function
|
||||
uint hwLocalSize_; //!< HW local ring allocation by the function
|
||||
uint flags_; //!< The IL func flags/properties
|
||||
long long totalHwPrivateSize_; //!< total HW private usage including called functions
|
||||
std::vector<ILFunc*> calls_; //! Functions called from the current
|
||||
std::vector<uint> macros_; //! Macros, used in the IL function
|
||||
|
||||
uint totalHwPrivateUsage(); //!< total HW private usage including called functions
|
||||
};
|
||||
|
||||
//! \class empty program
|
||||
class NullProgram : public device::Program {
|
||||
friend class ClBinary;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
NullProgram(NullDevice& nullDev, amd::Program& owner)
|
||||
: device::Program(nullDev, owner), patch_(0) {}
|
||||
|
||||
//! Default destructor
|
||||
~NullProgram();
|
||||
|
||||
// Initialize Binary for GPU
|
||||
virtual bool initClBinary();
|
||||
|
||||
//! Returns global constant buffers
|
||||
const std::vector<uint>& glbCb() const { return glbCb_; }
|
||||
|
||||
protected:
|
||||
/*! \brief Compiles GPU CL program to LLVM binary (compiler frontend)
|
||||
*
|
||||
* \return True if we successfully compiled a GPU program
|
||||
*/
|
||||
virtual bool compileImpl(const std::string& sourceCode, //!< the program's source code
|
||||
const std::vector<const std::string*>& headers, //!< header souce codes
|
||||
const char** headerIncludeNames, //!< include names of headers
|
||||
amd::option::Options* options //!< compile options's object
|
||||
);
|
||||
|
||||
/*! \brief Compiles LLVM binary to IL code (compiler backend: link+opt+codegen)
|
||||
*
|
||||
* \return The build error code
|
||||
*/
|
||||
int compileBinaryToIL(amd::option::Options* options //!< options for compilation
|
||||
);
|
||||
|
||||
/*! \brief Links the compiled IL program with HW
|
||||
*
|
||||
* \return True if we successefully linked a GPU program
|
||||
*/
|
||||
virtual bool linkImpl(amd::option::Options* options = NULL //!< options object
|
||||
);
|
||||
virtual bool linkImpl(const std::vector<device::Program*>& inputPrograms,
|
||||
amd::option::Options* options = NULL, //!< options object
|
||||
bool createLibrary = false);
|
||||
|
||||
virtual bool createBinary(amd::option::Options* options);
|
||||
|
||||
|
||||
/*! \brief Parses the GPU program and finds all available kernels
|
||||
*
|
||||
* \return True if we successfully parsed the GPU program
|
||||
*/
|
||||
bool parseKernels(const std::string& source //! the program's source code
|
||||
);
|
||||
|
||||
/*! \brief Parse all functions in the program
|
||||
*
|
||||
* \return True if we successfully parsed all functions
|
||||
*/
|
||||
bool parseAllILFuncs(const std::string& source //! the program's source code
|
||||
);
|
||||
|
||||
/*! \brief Parse a function's metadata given as source[posBegin:posEnd-1]
|
||||
*
|
||||
* \return True if we successfully parsed the given metadata
|
||||
*/
|
||||
bool parseFuncMetadata(const std::string& source, //! string that contains metadata
|
||||
size_t posBegin, //! begin of metadata in 'source'
|
||||
size_t posEnd //! end of metadata in 'source'
|
||||
);
|
||||
|
||||
/*! \brief Finds functions with the given start and end string in the
|
||||
* program
|
||||
*
|
||||
* \return True if we successfully found all functions
|
||||
*/
|
||||
bool findILFuncs(const std::string& source, //! the program's source code
|
||||
const std::string& func_start, //! the start string of a function
|
||||
const std::string& func_end, //! the end string of a function
|
||||
size_t& lastFuncPos //! pos to the end of the last func in 'source'
|
||||
);
|
||||
|
||||
|
||||
/*! \brief Finds all functions in the program
|
||||
*
|
||||
* \return True if we successefully found all functions
|
||||
*/
|
||||
bool findAllILFuncs(const std::string& source, //! the program's source code
|
||||
size_t& lastFuncPos //! pos to the end of the last func in 'source'
|
||||
);
|
||||
|
||||
/*! \brief Finds function, corresponded to the provided unique index
|
||||
*
|
||||
* \return Pointer to the ILFunc structure
|
||||
*/
|
||||
ILFunc* findILFunc(uint index //! the function unique index
|
||||
);
|
||||
|
||||
//! Destroys all objects, associated with the IL functions
|
||||
void freeAllILFuncs();
|
||||
|
||||
/*! \brief Finds if a provided function is called from the base function
|
||||
*
|
||||
* \return True if a function is used from the base one
|
||||
*/
|
||||
bool isCalled(const ILFunc* base, //!< The base function
|
||||
const ILFunc* func //!< Function to check for usage
|
||||
);
|
||||
|
||||
//! Patches the "main" function with the call to the current kernel
|
||||
void patchMain(std::string& kernel, //! The current kernel's code for compilation
|
||||
uint index //! Index of the current kernel in the program
|
||||
);
|
||||
|
||||
//! Adds the IL function object into the list of functions
|
||||
void addFunc(ILFunc* func) { funcs_.push_back(func); }
|
||||
|
||||
//! Empty implementation, since we don't have real HW
|
||||
virtual bool allocGlobalData(const void* globalData, //!< Pointer to the global data
|
||||
size_t dataSize, //!< The global data size
|
||||
uint index //!< Index for the global data store (0 - global heap)
|
||||
) {
|
||||
glbCb_.push_back(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Load binary for offline device.
|
||||
virtual bool loadBinary(bool* hasRecompiled);
|
||||
|
||||
//! Create NullKernel for compiling to isa.
|
||||
virtual NullKernel* createKernel(const std::string& name, //!< The kernel's name
|
||||
const Kernel::InitData* initData, //!< Initialization data
|
||||
const std::string& code, //!< IL source code
|
||||
const std::string& metadata, //!< the kernel metadata structure
|
||||
bool* created, //!< True if the object was created
|
||||
const void* binaryCode = NULL, //!< binary machine code for CAL
|
||||
size_t binarySize = 0 //!< the machine code size
|
||||
);
|
||||
|
||||
ClBinary* clBinary() { return static_cast<ClBinary*>(device::Program::clBinary()); }
|
||||
const ClBinary* clBinary() const {
|
||||
return static_cast<const ClBinary*>(device::Program::clBinary());
|
||||
}
|
||||
|
||||
/*! Get all per-kernel IL from programIL, where programIL is the IL for the
|
||||
* whole compilation unit.
|
||||
*/
|
||||
bool getAllKernelILs(std::unordered_map<std::string, std::string>& allKernelILs, std::string& programIL,
|
||||
const char* ilKernelName);
|
||||
|
||||
protected:
|
||||
std::vector<device::PrintfInfo> printf_; //!< Format strings for GPU printf support
|
||||
std::vector<uint> glbCb_; //!< Global constant buffers
|
||||
|
||||
virtual const aclTargetInfo& info();
|
||||
|
||||
virtual bool saveBinaryAndSetType(type_t type) { return true; }
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
NullProgram(const NullProgram&);
|
||||
|
||||
//! Disable operator=
|
||||
NullProgram& operator=(const NullProgram&);
|
||||
|
||||
//! Initializes the global data store
|
||||
bool initGlobalData(const std::string& source, //!< the program's source code
|
||||
size_t start //!< start position for the global data search
|
||||
);
|
||||
|
||||
//! Return a typecasted GPU device
|
||||
gpu::NullDevice& gpuNullDevice() {
|
||||
return const_cast<gpu::NullDevice&>(static_cast<const gpu::NullDevice&>(device()));
|
||||
}
|
||||
|
||||
size_t patch_; //!< Patch call position in the source code.
|
||||
std::vector<ILFunc*> funcs_; //!< list of all functions.
|
||||
|
||||
std::string ilProgram_; //!< IL program after compilation
|
||||
};
|
||||
|
||||
//! \class GPU program
|
||||
class Program : public NullProgram {
|
||||
public:
|
||||
//! GPU program constructor
|
||||
Program(Device& gpuDev, amd::Program& owner) : NullProgram(gpuDev, owner), glbData_(NULL) {}
|
||||
|
||||
//! GPU program destructor
|
||||
~Program();
|
||||
|
||||
//! Get the global data store for this program
|
||||
gpu::Memory* glbData() const { return glbData_; }
|
||||
|
||||
//! Returns TRUE if we successfully allocated the global data store
|
||||
//! in video memory
|
||||
bool allocGlobalData(const void* globalData, //!< Pointer to the global data
|
||||
size_t dataSize, //!< The global data size
|
||||
uint index //!< Index for the global data store (0 - global heap)
|
||||
);
|
||||
|
||||
//! Returns TRUE if we could
|
||||
virtual bool loadBinary(bool* hasRecompiled);
|
||||
|
||||
//! Creates the GPU kernel (return base type)
|
||||
virtual NullKernel* createKernel(const std::string& name, //!< The kernel's name
|
||||
const Kernel::InitData* initData, //!< Initialization data
|
||||
const std::string& code, //!< IL source code
|
||||
const std::string& metadata, //!< the kernel metadata structure
|
||||
bool* created, //!< True if the object was created
|
||||
const void* binaryCode = NULL, //!< binary machine code for CAL
|
||||
size_t binarySize = 0 //!< the machine code size
|
||||
);
|
||||
|
||||
typedef std::unordered_map<uint, gpu::Memory*> HwConstBuffers;
|
||||
|
||||
//! Global HW constant buffers
|
||||
const HwConstBuffers& glbHwCb() const { return constBufs_; }
|
||||
|
||||
//! Returns pritnf info array
|
||||
const std::vector<device::PrintfInfo>& printfInfo() const { return printf_; }
|
||||
|
||||
protected:
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Program(const Program&);
|
||||
|
||||
//! Disable operator=
|
||||
Program& operator=(const Program&);
|
||||
|
||||
//! Return a typecasted GPU device
|
||||
gpu::Device& gpuDevice() {
|
||||
assert(!isNull());
|
||||
return const_cast<gpu::Device&>(static_cast<const gpu::Device&>(device()));
|
||||
}
|
||||
|
||||
HwConstBuffers constBufs_; //!< Constant buffers for the global store
|
||||
gpu::Memory* glbData_; //!< Global data store
|
||||
};
|
||||
|
||||
using namespace amd::hsa::loader;
|
||||
class HSAILProgram;
|
||||
|
||||
class ORCAHSALoaderContext final : public Context {
|
||||
public:
|
||||
ORCAHSALoaderContext(HSAILProgram* program) : program_(program) {}
|
||||
|
||||
virtual ~ORCAHSALoaderContext() {}
|
||||
|
||||
hsa_isa_t IsaFromName(const char* name) override;
|
||||
|
||||
bool IsaSupportedByAgent(hsa_agent_t agent, hsa_isa_t isa) override;
|
||||
|
||||
void* SegmentAlloc(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, size_t size, size_t align,
|
||||
bool zero) override;
|
||||
|
||||
bool SegmentCopy(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* dst, size_t offset,
|
||||
const void* src, size_t size) override;
|
||||
|
||||
void SegmentFree(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg,
|
||||
size_t size = 0) override;
|
||||
|
||||
void* SegmentAddress(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg,
|
||||
size_t offset) override;
|
||||
|
||||
void* SegmentHostAddress(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg,
|
||||
size_t offset) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SegmentFreeze(amdgpu_hsa_elf_segment_t segment, hsa_agent_t agent, void* seg,
|
||||
size_t size) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ImageExtensionSupported() override { return false; }
|
||||
|
||||
hsa_status_t ImageCreate(hsa_agent_t agent, hsa_access_permission_t image_permission,
|
||||
const hsa_ext_image_descriptor_t* image_descriptor,
|
||||
const void* image_data, hsa_ext_image_t* image_handle) override {
|
||||
// not supported
|
||||
assert(false);
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
|
||||
hsa_status_t ImageDestroy(hsa_agent_t agent, hsa_ext_image_t image_handle) override {
|
||||
// not supported
|
||||
assert(false);
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
|
||||
hsa_status_t SamplerCreate(hsa_agent_t agent,
|
||||
const hsa_ext_sampler_descriptor_t* sampler_descriptor,
|
||||
hsa_ext_sampler_t* sampler_handle) override;
|
||||
|
||||
//! All samplers are owned by HSAILProgram and are deleted in its destructor.
|
||||
hsa_status_t SamplerDestroy(hsa_agent_t agent, hsa_ext_sampler_t sampler_handle) override;
|
||||
|
||||
private:
|
||||
void* AgentGlobalAlloc(hsa_agent_t agent, size_t size, size_t align, bool zero) {
|
||||
return GpuMemAlloc(size, align, zero);
|
||||
}
|
||||
|
||||
bool AgentGlobalCopy(void* dst, size_t offset, const void* src, size_t size) {
|
||||
return GpuMemCopy(dst, offset, src, size);
|
||||
}
|
||||
|
||||
void AgentGlobalFree(void* ptr, size_t size) { GpuMemFree(ptr, size); }
|
||||
|
||||
void* KernelCodeAlloc(hsa_agent_t agent, size_t size, size_t align, bool zero) {
|
||||
return CpuMemAlloc(size, align, zero);
|
||||
}
|
||||
|
||||
bool KernelCodeCopy(void* dst, size_t offset, const void* src, size_t size) {
|
||||
return CpuMemCopy(dst, offset, src, size);
|
||||
}
|
||||
|
||||
void KernelCodeFree(void* ptr, size_t size) { CpuMemFree(ptr, size); }
|
||||
|
||||
void* CpuMemAlloc(size_t size, size_t align, bool zero);
|
||||
|
||||
bool CpuMemCopy(void* dst, size_t offset, const void* src, size_t size);
|
||||
|
||||
void CpuMemFree(void* ptr, size_t size) { amd::Os::alignedFree(ptr); }
|
||||
|
||||
void* GpuMemAlloc(size_t size, size_t align, bool zero);
|
||||
|
||||
bool GpuMemCopy(void* dst, size_t offset, const void* src, size_t size);
|
||||
|
||||
void GpuMemFree(void* ptr, size_t size = 0);
|
||||
|
||||
ORCAHSALoaderContext(const ORCAHSALoaderContext& c);
|
||||
|
||||
ORCAHSALoaderContext& operator=(const ORCAHSALoaderContext& c);
|
||||
|
||||
gpu::HSAILProgram* program_;
|
||||
};
|
||||
|
||||
//! \class HSAIL program
|
||||
class HSAILProgram : public device::Program {
|
||||
friend class ClBinary;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
HSAILProgram(Device& device, amd::Program& owner);
|
||||
HSAILProgram(NullDevice& device, amd::Program& owner);
|
||||
//! Default destructor
|
||||
~HSAILProgram();
|
||||
|
||||
void addGlobalStore(Memory* mem) { globalStores_.push_back(mem); }
|
||||
|
||||
const std::vector<Memory*>& globalStores() const { return globalStores_; }
|
||||
|
||||
//! Return a typecasted GPU device. The device must not be the NullDevice.
|
||||
gpu::Device& gpuDevice() {
|
||||
assert(!isNull());
|
||||
return const_cast<gpu::Device&>(static_cast<const gpu::Device&>(device()));
|
||||
}
|
||||
|
||||
//! Returns GPU kernel table
|
||||
const Memory* kernelTable() const { return kernels_; }
|
||||
|
||||
//! Adds all kernels to the mem handle lists
|
||||
void fillResListWithKernels(std::vector<const Memory*>& memList) const;
|
||||
|
||||
//! Returns the maximum number of scratch regs used in the program
|
||||
uint maxScratchRegs() const { return maxScratchRegs_; }
|
||||
|
||||
//! Add internal static sampler
|
||||
void addSampler(Sampler* sampler) { staticSamplers_.push_back(sampler); }
|
||||
|
||||
//! Returns TRUE if the program contains static samplers
|
||||
bool isStaticSampler() const { return (staticSamplers_.size() != 0); }
|
||||
|
||||
protected:
|
||||
bool saveBinaryAndSetType(type_t type);
|
||||
|
||||
virtual bool linkImpl(amd::option::Options* options);
|
||||
|
||||
virtual bool createBinary(amd::option::Options* options);
|
||||
|
||||
virtual const aclTargetInfo& info();
|
||||
|
||||
private:
|
||||
//! Disable default copy constructor
|
||||
HSAILProgram(const HSAILProgram&);
|
||||
|
||||
//! Disable operator=
|
||||
HSAILProgram& operator=(const HSAILProgram&);
|
||||
|
||||
//! Returns all the options to be appended while passing to the
|
||||
// compiler library
|
||||
std::string hsailOptions();
|
||||
|
||||
//! Allocate kernel table
|
||||
bool allocKernelTable();
|
||||
|
||||
//! Return a typecasted GPU null device.
|
||||
gpu::NullDevice& gpuNullDevice() {
|
||||
return const_cast<gpu::NullDevice&>(static_cast<const gpu::NullDevice&>(device()));
|
||||
}
|
||||
|
||||
void* rawBinary_; //!< Pointer to the raw binary
|
||||
std::vector<Memory*> globalStores_; //!< Global memory for the program
|
||||
Memory* kernels_; //!< Table with kernel object pointers
|
||||
uint
|
||||
maxScratchRegs_; //!< Maximum number of scratch regs used in the program by individual kernel
|
||||
std::list<Sampler*> staticSamplers_; //!< List od internal static samplers
|
||||
amd::hsa::loader::Loader* loader_; //!< Loader object
|
||||
amd::hsa::loader::Executable* executable_; //!< Executable for HSA Loader
|
||||
ORCAHSALoaderContext loaderContext_; //!< Context for HSA Loader
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUPROGRAM_HPP_*/
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,501 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPURESOURCE_HPP_
|
||||
#define GPURESOURCE_HPP_
|
||||
|
||||
#include "platform/command.hpp"
|
||||
#include "platform/program.hpp"
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
//! \namespace gpu GPU Resource Implementation
|
||||
namespace gpu {
|
||||
|
||||
class Device;
|
||||
class VirtualGPU;
|
||||
|
||||
/*! \addtogroup GPU GPU Resource Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
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_; }
|
||||
|
||||
//! 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
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~GslResourceReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
GslResourceReference(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
|
||||
};
|
||||
|
||||
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 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 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_;
|
||||
};
|
||||
|
||||
#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
|
||||
};
|
||||
#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_;
|
||||
};
|
||||
};
|
||||
|
||||
//! Constructor of 1D Resource object
|
||||
Resource(const Device& gpuDev, //!< GPU device object
|
||||
size_t width, //!< resource width
|
||||
cmSurfFmt format //!< resource format
|
||||
);
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! Destructor of the resource
|
||||
virtual ~Resource();
|
||||
|
||||
/*! \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
|
||||
);
|
||||
|
||||
/*! \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;
|
||||
|
||||
/*! \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 offset in GPU memory for aliases
|
||||
size_t offset() const { return offset_; }
|
||||
|
||||
//! Returns the offset in GPU heap
|
||||
uint64_t hbOffset() const { return hbOffset_; }
|
||||
|
||||
//! Returns the pinned memory offset
|
||||
uint64_t pinOffset() const { return pinOffset_; }
|
||||
|
||||
//! Returns the size in GPU heap
|
||||
uint64_t hbSize() const { return hbSize_; }
|
||||
|
||||
//! Returns the GPU device that owns this resource
|
||||
const Device& dev() const { return gpuDevice_; }
|
||||
|
||||
//! Returns the CAL descriptor for resource
|
||||
const CalResourceDesc* cal() const { return &cal_; }
|
||||
|
||||
//! Returns the CAL resource handle
|
||||
gslMemObject gslResource() const { return gslRef_->gslResource(); }
|
||||
|
||||
//! Returns global memory offset
|
||||
uint64_t vmAddress() const { return gslResource()->getSurfaceAddress(); }
|
||||
|
||||
//! Returns global memory offset
|
||||
bool mipMapped() const { return (cal()->mipLevels_ > 1) ? true : false; }
|
||||
|
||||
//! Checks if persistent memory can have a direct map
|
||||
bool isPersistentDirectMap() 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
|
||||
);
|
||||
|
||||
//! Unlocks the resource if it was locked
|
||||
void unmap(VirtualGPU* gpu //!< Virtual GPU device object
|
||||
);
|
||||
|
||||
//! Marks the resource as busy
|
||||
void setBusy(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GpuEvent calEvent //!< CAL event
|
||||
) const;
|
||||
|
||||
//! Wait for the resource
|
||||
void wait(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
bool waitOnBusyEngine = false //!< Wait only if engine has changed
|
||||
) const;
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! Warms up the rename list for this resource
|
||||
void warmUpRenames(VirtualGPU& gpu);
|
||||
|
||||
//! Gets the resource element size
|
||||
size_t elementSize() const { return elementSize_; }
|
||||
|
||||
//! Get the mapped address of this resource
|
||||
address data() const { return reinterpret_cast<address>(address_); }
|
||||
|
||||
//! 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();
|
||||
|
||||
//! Return memory type
|
||||
MemoryType memoryType() const { return cal_.type_; }
|
||||
|
||||
//! Retunrs true if memory type matches specified
|
||||
bool isMemoryType(MemoryType memType) const;
|
||||
|
||||
//! Returns TRUE if resource was allocated as cacheable
|
||||
bool isCacheable() const { return (isMemoryType(Remote) || isMemoryType(Pinned)) ? true : false; }
|
||||
|
||||
bool gslGLAcquire();
|
||||
bool gslGLRelease();
|
||||
|
||||
//! Returns HW state for the resource (used for images only)
|
||||
const void* hwState() const { return hwState_; }
|
||||
|
||||
//! Returns CPU HW SRD for the resource (used for images only)
|
||||
uint64_t hwSrd() const { return hwSrd_; }
|
||||
|
||||
protected:
|
||||
size_t elementSize_; //!< Size of a single element in bytes
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
Resource(const Resource&);
|
||||
|
||||
//! Disable operator=
|
||||
Resource& operator=(const Resource&);
|
||||
|
||||
typedef std::vector<GslResourceReference*> RenameList;
|
||||
|
||||
//! Rename current resource
|
||||
bool rename(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
bool force = false //!< Force renaming
|
||||
);
|
||||
|
||||
//! Sets the rename as active
|
||||
void setActiveRename(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GslResourceReference* rename //!< new active rename
|
||||
);
|
||||
|
||||
//! Gets the active rename
|
||||
bool getActiveRename(VirtualGPU& gpu, //!< Virtual GPU device object
|
||||
GslResourceReference** rename //!< Saved active rename
|
||||
);
|
||||
|
||||
/*! \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
|
||||
);
|
||||
|
||||
//! Unlocks the resource with layers if it was locked
|
||||
void unmapLayers(VirtualGPU* gpu //!< Virtual GPU device object
|
||||
);
|
||||
|
||||
//! 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;
|
||||
|
||||
//! Uses GSL to unmap a resource
|
||||
void gslUnmap(gslMemObject resource //!< GSL memory object
|
||||
) const;
|
||||
|
||||
//! Fress all GSL resources associated with OCL resource
|
||||
void gslFree() const;
|
||||
|
||||
const Device& gpuDevice_; //!< GPU device
|
||||
CalResourceDesc cal_; //!< CAL descriptor for this resource
|
||||
std::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
|
||||
};
|
||||
|
||||
class ResourceCache : public amd::HeapObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
ResourceCache(size_t cacheSizeLimit)
|
||||
: lockCacheOps_("CAL resource cache", true)
|
||||
, cacheSize_(0)
|
||||
, lclCacheSize_(0)
|
||||
, cacheSizeLimit_(cacheSizeLimit) {}
|
||||
|
||||
//! 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
|
||||
);
|
||||
|
||||
//! 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);
|
||||
|
||||
//! Returns the size of all memory, stored in the cache
|
||||
size_t cacheSize() const { return cacheSize_; }
|
||||
|
||||
//! Returns the size of local memory, stored in the cache
|
||||
size_t lclCacheSize() const { return lclCacheSize_; }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
ResourceCache(const ResourceCache&);
|
||||
|
||||
//! Disable operator=
|
||||
ResourceCache& operator=(const ResourceCache&);
|
||||
|
||||
//! Gets resource size in bytes
|
||||
size_t getResourceSize(Resource::CalResourceDesc* desc);
|
||||
|
||||
//! Removes one last entry from the cache
|
||||
void removeLast();
|
||||
|
||||
amd::Monitor lockCacheOps_; //!< Lock to serialise cache access
|
||||
|
||||
size_t cacheSize_; //!< Current cache size in bytes
|
||||
size_t lclCacheSize_; //!< Local memory stored in the cache
|
||||
size_t cacheSizeLimit_; //!< Cache size limit in bytes
|
||||
|
||||
//! CAL resource cache
|
||||
std::list<std::pair<Resource::CalResourceDesc*, GslResourceReference*> > resCache_;
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPURESOURCE_HPP_*/
|
||||
@@ -1,96 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUSCHED_HPP_
|
||||
#define GPUSCHED_HPP_
|
||||
|
||||
#include "hsa.h"
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
|
||||
#endif
|
||||
@@ -1,310 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
namespace gpu {
|
||||
|
||||
#define SCHEDULER_KERNEL(...) #__VA_ARGS__
|
||||
|
||||
const char* SchedulerSourceCode = SCHEDULER_KERNEL(
|
||||
\n
|
||||
extern void __amd_scheduler(__global void *, __global void *, uint);
|
||||
\n
|
||||
typedef struct _HsaAqlDispatchPacket {
|
||||
uint mix;
|
||||
ushort workgroup_size[3];
|
||||
ushort reserved2;
|
||||
uint grid_size[3];
|
||||
uint private_segment_size_bytes;
|
||||
uint group_segment_size_bytes;
|
||||
ulong kernel_object_address;
|
||||
ulong kernel_arg_address;
|
||||
ulong reserved3;
|
||||
ulong completion_signal;
|
||||
} HsaAqlDispatchPacket;
|
||||
\n
|
||||
// This is an OpenCLized hsa_control_directives_t
|
||||
typedef struct _AmdControlDirectives {
|
||||
ulong enabled_control_directives;
|
||||
ushort enable_break_exceptions;
|
||||
ushort enable_detect_exceptions;
|
||||
uint max_dynamic_group_size;
|
||||
ulong max_flat_grid_size;
|
||||
uint max_flat_workgroup_size;
|
||||
uchar required_dim;
|
||||
uchar reserved1[3];
|
||||
ulong required_grid_size[3];
|
||||
uint required_workgroup_size[3];
|
||||
uchar reserved2[60];
|
||||
} AmdControlDirectives;
|
||||
\n
|
||||
// This is an OpenCLized amd_kernel_code_t
|
||||
typedef struct _AmdKernelCode {
|
||||
uint amd_kernel_code_version_major;
|
||||
uint amd_kernel_code_version_minor;
|
||||
ushort amd_machine_kind;
|
||||
ushort amd_machine_version_major;
|
||||
ushort amd_machine_version_minor;
|
||||
ushort amd_machine_version_stepping;
|
||||
long kernel_code_entry_byte_offset;
|
||||
long kernel_code_prefetch_byte_offset;
|
||||
ulong kernel_code_prefetch_byte_size;
|
||||
ulong max_scratch_backing_memory_byte_size;
|
||||
uint compute_pgm_rsrc1;
|
||||
uint compute_pgm_rsrc2;
|
||||
uint kernel_code_properties;
|
||||
uint workitem_private_segment_byte_size;
|
||||
uint workgroup_group_segment_byte_size;
|
||||
uint gds_segment_byte_size;
|
||||
ulong kernarg_segment_byte_size;
|
||||
uint workgroup_fbarrier_count;
|
||||
ushort wavefront_sgpr_count;
|
||||
ushort workitem_vgpr_count;
|
||||
ushort reserved_vgpr_first;
|
||||
ushort reserved_vgpr_count;
|
||||
ushort reserved_sgpr_first;
|
||||
ushort reserved_sgpr_count;
|
||||
ushort debug_wavefront_private_segment_offset_sgpr;
|
||||
ushort debug_private_segment_buffer_sgpr;
|
||||
uchar kernarg_segment_alignment;
|
||||
uchar group_segment_alignment;
|
||||
uchar private_segment_alignment;
|
||||
uchar wavefront_size;
|
||||
int call_convention;
|
||||
uchar reserved1[12];
|
||||
ulong runtime_loader_kernel_symbol;
|
||||
AmdControlDirectives control_directives;
|
||||
} AmdKernelCode;
|
||||
\n
|
||||
typedef struct _HwDispatchHeader {
|
||||
uint writeData0; // CP WRITE_DATA write to rewind for memory
|
||||
uint writeData1;
|
||||
uint writeData2;
|
||||
uint writeData3;
|
||||
uint rewind; // REWIND execution
|
||||
uint startExe; // valid bit
|
||||
uint condExe0; // 0xC0032200 -- TYPE 3, COND_EXEC
|
||||
uint condExe1; // 0x00000204 ----
|
||||
uint condExe2; // 0x00000000 ----
|
||||
uint condExe3; // 0x00000000 ----
|
||||
uint condExe4; // 0x00000000 ----
|
||||
} HwDispatchHeader;
|
||||
\n
|
||||
typedef struct _HwDispatch {
|
||||
uint packet0; // 0xC0067602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (6 values)
|
||||
uint offset0; // 0x00000204 ---- OFFSET
|
||||
uint startX; // 0x00000000 ---- COMPUTE_START_X: START = 0x0
|
||||
uint startY; // 0x00000000 ---- COMPUTE_START_Y: START = 0x0
|
||||
uint startZ; // 0x00000000 ---- COMPUTE_START_Z: START = 0x0
|
||||
uint wrkGrpSizeX; // 0x00000000 ---- COMPUTE_NUM_THREAD_X: NUM_THREAD_FULL = 0x0, NUM_THREAD_PARTIAL = 0x0
|
||||
uint wrkGrpSizeY; // 0x00000000 ---- COMPUTE_NUM_THREAD_Y: NUM_THREAD_FULL = 0x0, NUM_THREAD_PARTIAL = 0x0
|
||||
uint wrkGrpSizeZ; // 0x00000000 ---- COMPUTE_NUM_THREAD_Z: NUM_THREAD_FULL = 0x0, NUM_THREAD_PARTIAL = 0x0
|
||||
uint packet1; // 0xC0027602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (2 values)
|
||||
uint offset1; // 0x0000020C ---- OFFSET
|
||||
uint isaLo; // 0x00000000 ---- COMPUTE_PGM_LO: DATA = 0x0
|
||||
uint isaHi; // 0x00000000 ---- COMPUTE_PGM_HI: DATA = 0x0, INST_ATC__CI__VI = 0x0
|
||||
uint packet2; // 0xC0027602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (2 values)
|
||||
uint offset2; // 0x00000212 ---- OFFSET
|
||||
uint resource1; // 0x00000000 ---- COMPUTE_PGM_RSRC1
|
||||
uint resource2; // 0x00000000 ---- COMPUTE_PGM_RSRC2
|
||||
uint packet3; // 0xc0017602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (1 value)
|
||||
uint offset3; // 0x00000215 ---- OFFSET
|
||||
uint pad31; // 0x000003ff ---- COMPUTE_RESOURCE_LIMITS
|
||||
uint packet31; // 0xC0067602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (1 value)
|
||||
uint offset31; // 0x00000218 ---- OFFSET
|
||||
uint ringSize; // 0x00000000 ---- COMPUTE_TMPRING_SIZE: WAVES = 0x0, WAVESIZE = 0x0
|
||||
uint user0; // 0xC0047602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (4 values)
|
||||
uint offsUser0; // 0x00000240 ---- OFFSET
|
||||
uint scratchLo; // 0x00000000 ---- COMPUTE_USER_DATA_0: DATA = 0x0
|
||||
uint scratchHi; // 0x80000000 ---- COMPUTE_USER_DATA_1: DATA = 0x80000000
|
||||
uint scratchSize; // 0x00000000 ---- COMPUTE_USER_DATA_2: DATA = 0x0
|
||||
uint padUser; // 0x00EA7FAC ---- COMPUTE_USER_DATA_3: DATA = 0xEA7FAC
|
||||
uint user1; // 0xC0027602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (2 values)
|
||||
uint offsUser1; // 0x00000244 ---- OFFSET
|
||||
uint aqlPtrLo; // 0x00000000 ---- COMPUTE_USER_DATA_4: DATA = 0x0
|
||||
uint aqlPtrHi; // 0x00000000 ---- COMPUTE_USER_DATA_5: DATA = 0x0
|
||||
uint user2; // 0xC0027602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (2 values)
|
||||
uint offsUser2; // 0x00000246 ---- OFFSET
|
||||
uint hsaQueueLo; // 0x00000000 ---- COMPUTE_USER_DATA_6: DATA = 0x0
|
||||
uint hsaQueueHi; // 0x00000000 ---- COMPUTE_USER_DATA_7: DATA = 0x0
|
||||
uint user3; // 0xC0027602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (2 values)
|
||||
uint offsUser3; // 0x00000246 ---- OFFSET
|
||||
uint argsLo; // 0x00000000 ---- COMPUTE_USER_DATA_8: DATA = 0x0
|
||||
uint argsHi; // 0x00000000 ---- COMPUTE_USER_DATA_9: DATA = 0x0
|
||||
uint copyData; // 0xC0044000 -- TYPE 3, COPY_DATA
|
||||
uint copyDataFlags; // 0x00000405 ---- srcSel 0x5, destSel 0x4, countSel 0x0, wrConfirm 0x0, engineSel 0x0
|
||||
uint scratchAddrLo; // 0x000201C4 ---- srcAddressLo
|
||||
uint scratchAddrHi; // 0x00000000 ---- srcAddressHi
|
||||
uint shPrivateLo; // 0x00002580 ---- dstAddressLo
|
||||
uint shPrivateHi; // 0x00000000 ---- dstAddressHi
|
||||
uint user4; // 0xC0027602 -- TYPE 3, SET_SH_REG, TYPE:COMPUTE (2 values)
|
||||
uint offsUser4; // 0x00000248 ---- OFFSET
|
||||
uint scratchOffs; // 0x00000000 ---- COMPUTE_USER_DATA_10: DATA = 0x0
|
||||
uint privSize; // 0x00000030 ---- COMPUTE_USER_DATA_11: DATA = 0x30
|
||||
uint packet4; // 0xC0031502 -- TYPE 3, DISPATCH_DIRECT, TYPE:COMPUTE
|
||||
uint glbSizeX; // 0x00000000
|
||||
uint glbSizeY; // 0x00000000
|
||||
uint glbSizeZ; // 0x00000000
|
||||
uint padd41; // 0x00000021
|
||||
} HwDispatch;
|
||||
\n
|
||||
static const uint WavefrontSize = 64;
|
||||
static const uint MaxWaveSize = 0x400;
|
||||
static const uint UsrRegOffset = 0x240;
|
||||
static const uint Pm4Nop = 0xC0001002;
|
||||
static const uint Pm4UserRegs = 0xC0007602;
|
||||
static const uint Pm4CopyReg = 0xC0044000;
|
||||
static const uint PrivateSegEna = 0x1;
|
||||
static const uint DispatchEna = 0x2;
|
||||
static const uint QueuePtrEna = 0x4;
|
||||
static const uint KernelArgEna = 0x8;
|
||||
static const uint FlatScratchEna = 0x20;
|
||||
\n
|
||||
uint GetCmdTemplateHeaderSize() { return sizeof(HwDispatchHeader); }
|
||||
\n
|
||||
uint GetCmdTemplateDispatchSize() { return sizeof(HwDispatch); }
|
||||
\n
|
||||
void EmptyCmdTemplateDispatch(ulong cmdBuf)
|
||||
{
|
||||
volatile __global HwDispatch* dispatch = (volatile __global HwDispatch*)cmdBuf;
|
||||
dispatch->glbSizeX = 0;
|
||||
dispatch->glbSizeY = 0;
|
||||
dispatch->glbSizeZ = 0;
|
||||
}
|
||||
\n
|
||||
void RunCmdTemplateDispatch(
|
||||
ulong cmdBuf,
|
||||
__global HsaAqlDispatchPacket* aqlPkt,
|
||||
ulong scratch,
|
||||
ulong hsaQueue,
|
||||
uint scratchSize,
|
||||
uint scratchOffset,
|
||||
uint numMaxWaves,
|
||||
uint useATC)
|
||||
\n
|
||||
{
|
||||
volatile __global HwDispatch* dispatch = (volatile __global HwDispatch*)cmdBuf;
|
||||
uint usrRegCnt = 0;
|
||||
|
||||
// Program workgroup size
|
||||
dispatch->wrkGrpSizeX = aqlPkt->workgroup_size[0];
|
||||
dispatch->wrkGrpSizeY = aqlPkt->workgroup_size[1];
|
||||
dispatch->wrkGrpSizeZ = aqlPkt->workgroup_size[2];
|
||||
|
||||
// ISA address
|
||||
__global AmdKernelCode* kernelObj = (__global AmdKernelCode*)aqlPkt->kernel_object_address;
|
||||
ulong isa = aqlPkt->kernel_object_address + kernelObj->kernel_code_entry_byte_offset;
|
||||
|
||||
dispatch->isaLo = (uint)(isa >> 8);
|
||||
dispatch->isaHi = (uint)(isa >> 40) | (useATC ? 0x100 : 0);
|
||||
|
||||
// Program PGM resource registers
|
||||
dispatch->resource1 = kernelObj->compute_pgm_rsrc1;
|
||||
dispatch->resource2 = kernelObj->compute_pgm_rsrc2;
|
||||
|
||||
uint flags = kernelObj->kernel_code_properties;
|
||||
uint privateSize = kernelObj->workitem_private_segment_byte_size;
|
||||
|
||||
uint ldsSize = aqlPkt->group_segment_size_bytes;
|
||||
|
||||
// Align up the LDS blocks 128 * 4(in DWORDs)
|
||||
uint ldsBlocks = (ldsSize + 511) >> 9;
|
||||
|
||||
dispatch->resource2 |= (ldsBlocks << 15);
|
||||
|
||||
// Private/scratch segment was enabled
|
||||
if (flags & PrivateSegEna) {
|
||||
uint waveSize = privateSize * WavefrontSize;
|
||||
// 256 DWRODs is the minimum for SQ
|
||||
waveSize = max(MaxWaveSize, waveSize);
|
||||
|
||||
uint numWaves = scratchSize / waveSize;
|
||||
|
||||
numWaves = min(numWaves, numMaxWaves);
|
||||
|
||||
dispatch->ringSize = numWaves;
|
||||
dispatch->ringSize |= (waveSize >> 10) << 12;
|
||||
dispatch->user0 = Pm4UserRegs | (4 << 16);
|
||||
dispatch->scratchLo = (uint)scratch;
|
||||
dispatch->scratchHi = ((uint)(scratch >> 32)) | 0x80000000; // Enables swizzle
|
||||
dispatch->scratchSize = scratchSize;
|
||||
usrRegCnt += 4;
|
||||
}
|
||||
else {
|
||||
dispatch->ringSize = 0;
|
||||
dispatch->user0 = Pm4Nop | (4 << 16);
|
||||
}
|
||||
|
||||
// Pointer to the AQL dispatch packet
|
||||
dispatch->user1 = (flags & DispatchEna) ? (Pm4UserRegs | (2 << 16)) : (Pm4Nop | (2 << 16));
|
||||
dispatch->offsUser1 = UsrRegOffset + usrRegCnt;
|
||||
usrRegCnt += (flags & DispatchEna) ? 2 : 0;
|
||||
ulong gpuAqlPtr = (ulong)aqlPkt;
|
||||
dispatch->aqlPtrLo = (uint)gpuAqlPtr;
|
||||
dispatch->aqlPtrHi = (uint)(gpuAqlPtr >> 32);
|
||||
|
||||
// Pointer to the AQL queue header
|
||||
if (flags & QueuePtrEna) {
|
||||
dispatch->user2 = Pm4UserRegs | (2 << 16);
|
||||
dispatch->offsUser2 = UsrRegOffset + usrRegCnt;
|
||||
usrRegCnt += 2;
|
||||
dispatch->hsaQueueLo = (uint)hsaQueue;
|
||||
dispatch->hsaQueueHi = (uint)(hsaQueue >> 32);
|
||||
}
|
||||
else {
|
||||
dispatch->user2 = Pm4Nop | (2 << 16);
|
||||
}
|
||||
|
||||
// Pointer to the AQL kernel arguments
|
||||
dispatch->user3 = (flags & KernelArgEna) ? (Pm4UserRegs | (2 << 16)) : (Pm4Nop | (2 << 16));
|
||||
dispatch->offsUser3 = UsrRegOffset + usrRegCnt;
|
||||
usrRegCnt += (flags & KernelArgEna) ? 2 : 0;
|
||||
dispatch->argsLo = (uint)aqlPkt->kernel_arg_address;
|
||||
dispatch->argsHi = (uint)(aqlPkt->kernel_arg_address >> 32);
|
||||
|
||||
// Provide pointer to the private/scratch buffer for the flat address
|
||||
if (flags & FlatScratchEna) {
|
||||
dispatch->copyData = Pm4CopyReg;
|
||||
dispatch->scratchAddrLo = (uint)((scratch - scratchOffset) >> 16);
|
||||
dispatch->offsUser4 = UsrRegOffset + usrRegCnt;
|
||||
dispatch->scratchOffs = scratchOffset;
|
||||
dispatch->privSize = privateSize;
|
||||
}
|
||||
else {
|
||||
dispatch->copyData = Pm4Nop | (8 << 16);
|
||||
}
|
||||
|
||||
// Update the global launch grid
|
||||
dispatch->glbSizeX = aqlPkt->grid_size[0];
|
||||
dispatch->glbSizeY = aqlPkt->grid_size[1];
|
||||
dispatch->glbSizeZ = aqlPkt->grid_size[2];
|
||||
}
|
||||
\n
|
||||
__kernel void
|
||||
__amd_rocclr_scheduler(
|
||||
__global void * queue,
|
||||
__global void * params,
|
||||
uint paramIdx)
|
||||
{
|
||||
__amd_scheduler(queue, params, paramIdx);
|
||||
}
|
||||
\n
|
||||
);
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,210 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpuprogram.hpp"
|
||||
#include "device/gpu/gpukernel.hpp"
|
||||
#include "hsailctx.hpp"
|
||||
#include "SCShadersSi.h"
|
||||
#include "si_ci_vi_merged_offset.h"
|
||||
#include "si_ci_vi_merged_registers.h"
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include "amd_hsa_loader.hpp"
|
||||
|
||||
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;
|
||||
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_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;
|
||||
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_NUM_WAVEFRONT_PER_SIMD; // Setting the same as for scWrapR800Info
|
||||
newInfos[i].value = 1;
|
||||
i++;
|
||||
|
||||
newInfos[i].address = AMU_ABI_WAVEFRONT_SIZE;
|
||||
newInfos[i].value = nullDev().isa().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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
} // namespace gpu
|
||||
@@ -1,476 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "top.hpp"
|
||||
#include "os/os.hpp"
|
||||
#include "device/device.hpp"
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpusettings.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "VersionHelpers.h"
|
||||
#endif
|
||||
|
||||
namespace gpu {
|
||||
|
||||
/*! \brief information for adjusting maximum workload time
|
||||
*
|
||||
* 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
|
||||
#if defined(_WIN32)
|
||||
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;
|
||||
|
||||
stagedXferRead_ = true;
|
||||
stagedXferWrite_ = true;
|
||||
stagedXferSize_ = GPU_STAGING_BUFFER_SIZE * Ki;
|
||||
|
||||
// We will enable staged read/write if we use local memory
|
||||
disablePersistent_ = false;
|
||||
|
||||
maxRenames_ = 16;
|
||||
maxRenameSize_ = 4 * Mi;
|
||||
|
||||
imageSupport_ = false;
|
||||
hwLDSSize_ = 0;
|
||||
|
||||
// Set this to true when we drop the flag
|
||||
doublePrecision_ = ::CL_KHR_FP64;
|
||||
|
||||
// Fill workgroup info size
|
||||
maxWorkGroupSize_ = 1024;
|
||||
preferredWorkGroupSize_ = 256;
|
||||
|
||||
hostMemDirectAccess_ = HostMemDisable;
|
||||
|
||||
libSelector_ = amd::LibraryUndefined;
|
||||
|
||||
// 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_);
|
||||
|
||||
// Disable FP_FAST_FMA defines by default
|
||||
reportFMAF_ = false;
|
||||
reportFMA_ = false;
|
||||
|
||||
// GPU device by default
|
||||
apuSystem_ = false;
|
||||
|
||||
// Disable 64 bit pointers support by default
|
||||
use64BitPtr_ = false;
|
||||
|
||||
// Max alloc size is 16GB
|
||||
maxAllocSize_ = 16 * static_cast<uint64_t>(Gi);
|
||||
|
||||
// Disable memory dependency tracking by default
|
||||
numMemDependencies_ = 0;
|
||||
|
||||
// By default cache isn't present
|
||||
cacheLineSize_ = 0;
|
||||
cacheSize_ = 0;
|
||||
|
||||
// Initialize transfer buffer size to 1MB by default
|
||||
xferBufSize_ = 1024 * Ki;
|
||||
|
||||
// Use image DMA if requested
|
||||
imageDMA_ = GPU_IMAGE_DMA;
|
||||
|
||||
// Disable ASIC specific features by default
|
||||
ciPlus_ = false;
|
||||
viPlus_ = false;
|
||||
aiPlus_ = false;
|
||||
|
||||
// Number of compute rings.
|
||||
numComputeRings_ = 0;
|
||||
|
||||
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;
|
||||
|
||||
useSingleScratch_ = GPU_USE_SINGLE_SCRATCH;
|
||||
|
||||
// SDMA profiling is disabled by default
|
||||
sdmaProfiling_ = false;
|
||||
|
||||
// Device enqueuing settings
|
||||
numDeviceEvents_ = 1024;
|
||||
numWaitEvents_ = 8;
|
||||
|
||||
// Don't support platform atomics by default.
|
||||
svmAtomics_ = false;
|
||||
|
||||
// Use host queue for device enqueuing by default
|
||||
useDeviceQueue_ = GPU_USE_DEVICE_QUEUE;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Update GPU specific settings and info structure if we have any
|
||||
ModifyMaxWorkload modifyMaxWorkload = {0};
|
||||
|
||||
switch (target) {
|
||||
case CAL_TARGET_RAVEN:
|
||||
case CAL_TARGET_RAVEN2:
|
||||
case CAL_TARGET_RENOIR:
|
||||
// APU systems for AI
|
||||
apuSystem_ = true;
|
||||
case CAL_TARGET_GREENLAND:
|
||||
case CAL_TARGET_VEGA12:
|
||||
case CAL_TARGET_VEGA20:
|
||||
// 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 defined(_WIN32)
|
||||
modifyMaxWorkload.comparisonOps = VER_EQUAL; // Limit to Win 7 only
|
||||
#endif
|
||||
}
|
||||
case CAL_TARGET_CARRIZO:
|
||||
if (!aiPlus_) {
|
||||
// APU systems for VI
|
||||
apuSystem_ = true;
|
||||
}
|
||||
case CAL_TARGET_ICELAND:
|
||||
case CAL_TARGET_TONGA:
|
||||
case CAL_TARGET_FIJI:
|
||||
case CAL_TARGET_ELLESMERE:
|
||||
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 ...
|
||||
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 defined(_WIN32)
|
||||
modifyMaxWorkload.comparisonOps = VER_EQUAL; // limit to Win 7
|
||||
#endif
|
||||
}
|
||||
// Fall through ...
|
||||
case CAL_TARGET_BONAIRE:
|
||||
case CAL_TARGET_HAWAII:
|
||||
ciPlus_ = true;
|
||||
sdmaProfiling_ = true;
|
||||
threadTraceEnable_ = AMD_THREAD_TRACE_ENABLE;
|
||||
reportFMAF_ = false;
|
||||
if (target == CAL_TARGET_HAWAII) {
|
||||
reportFMAF_ = true;
|
||||
}
|
||||
// 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;
|
||||
} else {
|
||||
numComputeRings_ = 2;
|
||||
libSelector_ = amd::GPU_Library_SI;
|
||||
}
|
||||
|
||||
// Cap at OpenCL20 for now
|
||||
if (oclVersion_ > OpenCL20) oclVersion_ = OpenCL20;
|
||||
|
||||
// This needs to be cleaned once 64bit addressing is stable
|
||||
if (oclVersion_ < OpenCL20) {
|
||||
use64BitPtr_ = flagIsDefault(GPU_FORCE_64BIT_PTR)
|
||||
? LP64_SWITCH(false, true)
|
||||
: GPU_FORCE_64BIT_PTR;
|
||||
} else {
|
||||
if (GPU_FORCE_64BIT_PTR || LP64_SWITCH(false, true)) {
|
||||
use64BitPtr_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (oclVersion_ >= OpenCL20) {
|
||||
supportDepthsRGB_ = true;
|
||||
}
|
||||
if (use64BitPtr_) {
|
||||
if (GPU_ENABLE_LARGE_ALLOCATION && (viPlus_ || (oclVersion_ == OpenCL20))) {
|
||||
maxAllocSize_ = 64ULL * Gi;
|
||||
} else {
|
||||
maxAllocSize_ = 4048 * Mi;
|
||||
}
|
||||
} else {
|
||||
maxAllocSize_ = 3ULL * Gi;
|
||||
}
|
||||
|
||||
supportRA_ = false;
|
||||
numMemDependencies_ = GPU_NUM_MEM_DEPENDENCY;
|
||||
|
||||
enableExtension(ClKhrInt64BaseAtomics);
|
||||
enableExtension(ClKhrInt64ExtendedAtomics);
|
||||
enableExtension(ClKhrImage2dFromBuffer);
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
enableExtension(ClAMDLiquidFlash);
|
||||
#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);
|
||||
|
||||
hwLDSSize_ = 32 * Ki;
|
||||
|
||||
imageSupport_ = true;
|
||||
|
||||
// Use kernels for blit if appropriate
|
||||
blitEngine_ = BlitEngineKernel;
|
||||
|
||||
hostMemDirectAccess_ |= HostMemBuffer;
|
||||
// HW doesn't support untiled image writes
|
||||
// hostMemDirectAccess_ |= HostMemImage;
|
||||
|
||||
// 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.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;
|
||||
}
|
||||
|
||||
svmFineGrainSystem_ = calAttr.isSVMFineGrainSystem;
|
||||
|
||||
svmAtomics_ = (calAttr.svmAtomics || calAttr.isSVMFineGrainSystem) ? true : false;
|
||||
|
||||
#if defined(_WIN32)
|
||||
enableExtension(ClKhrD3d9Sharing);
|
||||
enableExtension(ClKhrD3d10Sharing);
|
||||
enableExtension(ClKhrD3d11Sharing);
|
||||
#endif // _WIN32
|
||||
|
||||
// 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 defined(_WIN32)
|
||||
enableExtension(ClAmdPlanarYuv);
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
#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);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Override current device settings
|
||||
override();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Settings::override() {
|
||||
// Limit reported workgroup size
|
||||
if (GPU_MAX_WORKGROUP_SIZE != 0) {
|
||||
preferredWorkGroupSize_ = GPU_MAX_WORKGROUP_SIZE;
|
||||
}
|
||||
|
||||
// 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(GPU_XFER_BUFFER_SIZE)) {
|
||||
xferBufSize_ = GPU_XFER_BUFFER_SIZE * Ki;
|
||||
}
|
||||
|
||||
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_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,135 +0,0 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUSETTINGS_HPP_
|
||||
#define GPUSETTINGS_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "library.hpp"
|
||||
|
||||
/*! \addtogroup GPU GPU Resource Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! GPU Device Implementation
|
||||
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,
|
||||
};
|
||||
|
||||
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 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 svmAtomics_ : 1; //!< SVM device atomics
|
||||
uint svmFineGrainSystem_ : 1; //!< SVM fine grain system support
|
||||
uint useDeviceQueue_ : 1; //!< Submit to separate device queue
|
||||
uint reserved_ : 11;
|
||||
};
|
||||
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 preferredWorkGroupSize_; //!< Requested preferred 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();
|
||||
|
||||
//! 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&);
|
||||
|
||||
//! Disable assignment
|
||||
Settings& operator=(const Settings&);
|
||||
|
||||
//! Overrides current settings based on registry/environment
|
||||
void override();
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUSETTINGS_HPP_*/
|
||||
@@ -1,77 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "device/gpu/gputhreadtrace.hpp"
|
||||
#include "device/gpu/gpuvirtual.hpp"
|
||||
|
||||
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());
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
// Release the thread trace reference object
|
||||
// calRef_->release();
|
||||
}
|
||||
|
||||
bool ThreadTrace::create(CalThreadTraceReference* calRef) {
|
||||
assert(&gpu() == &calRef->gpu());
|
||||
|
||||
calRef_ = calRef;
|
||||
threadTrace_ = calRef->gslThreadTrace();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
default:
|
||||
LogError("Wrong ThreadTrace::getInfo parameter");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gpu
|
||||
@@ -1,148 +0,0 @@
|
||||
/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPU_THREAD_TRACE_HPP_
|
||||
#define GPU_THREAD_TRACE_HPP_
|
||||
|
||||
#include "top.hpp"
|
||||
#include "device/device.hpp"
|
||||
#include "device/gpu/gpudevice.hpp"
|
||||
#include "shadertracebuffer/ShaderTraceBufferObject.h"
|
||||
|
||||
#include <vector>
|
||||
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) {}
|
||||
|
||||
//! Get GSL thread race object
|
||||
gslQueryObject gslThreadTrace() const { return threadTrace_; }
|
||||
|
||||
//! Returns the virtual GPU device
|
||||
const VirtualGPU& gpu() const { return gpu_; }
|
||||
|
||||
protected:
|
||||
//! Default destructor
|
||||
~CalThreadTraceReference();
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CalThreadTraceReference(const CalThreadTraceReference&);
|
||||
|
||||
//! Disable operator=
|
||||
CalThreadTraceReference& operator=(const CalThreadTraceReference&);
|
||||
|
||||
VirtualGPU& gpu_; //!< The virtual GPU device object
|
||||
gslQueryObject threadTrace_; //!< GSL thread trace query object
|
||||
};
|
||||
|
||||
//! ThreadTrace implementation on GPU
|
||||
class ThreadTrace : public device::ThreadTrace {
|
||||
public:
|
||||
//! Destructor for the GPU ThreadTrace object
|
||||
virtual ~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 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();
|
||||
}
|
||||
}
|
||||
|
||||
//! 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 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();
|
||||
|
||||
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&);
|
||||
|
||||
//! Disable default operator=
|
||||
ThreadTrace& operator=(const ThreadTrace&);
|
||||
|
||||
//! Retrieve gslMemoryObject
|
||||
gslMemObject getCurrentGslMemObject(amd::Memory*);
|
||||
|
||||
const Device& gpuDevice_; //!< The backend device
|
||||
|
||||
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_
|
||||
@@ -1,112 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "os/os.hpp"
|
||||
#include "platform/perfctr.hpp"
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gputimestamp.hpp"
|
||||
#include "device/gpu/gpuvirtual.hpp"
|
||||
#include "device/gpu/gpucounters.hpp"
|
||||
|
||||
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() {}
|
||||
|
||||
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!");
|
||||
gpu().rs()->writeTimer(gpu().cs(), sdma, gslMem_, memOffset_ + CommandEndTime * sizeof(uint64_t));
|
||||
flags_.endIssued_ = true;
|
||||
flags_.sdma_ = sdma;
|
||||
}
|
||||
|
||||
inline void SetValue(uint64_t* time, uint64_t val, double nanos) {
|
||||
*time = static_cast<uint64_t>(static_cast<double>(val) * nanos);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 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
|
||||
@@ -1,137 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUTIMESTAMP_HPP_
|
||||
#define GPUTIMESTAMP_HPP_
|
||||
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpuresource.hpp"
|
||||
|
||||
/*! \addtogroup GPU GPU Resource Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
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 };
|
||||
|
||||
//! 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 destructor
|
||||
~TimeStamp();
|
||||
|
||||
//! Starts the timestamp
|
||||
void begin(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);
|
||||
|
||||
//! 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; }
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
TimeStamp(const TimeStamp&);
|
||||
|
||||
//! Disable operator=
|
||||
TimeStamp& operator=(const TimeStamp&);
|
||||
|
||||
//! 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
|
||||
};
|
||||
|
||||
class TimeStampCache : public amd::HeapObject {
|
||||
public:
|
||||
//! Default constructor
|
||||
TimeStampCache(VirtualGPU& gpu //!< Virtual GPU object
|
||||
)
|
||||
: gpu_(gpu), tsBufCpu_(NULL), tsOffset_(0) {}
|
||||
|
||||
//! Default destructor
|
||||
~TimeStampCache();
|
||||
|
||||
//! 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); }
|
||||
|
||||
private:
|
||||
static constexpr uint TimerSlotSize = TimeStamp::CommandTotal * sizeof(uint64_t);
|
||||
static constexpr uint TimerBufSize = TimerSlotSize * 4096;
|
||||
|
||||
//! Disable copy constructor
|
||||
TimeStampCache(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
|
||||
};
|
||||
|
||||
/*@}*/} // namespace gpu
|
||||
|
||||
#endif /*GPUTIMESTAMP_HPP_*/
|
||||
@@ -1,139 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* The source of the runtime trap handler, "runtimetraphandler.sp3".
|
||||
* The binary is created by the SP3 tool with the following command:
|
||||
*
|
||||
* sp3.exe runtimetraphandler.sp3 -hex runtimeTrapCode.hex
|
||||
*
|
||||
*******************************************************************************
|
||||
|
||||
shader main
|
||||
asic(TAHITI) // for SI/CI or asic(VI) for VI
|
||||
type(CS)
|
||||
|
||||
// clear wave exception state
|
||||
v_clrexcp
|
||||
s_waitcnt 0
|
||||
//==========================================================================
|
||||
// Handle the workaround for HW bug that causes the incorrect TMA value.
|
||||
// Retrieve the TMA values, which are stored at TBA buffer at location
|
||||
// 256 (0x100).
|
||||
|
||||
// Construct the memory descriptor with TBA as the start address
|
||||
// we are using the registers ttmp[8:11] for that.
|
||||
s_mov_b32 ttmp8, tba_lo
|
||||
s_and_b32 ttmp9, tba_hi, 0xffff
|
||||
|
||||
// 0x100=256 bytes, which is the size of the buffer to
|
||||
// store all the level 2 trap handler info
|
||||
s_or_b32 ttmp9, ttmp9, 0x01000000
|
||||
s_mov_b32 ttmp10, 0x00002000
|
||||
s_mov_b32 ttmp11, 0x00024fac
|
||||
|
||||
// TMA is stored 256 (0x100) bytes before the TBA value
|
||||
s_sub_u32 ttmp8, ttmp8, 0x100
|
||||
|
||||
// Backup the s0 since ttmp registers cannot be target of
|
||||
// buffer read instruction
|
||||
s_mov_b32 ttmp7, s0
|
||||
s_buffer_load_dword s0, ttmp8, 0x0 // VI: offset=0x0 (bytes)
|
||||
s_waitcnt 0
|
||||
s_mov_b32 tma_lo, s0
|
||||
s_buffer_load_dword s0, ttmp8, 0x1 // VI: offset=0x4 (bytes)
|
||||
s_waitcnt 0
|
||||
s_mov_b32 tma_hi, s0
|
||||
s_mov_b32 s0, ttmp7
|
||||
|
||||
//===================================================
|
||||
// setup the mmeory descriptor for TMA
|
||||
s_mov_b32 ttmp6, 0x18
|
||||
s_add_u32 ttmp8, tma_lo, ttmp6
|
||||
s_and_b32 ttmp9, tma_hi, 0xffff
|
||||
//0x68=104 bytes, which is the size of the buffer to
|
||||
//store all the level2 trap handler info
|
||||
s_or_b32 ttmp9, ttmp9, 0x00680000
|
||||
s_mov_b32 ttmp10, 0x00002000
|
||||
s_mov_b32 ttmp11, 0x00024fac
|
||||
|
||||
//===================================================
|
||||
// backup the TMA values to be restored later
|
||||
// level-one TMA saved in the ttmp6,ttmp7
|
||||
s_mov_b32 ttmp6, tma_lo
|
||||
s_mov_b32 ttmp7, tma_hi
|
||||
|
||||
//===================================================
|
||||
// setup the TMA for the level-two trap handler
|
||||
// level-two TMA saved in tma_hi, tma_lo
|
||||
s_mov_b32 ttmp3, s0
|
||||
s_buffer_load_dword s0, ttmp8, 0x2 // VI: offset=0x8 (bytes)
|
||||
s_waitcnt 0x0000
|
||||
s_mov_b32 tma_lo, s0
|
||||
|
||||
s_buffer_load_dword s0, ttmp8, 0x3 // VI: offset=0xc (bytes)
|
||||
s_waitcnt 0x0000
|
||||
s_mov_b32 tma_hi, s0
|
||||
|
||||
//===================================================
|
||||
// setup the TBA for the level-two trap handler
|
||||
// level-two TBA saved in ttmp9, ttmp8
|
||||
s_buffer_load_dword s0, ttmp8, 0x0 // VI: offset=0x0 (bytes)
|
||||
s_waitcnt 0x0000
|
||||
s_mov_b32 ttmp2, s0
|
||||
|
||||
s_buffer_load_dword s0, ttmp8, 0x1 // VI: offset=0x4 (bytes)
|
||||
s_waitcnt 0x0000
|
||||
|
||||
//swap the values of s0 and ttmp3 without using other registers
|
||||
s_xor_b32 ttmp3, s0, ttmp3
|
||||
s_xor_b32 s0, s0, ttmp3
|
||||
s_xor_b32 ttmp3, s0, ttmp3
|
||||
|
||||
//store the debug trap handler start address in ttmp8,9
|
||||
s_mov_b32 ttmp8, ttmp2
|
||||
s_mov_b32 ttmp9, ttmp3
|
||||
|
||||
//===================================================
|
||||
// get the pc value to resume execution
|
||||
s_getpc_b64 [ttmp2, ttmp3]
|
||||
s_add_u32 ttmp2, ttmp2, 0x8
|
||||
|
||||
//===================================================
|
||||
//set the pc value to jump to the debug trap handler
|
||||
s_setpc_b64 [ttmp8, ttmp9]
|
||||
|
||||
//===================================================
|
||||
// restore the tamp values
|
||||
s_mov_b32 tma_hi, ttmp7
|
||||
s_mov_b32 tma_lo, ttmp6
|
||||
|
||||
label_return:
|
||||
//===================================================
|
||||
// return from the trap handler to the saved PC
|
||||
s_and_b32 ttmp1, ttmp1, 0xffff
|
||||
s_rfe_b64 [ttmp0,ttmp1]
|
||||
|
||||
end
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/// shader codes with "asic(TAHITI)" instruction
|
||||
static constexpr 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 constexpr 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};
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,528 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef GPUVIRTUAL_HPP_
|
||||
#define GPUVIRTUAL_HPP_
|
||||
|
||||
#include "device/gpu/gpudefs.hpp"
|
||||
#include "device/gpu/gpuconstbuf.hpp"
|
||||
#include "device/gpu/gpuprintf.hpp"
|
||||
#include "device/gpu/gputimestamp.hpp"
|
||||
#include "device/gpu/gpusched.hpp"
|
||||
#include "platform/commandqueue.hpp"
|
||||
#include "device/blit.hpp"
|
||||
|
||||
#include "device/gpu/gpudebugger.hpp"
|
||||
|
||||
|
||||
/*! \addtogroup GPU GPU Resource Implementation
|
||||
* @{
|
||||
*/
|
||||
|
||||
//! GPU Device Implementation
|
||||
namespace gpu {
|
||||
|
||||
class Device;
|
||||
class Kernel;
|
||||
class Memory;
|
||||
class CalCounterReference;
|
||||
class VirtualGPU;
|
||||
class Program;
|
||||
class BlitManager;
|
||||
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
|
||||
|
||||
//! 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) {}
|
||||
};
|
||||
|
||||
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), endMemObjectsInQueue_(0), 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:
|
||||
explicit 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 submitCopyMemoryP2P(amd::CopyMemoryP2PCommand& 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);
|
||||
|
||||
//! 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);
|
||||
|
||||
//! Attach profiler
|
||||
void profilerAttach(bool enable = false) {}
|
||||
|
||||
//! 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_; }
|
||||
|
||||
//! Get the PrintfDbg object
|
||||
PrintfDbg& printfDbg() const { return *printfDbg_; }
|
||||
|
||||
//! 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)
|
||||
);
|
||||
|
||||
private:
|
||||
typedef std::unordered_map<CALimage, GslKernelDesc*> GslKernels;
|
||||
typedef std::unordered_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 forceBlit = false //!< force shader blit path
|
||||
);
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
#endif /*GPUVIRTUAL_HPP_*/
|
||||
@@ -1,2 +0,0 @@
|
||||
OPENCL_DEPTH = $(CAL_DEPTH)/../../../..
|
||||
include $(OPENCL_DEPTH)/runtime/runtimedefs
|
||||
@@ -1 +0,0 @@
|
||||
include $(OPENCL_DEPTH)/runtime/runtimerules
|
||||
@@ -1,2 +0,0 @@
|
||||
Promotions directory contains functionality from other staging branches copied
|
||||
(promoted) into the CAL tree.
|
||||
@@ -1,222 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
|
||||
#include "EventQueue.h"
|
||||
#include "query/QueryObject.h"
|
||||
#include "gsl_ctx.h"
|
||||
|
||||
EventQueue::EventQueue()
|
||||
{
|
||||
m_cs = NULL;
|
||||
m_queueSize = c_staticQueueSize;
|
||||
|
||||
memset(m_queries,0,sizeof(m_queries));
|
||||
memset(m_flushed,0,sizeof(m_flushed));
|
||||
|
||||
m_latestRetired = 0;
|
||||
m_headId = m_queueSize - 1 ;
|
||||
m_tail = 0;
|
||||
}
|
||||
|
||||
EventQueue::~EventQueue()
|
||||
{
|
||||
for (unsigned int i = 0; i < c_staticQueueSize; i++)
|
||||
{
|
||||
assert(m_queries[i] == 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
EventQueue::open(gsCtx* cs, gslQueryTarget target, EQManagerConfig config, uint32 engineMask)
|
||||
{
|
||||
assert((config == EQManager_HIGH) || (config == EQManager_LOW));
|
||||
setSlotCount((int) config);
|
||||
assert((GpuEvent::InvalidID+1) % m_queueSize == 0);
|
||||
|
||||
m_cs = cs;
|
||||
|
||||
m_headId = m_queueSize - 1 ;
|
||||
m_tail = 0;
|
||||
m_latestRetired = 0;
|
||||
m_target = target;
|
||||
m_engineMask = engineMask;
|
||||
|
||||
for (unsigned int i = 0; i < m_queueSize; i++)
|
||||
{
|
||||
m_queries[i] = cs->createQuery(target);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
EventQueue::close()
|
||||
{
|
||||
if (!m_cs) // the queue is unintialized.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < m_queueSize; i++)
|
||||
{
|
||||
m_cs->destroyQuery(m_queries[i]);
|
||||
}
|
||||
memset(m_queries, 0, sizeof(m_queries));
|
||||
memset(m_flushed, 0, sizeof(m_flushed));
|
||||
m_latestRetired = 0;
|
||||
m_headId = m_queueSize - 1 ;
|
||||
m_tail = 0;
|
||||
m_cs = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
EventQueue::begin()
|
||||
{
|
||||
const CALuint slot = m_headId % m_queueSize;
|
||||
gslErrorCode ec = m_queries[slot]->BeginQuery(m_cs, m_target, 0, m_engineMask);
|
||||
assert(ec == GSL_NO_ERROR);
|
||||
|
||||
m_flushed[slot] = false; // we've started a query, but it hasn't been checked yet...
|
||||
}
|
||||
|
||||
uint32
|
||||
EventQueue::end()
|
||||
{
|
||||
uint32 ret = m_headId;
|
||||
const uint32 slot = m_headId % m_queueSize;
|
||||
|
||||
m_queries[slot]->EndQuery(m_cs, 0);
|
||||
|
||||
m_headId++;
|
||||
m_tail++;
|
||||
|
||||
if (GpuEvent::InvalidID == m_headId)
|
||||
{
|
||||
// Flush on an event ID wrap around or when the Queue is going to wrap in
|
||||
flush();
|
||||
//roll numbers back to the beginning
|
||||
m_latestRetired = 0;
|
||||
m_headId = m_headId % m_queueSize;
|
||||
m_tail = m_tail % m_queueSize;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
EventQueue::isDone(uint32 event)
|
||||
{
|
||||
assert((event < GpuEvent::InvalidID) && "illegal event handle");
|
||||
// if the event is older the the last known retired event we
|
||||
// do not need to process it.
|
||||
if (event <= m_latestRetired)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// if the event is older than the oldest event handle we have
|
||||
// we synchronize with the oldest event.
|
||||
if (event < m_tail)
|
||||
{
|
||||
return waitForEvent(m_tail, CAL_WAIT_LOW_CPU_UTILIZATION);
|
||||
}
|
||||
|
||||
//
|
||||
// If we've never called flush on the query object, go ahead flush the first time to ensure
|
||||
// we never infinite loop
|
||||
//
|
||||
const uint32 slot = event % m_queueSize;
|
||||
if (!m_flushed[slot])
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
//
|
||||
// Since we're in between, we actually have to check to see if things are truely done
|
||||
//
|
||||
bool retVal = m_queries[slot]->IsResultAvailable(m_cs);
|
||||
|
||||
// cache the most recently retired event
|
||||
if (retVal && (event < m_headId) && (event > m_latestRetired))
|
||||
{
|
||||
m_latestRetired = event;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool
|
||||
EventQueue::waitForEvent(uint32 event, uint32 waitType)
|
||||
{
|
||||
// if we already retired a younger event we don't to process current events
|
||||
if (event <= m_latestRetired)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// if the event is older than the oldest event handle we have
|
||||
// we synchronize with the oldest event
|
||||
if (event < m_tail)
|
||||
{
|
||||
event = m_tail;
|
||||
}
|
||||
|
||||
//
|
||||
// If we've never called flush on the query object, go ahead flush the first time to ensure
|
||||
// we never infinite loop
|
||||
//
|
||||
const uint32 slot = event % m_queueSize;
|
||||
if (!m_flushed[slot])
|
||||
{
|
||||
flush();
|
||||
}
|
||||
uint64 param;
|
||||
m_queries[slot]->GetResult(m_cs, ¶m, (IOSyncWaitType) waitType);
|
||||
|
||||
// cache the most recently retired event
|
||||
if ((event < m_headId) && (event > m_latestRetired))
|
||||
{
|
||||
m_latestRetired = event;
|
||||
}
|
||||
|
||||
return (param != 0);
|
||||
}
|
||||
|
||||
bool
|
||||
EventQueue::flush()
|
||||
{
|
||||
m_cs->Flush(false, m_engineMask);
|
||||
memset(m_flushed, 1, sizeof(m_flushed));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EventQueue::setSlotCount(uint32 slotCount)
|
||||
{
|
||||
if (slotCount < c_staticQueueSize)
|
||||
{
|
||||
m_queueSize = slotCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_queueSize = c_staticQueueSize;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __EventQueue_h__
|
||||
#define __EventQueue_h__
|
||||
|
||||
#include "backend.h"
|
||||
#include "atitypes.h"
|
||||
#include "gsl_types.h"
|
||||
#include "gsl_config.h"
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
class gsCtx;
|
||||
};
|
||||
|
||||
enum EQManagerConfig
|
||||
{
|
||||
EQManager_HIGH = 512,
|
||||
EQManager_LOW = 32
|
||||
};
|
||||
|
||||
class EventQueue {
|
||||
public:
|
||||
static constexpr unsigned int c_staticQueueSize = EQManager_HIGH;
|
||||
EventQueue();
|
||||
~EventQueue();
|
||||
|
||||
bool open(gsl::gsCtx* cs, gslQueryTarget target, EQManagerConfig config, uint32 engineMask = GSL_ENGINEMASK_ALL_BUT_UVD_VCE);
|
||||
void close();
|
||||
|
||||
void begin();
|
||||
uint32 end();
|
||||
bool isDone(uint32 event);
|
||||
bool waitForEvent(uint32 event, uint32 waitType);
|
||||
bool flush();
|
||||
|
||||
private:
|
||||
|
||||
gsl::gsCtx* m_cs;
|
||||
|
||||
uint32 m_queueSize;
|
||||
gslQueryTarget m_target;
|
||||
uint32 m_engineMask; // EngineMask for this Query
|
||||
uint32 m_tail; //represents the oldest event we have
|
||||
uint32 m_headId;
|
||||
uint32 m_latestRetired; //!< most recentyl retired event.
|
||||
gslQueryObject m_queries[c_staticQueueSize];
|
||||
bool m_flushed[c_staticQueueSize];
|
||||
///////////////////////
|
||||
// private functions //
|
||||
///////////////////////
|
||||
void setSlotCount(uint32 slotCount);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,601 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "gsl_ctx.h"
|
||||
#include "gsl_adaptor.h"
|
||||
#include "GSLContext.h"
|
||||
#include "GSLDevice.h"
|
||||
#include "cm_if.h"
|
||||
#include "amuABI.h"
|
||||
#include "shader/ProgramObject.h"
|
||||
#include "shader/ComputeProgramObject.h"
|
||||
#include "query/QueryObject.h"
|
||||
#include "query/PerformanceQueryObject.h"
|
||||
#include "constbuffer/ConstantBufferObject.h"
|
||||
#include "sampler/SamplerObject.h"
|
||||
#include "texture/TextureResourceObject.h"
|
||||
#include "uav/UAVObject.h"
|
||||
#include "RenderStateObject.h"
|
||||
#include "shadertracebuffer/ShaderTraceBufferObject.h"
|
||||
#include "scratchbuffer/ScratchBufferObject.h"
|
||||
#include "memory/MemObject.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
CALGSLContext::CALGSLContext()
|
||||
{
|
||||
m_cs = 0;
|
||||
m_rs = 0;
|
||||
m_allowDMA = false;
|
||||
|
||||
COMPILE_TIME_ASSERT((int)MAX_OUTPUTS <= (int)GSL_MAX_OUTPUT);
|
||||
|
||||
memset(m_textureSamplers, 0, sizeof(m_textureSamplers));
|
||||
memset(m_textureResources, 0, sizeof(m_textureResources));
|
||||
memset(m_uavResources, 0, sizeof(m_uavResources));
|
||||
memset(m_constantBuffers, 0, sizeof(m_constantBuffers));
|
||||
|
||||
m_scratchBuffers = 0;
|
||||
|
||||
m_waitType = CAL_WAIT_LOW_CPU_UTILIZATION;
|
||||
}
|
||||
|
||||
CALGSLContext::~CALGSLContext()
|
||||
{
|
||||
assert(m_cs == 0);
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::open(
|
||||
const CALGSLDevice* pDeviceObject,
|
||||
uint32 nEngines,
|
||||
gslEngineDescriptor* engines,
|
||||
uint32 rtCUs)
|
||||
{
|
||||
m_Dev = pDeviceObject;
|
||||
|
||||
//! @note: GSL device isn't thread safe
|
||||
amd::ScopedLock k(dev()->gslDeviceOps());
|
||||
|
||||
gsl::gsAdaptor* native = dev()->getNative();
|
||||
assert(native != 0);
|
||||
|
||||
EQManagerConfig EQConfig = EQManager_HIGH;
|
||||
|
||||
gslEngineID mainEngineOrdinal = GSL_ENGINEID_INVALID;
|
||||
gslEngineID sdmaOrdinal = GSL_ENGINEID_INVALID;
|
||||
for (uint i = 0; i < nEngines; i++)
|
||||
{
|
||||
if (engines[i].id >= GSL_ENGINEID_3DCOMPUTE0 &&
|
||||
engines[i].id <= GSL_ENGINEID_COMPUTE_MEDIUM_PRIORITY)
|
||||
{
|
||||
mainEngineOrdinal = engines[i].id;
|
||||
}
|
||||
|
||||
if (engines[i].id == GSL_ENGINEID_DRMDMA0||
|
||||
engines[i].id == GSL_ENGINEID_DRMDMA1)
|
||||
{
|
||||
sdmaOrdinal = engines[i].id;
|
||||
m_allowDMA = dev()->canDMA();
|
||||
}
|
||||
}
|
||||
|
||||
m_cs = native->createComputeContext(mainEngineOrdinal, sdmaOrdinal, false, rtCUs);
|
||||
|
||||
if (m_cs == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_cs->getMainSubCtx()->setVPUMask(dev()->getVPUMask());
|
||||
|
||||
m_cs->makeCurrent(0);
|
||||
|
||||
m_rs = m_cs->createRenderState();
|
||||
if (m_rs == 0)
|
||||
{
|
||||
native->deleteContext(m_cs);
|
||||
m_cs = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cs->setRenderState(m_rs);
|
||||
m_cs->createSubAllocDesc();
|
||||
|
||||
//
|
||||
//
|
||||
// configure the default compute mode
|
||||
//
|
||||
m_rs->setComputeShader(m_cs, true);
|
||||
|
||||
m_eventQueue[MainEngine].open(m_cs, GSL_SYNC_ATI, EQConfig);
|
||||
m_eventQueue[SdmaEngine].open(m_cs, GSL_DRMDMA_SYNC_ATI, EQConfig, GSL_ENGINE_MASK(GSL_ENGINEID_DRMDMA0) | GSL_ENGINE_MASK(GSL_ENGINEID_DRMDMA1));
|
||||
|
||||
m_cs->setGPU((gslGPUMask)dev()->getVPUMask());
|
||||
|
||||
m_cs->setDMAFlushBuf(dev()->m_srcDRMDMAMem, dev()->m_dstDRMDMAMem, 4 /* size of CM_SURF_FMT_R32F*/);
|
||||
|
||||
// Create the GSL scratch buffer object
|
||||
m_scratchBuffers = m_cs->createScratchBuffer();
|
||||
if (m_scratchBuffers == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_textureSamplers[0] == 0)
|
||||
{
|
||||
// Special case. GSL validation requires a sampler with any texture setup.
|
||||
// In OCL kernel may have an image argument, but doesn't use it. So a sampler
|
||||
// can be undefined.
|
||||
//! @note HSAIL will need a sampler as well
|
||||
m_textureSamplers[0] = m_cs->createSampler();
|
||||
m_rs->setSamplerObject(GSL_COMPUTE_PROGRAM, m_textureSamplers[0], 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::close(gsl::gsAdaptor* native)
|
||||
{
|
||||
if (m_cs == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//! @note: GSL device isn't thread safe
|
||||
amd::ScopedLock k(dev()->gslDeviceOps());
|
||||
|
||||
m_cs->Flush();
|
||||
|
||||
assert(m_rs != 0);
|
||||
|
||||
m_cs->setRenderState(m_rs);
|
||||
|
||||
m_rs->setCurrentProgramObject(GSL_COMPUTE_PROGRAM, 0);
|
||||
|
||||
for (int i = 0; i < MAX_SAMPLERS; i++)
|
||||
{
|
||||
m_rs->setSamplerObject(GSL_COMPUTE_PROGRAM, 0, i);
|
||||
if (m_textureSamplers[i] != 0)
|
||||
{
|
||||
m_cs->destroySampler(m_textureSamplers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_RESOURCES; i++)
|
||||
{
|
||||
m_rs->setTextureResourceObject(m_cs, GSL_COMPUTE_PROGRAM, 0, i);
|
||||
if (m_textureResources[i] != 0)
|
||||
{
|
||||
m_cs->destroyTextureResource(m_textureResources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_UAVS; i++)
|
||||
{
|
||||
m_rs->setUavObject(m_cs, GSL_COMPUTE_PROGRAM, 0, static_cast<uint32>(GSL_UAV0 + i));
|
||||
if (m_uavResources[i] != 0)
|
||||
{
|
||||
m_cs->destroyUAVObject(m_uavResources[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_CONSTANTBUFFERS; i++)
|
||||
{
|
||||
m_rs->setConstantBufferObject(GSL_COMPUTE_PROGRAM, 0, i);
|
||||
if (m_constantBuffers[i])
|
||||
{
|
||||
m_cs->destroyConstantBuffer(m_constantBuffers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scratchBuffers != NULL)
|
||||
{
|
||||
//!@todo it should be GSL_COMPUTE_PROGRAM
|
||||
m_rs->setScratchBufferObject(GSL_FRAGMENT_PROGRAM, 0);
|
||||
m_scratchBuffers->setMemObject(m_cs, 0, 0);
|
||||
m_cs->destroyScratchBuffer(m_scratchBuffers);
|
||||
m_scratchBuffers = 0;
|
||||
}
|
||||
|
||||
m_cs->setRenderState(0);
|
||||
|
||||
m_cs->destroyRenderState(m_rs);
|
||||
m_cs->destroySubAllocDesc();
|
||||
|
||||
m_rs = 0;
|
||||
|
||||
for (uint32 i = 0; i < AllEngines; ++i)
|
||||
{
|
||||
m_eventQueue[i].close();
|
||||
}
|
||||
|
||||
native->deleteContext(m_cs);
|
||||
|
||||
m_cs = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::setInput(uint32 physUnit, gslMemObject mem)
|
||||
{
|
||||
assert(physUnit < MAX_RESOURCES);
|
||||
|
||||
//if there is no texture resource object associated with this unit, then allocate one.
|
||||
if (m_textureResources[physUnit] == 0)
|
||||
{
|
||||
m_textureResources[physUnit] = m_cs->createTextureResource();
|
||||
m_rs->setTextureResourceObject(m_cs, GSL_COMPUTE_PROGRAM,
|
||||
m_textureResources[physUnit], physUnit);
|
||||
}
|
||||
|
||||
m_textureResources[physUnit]->updateDepthTextureParam(mem);
|
||||
m_textureResources[physUnit]->setMemObject(m_cs, GSL_COMPUTE_PROGRAM, mem, NULL);
|
||||
|
||||
if (mem != NULL)
|
||||
{
|
||||
intp channelOrder = mem->getAttribs().channelOrder;
|
||||
dev()->convertInputChannelOrder(&channelOrder);
|
||||
m_rs->setTextureResourceSwizzle(GSL_COMPUTE_PROGRAM, physUnit,
|
||||
reinterpret_cast<const int32 *>(&channelOrder));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::setConstantBuffer(uint32 physUnit, gslMemObject mem, uint32 offset, size_t size)
|
||||
{
|
||||
assert(physUnit < MAX_CONSTANTBUFFERS);
|
||||
assert((physUnit < MAX_APICONSTANTBUFFERS) || (physUnit == SC_INFO_CONSTANTBUFFER));
|
||||
|
||||
//if there is no constant buffer object associated with this unit, then allocate one.
|
||||
if (m_constantBuffers[physUnit] == 0)
|
||||
{
|
||||
m_constantBuffers[physUnit] = m_cs->createConstantBuffer();
|
||||
m_rs->setConstantBufferObject(GSL_COMPUTE_PROGRAM, m_constantBuffers[physUnit], physUnit);
|
||||
}
|
||||
|
||||
return m_constantBuffers[physUnit]->bindMemory(m_cs, mem, static_cast<mcoffset>(offset), (uint32)size);
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::setUAVBuffer(uint32 physUnit, gslMemObject mem, gslUAVType uavType)
|
||||
{
|
||||
assert(physUnit < MAX_UAVS);
|
||||
|
||||
if (m_uavResources[physUnit] == 0)
|
||||
{
|
||||
m_uavResources[physUnit] = m_cs->createUAVObject();
|
||||
m_rs->setUavObject(m_cs, GSL_COMPUTE_PROGRAM, m_uavResources[physUnit], GSL_UAV0 + physUnit);
|
||||
}
|
||||
m_uavResources[physUnit]->setMemObject(m_cs, mem, uavType);
|
||||
m_uavResources[physUnit]->setRSOBindings(m_cs, GSL_COMPUTE_PROGRAM);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::setUAVChannelOrder(uint32 physUnit, gslMemObject mem)
|
||||
{
|
||||
assert(physUnit < MAX_UAVS);
|
||||
intp channelOrder = mem->getAttribs().channelOrder;
|
||||
dev()->convertInputChannelOrder(&channelOrder);
|
||||
m_uavResources[physUnit]->setParameter(GSL_UAV_RESOURCE_SWIZZLE, &channelOrder);
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::isDone(GpuEvent* event)
|
||||
{
|
||||
if (event->isValid())
|
||||
{
|
||||
assert(event->engineId_ < AllEngines);
|
||||
if (m_eventQueue[event->engineId_].isDone(event->id))
|
||||
{
|
||||
event->invalidate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::waitForEvent(GpuEvent* event)
|
||||
{
|
||||
if (event->isValid())
|
||||
{
|
||||
assert(event->engineId_ < AllEngines);
|
||||
m_eventQueue[event->engineId_].waitForEvent(event->id, m_waitType);
|
||||
event->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::flushCUCaches(bool flushL2) const
|
||||
{
|
||||
m_cs->FlushCUCaches(flushL2);
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::setScratchBuffer(gslMemObject mem, int32 engineId)
|
||||
{
|
||||
// This card has global scratch buffer, so we only manage one resource,
|
||||
// independent of program type and number of shader engineers.
|
||||
// For consistency with GSL, We will store the buffer under the
|
||||
// fragment program type for shader engine 0.
|
||||
//!@tod should be GSL_COMPUTE_PROGRAM
|
||||
gslProgramTargetEnum target = GSL_FRAGMENT_PROGRAM;
|
||||
gslScratchBufferObject scratchBuff = (mem != NULL) ? m_scratchBuffers : NULL;
|
||||
|
||||
m_rs->setScratchBufferObject(target, m_scratchBuffers);
|
||||
|
||||
m_scratchBuffers->setMemObject(m_cs, mem, engineId);
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::copyPartial(GpuEvent& event,
|
||||
gslMemObject srcMem,
|
||||
size_t* srcOffset,
|
||||
gslMemObject destMem,
|
||||
size_t* destOffset,
|
||||
size_t* size,
|
||||
CALmemcopyflags flags,
|
||||
bool enableRectCopy,
|
||||
uint32 bytesPerElement)
|
||||
{
|
||||
uint32 mode = GSL_SYNCUPLOAD_IGNORE_ELEMENTSIZE;
|
||||
EngineType engineId = MainEngine;
|
||||
assert(m_cs != 0);
|
||||
uint64 linearBytePitch = 0;
|
||||
intp bpp = 0;
|
||||
|
||||
CopyType type = dev()->GetCopyType(srcMem, destMem, srcOffset, destOffset, m_allowDMA,
|
||||
flags, size[0], enableRectCopy);
|
||||
|
||||
if(type == USE_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
case CAL_MEMCOPY_DEFAULT:
|
||||
case CAL_MEMCOPY_SYNC:
|
||||
mode |= GSL_SYNCUPLOAD_SYNC_START | GSL_SYNCUPLOAD_SYNC_WAIT;
|
||||
break;
|
||||
|
||||
case CAL_MEMCOPY_ASYNC:
|
||||
if ((type == USE_DRMDMA) || (type == USE_DRMDMA_T2L) || (type == USE_DRMDMA_L2T))
|
||||
{
|
||||
engineId = SdmaEngine;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gslErrorCode gslErr = GSL_NO_ERROR;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case USE_DRMDMA:
|
||||
mode |= GSL_SYNCUPLOAD_DMA;
|
||||
eventBegin(engineId);
|
||||
if(enableRectCopy)
|
||||
{
|
||||
if ((*srcOffset%4 != 0) || (*destOffset%4 != 0) || (size[0]%4 !=0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_cs->syncUploadRawRect(srcMem, srcOffset[0], (uint32)srcOffset[1], (uint32)srcOffset[2],
|
||||
destMem, destOffset[0], (uint32)destOffset[1], (uint32)destOffset[2],
|
||||
size[0], (uint32)size[1], (uint32)size[2], mode, bytesPerElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cs->syncUploadRaw(srcMem, srcOffset[0], destMem, destOffset[0], size[0], mode);
|
||||
}
|
||||
eventEnd(engineId, event);
|
||||
break;
|
||||
|
||||
case USE_DRMDMA_T2L:
|
||||
mode |= GSL_SYNCUPLOAD_DMA;
|
||||
eventBegin(engineId);
|
||||
bpp = srcMem->getBitsPerElement();
|
||||
linearBytePitch = size[0] * (bpp / 8);
|
||||
gslErr = m_cs->DMACopySubSurface(srcOffset[0], (uint32)srcOffset[1], size[0], (uint32)size[1],
|
||||
destMem, destOffset[0], linearBytePitch, srcMem, 0, 0, ATIGL_FALSE, mode);
|
||||
eventEnd(engineId, event);
|
||||
break;
|
||||
|
||||
case USE_DRMDMA_L2T:
|
||||
mode |= GSL_SYNCUPLOAD_DMA;
|
||||
eventBegin(engineId);
|
||||
bpp = destMem->getBitsPerElement();
|
||||
linearBytePitch = size[0] * (bpp / 8);
|
||||
gslErr = m_cs->DMACopySubSurface(destOffset[0], (uint32)destOffset[1], size[0], (uint32)size[1],
|
||||
srcMem, srcOffset[0], linearBytePitch, destMem, 0, 0, ATIGL_TRUE, mode);
|
||||
eventEnd(engineId, event);
|
||||
break;
|
||||
|
||||
case USE_CPDMA:
|
||||
eventBegin(MainEngine);
|
||||
m_cs->syncUploadRaw(srcMem, srcOffset[0], destMem, destOffset[0], size[0], mode);
|
||||
eventEnd(MainEngine, event);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
//
|
||||
// XXX - should never be here
|
||||
//
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gslErr != GSL_NO_ERROR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::setSamplerParameter(uint32 sampler, gslTexParameterPname param, void* vals)
|
||||
{
|
||||
if (m_textureSamplers[sampler] == 0)
|
||||
{
|
||||
m_textureSamplers[sampler] = m_cs->createSampler();
|
||||
m_rs->setSamplerObject(GSL_COMPUTE_PROGRAM, m_textureSamplers[sampler], sampler);
|
||||
}
|
||||
|
||||
float* params = reinterpret_cast<float*>(vals);
|
||||
switch (param)
|
||||
{
|
||||
case GSL_TEXTURE_MIN_FILTER:
|
||||
m_textureSamplers[sampler]->setMinFilter(m_cs,
|
||||
static_cast<gslTexParameterParamMinFilter>((uint32)params[0]));
|
||||
break;
|
||||
case GSL_TEXTURE_MAG_FILTER:
|
||||
m_textureSamplers[sampler]->setMagFilter(m_cs,
|
||||
static_cast<gslTexParameterParamMagFilter>((uint32)params[0]));
|
||||
break;
|
||||
case GSL_TEXTURE_WRAP_S:
|
||||
case GSL_TEXTURE_WRAP_T:
|
||||
case GSL_TEXTURE_WRAP_R:
|
||||
m_textureSamplers[sampler]->setWrap(m_cs, param,
|
||||
static_cast<gslTexParameterParamWrap>((uint32)params[0]));
|
||||
break;
|
||||
case GSL_TEXTURE_BORDER_COLOR:
|
||||
m_textureSamplers[sampler]->setBorderColor(m_cs, params);
|
||||
break;
|
||||
default:
|
||||
assert(!"Unknown sampler state");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLContext::moduleLoad(CALimage image,
|
||||
gslProgramObject* func, gslMemObject* constants)
|
||||
{
|
||||
AMUabiMultiBinary binary;
|
||||
AMUabiEncoding encoding;
|
||||
|
||||
amuABIMultiBinaryCreate(&binary);
|
||||
amuABIMultiBinaryUnpack(binary, image);
|
||||
|
||||
CALuint machine, type, count = 0;
|
||||
amuABIMultiBinaryGetEncodingCount(&count, binary);
|
||||
bool binaryFound = false;
|
||||
for (CALuint i = 0; i < count; ++i)
|
||||
{
|
||||
if (amuABIMultiBinaryGetEncoding(&encoding, binary, i) &&
|
||||
amuABIEncodingGetSignature(&machine, &type, encoding) &&
|
||||
(machine == dev()->getElfMachine()) && (type == (CALuint)ED_ATI_CAL_TYPE_COMPUTE))
|
||||
{
|
||||
binaryFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!binaryFound)
|
||||
{
|
||||
amuABIMultiBinaryDestroy(binary);
|
||||
return false;
|
||||
}
|
||||
|
||||
*func = m_cs->createProgramObject(GSL_COMPUTE_PROGRAM);
|
||||
if (*func == 0)
|
||||
{
|
||||
amuABIMultiBinaryDestroy(binary);
|
||||
return false;
|
||||
}
|
||||
(*func)->programStringARB(m_cs, GSL_COMPUTE_PROGRAM, GSL_PROGRAM_FORMAT_ELF_BINARY, 0, image);
|
||||
|
||||
// Setup the loop constants from the ELF binary int const area.
|
||||
CALuint numConstants = 0;
|
||||
CALuint maxPhysical = 0;
|
||||
|
||||
AMUabiLiteralConst* litConsts;
|
||||
CALuint litConstsCount = 0;
|
||||
amuABIEncodingGetLitConsts(&litConstsCount, &litConsts, encoding);
|
||||
for (CALuint i = 0; i < litConstsCount; ++i)
|
||||
{
|
||||
if (litConsts[i].type == AMU_ABI_INT32)
|
||||
{
|
||||
maxPhysical = std::max(maxPhysical, litConsts[i].addr);
|
||||
++numConstants;
|
||||
}
|
||||
}
|
||||
|
||||
if (numConstants > 0)
|
||||
{
|
||||
const gslMemObjectAttribs attribs(
|
||||
GSL_MOA_CONSTANT_STORE, // type
|
||||
GSL_MOA_MEMORY_CARD, // location
|
||||
GSL_MOA_TILING_LINEAR, // tiling
|
||||
GSL_MOA_DISPLAYABLE_NO, // displayable
|
||||
ATIGL_FALSE, // mipmap
|
||||
1, // samples
|
||||
0, // cpu_address
|
||||
GSL_MOA_SIGNED_NO, // signed_format
|
||||
GSL_MOA_FORMAT_NORM, // numFormat
|
||||
DRIVER_MODULE_GLL, // module
|
||||
GSL_ALLOCATION_INSTANCED // alloc_type
|
||||
);
|
||||
|
||||
*constants = m_cs->createMemObject1D(CM_SURF_FMT_RGBX8, ++maxPhysical, &attribs);
|
||||
|
||||
CALuint* ptr = static_cast<CALuint*>((*constants)->map(m_cs, GSL_MAP_READ_WRITE));
|
||||
assert(ptr != 0 && "gslMapMemImage failed!");
|
||||
|
||||
for (CALuint i = 0; i < litConstsCount; ++i)
|
||||
{
|
||||
if (litConsts[i].type == AMU_ABI_INT32)
|
||||
{
|
||||
ptr[litConsts[i].addr] = litConsts[i].value.int32[0];
|
||||
}
|
||||
}
|
||||
|
||||
(*constants)->unmap(m_cs);
|
||||
}
|
||||
|
||||
amuABIMultiBinaryDestroy(binary);
|
||||
|
||||
// FIXME Until we get everything right, return an error or we'll hang the HW
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CALGSLContext::InvalidateSqCaches(bool instInvalidate, bool dataInvalidate, bool tcL1, bool tcL2)
|
||||
{
|
||||
// invalidating instruction/data L1 caches using Escape
|
||||
if (instInvalidate || dataInvalidate) {
|
||||
m_cs->invalidateSqCaches(instInvalidate, dataInvalidate);
|
||||
}
|
||||
|
||||
if (tcL1) {
|
||||
flushCUCaches(tcL2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __GSLContext_h__
|
||||
#define __GSLContext_h__
|
||||
|
||||
#include "atitypes.h"
|
||||
#include "gsl_types.h"
|
||||
#include "backend.h"
|
||||
|
||||
#include "EventQueue.h"
|
||||
#include "amuABI.h"
|
||||
|
||||
#define SC_INFO_CONSTANTBUFFER (147-128)
|
||||
#define SC_SR_INIT_CONSTANTBUFFER 0
|
||||
|
||||
#define HW_R800_MAX_UAV 12
|
||||
#define SC_R800_ARENA_UAV_SHORT_ID 9
|
||||
#define SC_R800_ARENA_UAV_BYTE_ID 10
|
||||
#define SC_R800_ARENA_UAV_DWORD_ID 11
|
||||
|
||||
class CALGSLDevice;
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
class gsAdaptor;
|
||||
};
|
||||
|
||||
class CALGSLContext
|
||||
{
|
||||
public:
|
||||
CALGSLContext();
|
||||
~CALGSLContext();
|
||||
|
||||
bool open(const CALGSLDevice* pDeviceObject, uint32 nEngines, gslEngineDescriptor *engines, uint32 rtCUs = 0);
|
||||
void close(gsl::gsAdaptor* native);
|
||||
|
||||
bool setInput(uint32 physUnit, gslMemObject mem);
|
||||
bool setOutput(uint32 physUnit, gslMemObject mem);
|
||||
bool setConstantBuffer(uint32 physUnit, gslMemObject mem, CALuint offset, size_t size);
|
||||
bool setUAVBuffer(uint32 physUnit, gslMemObject mem, gslUAVType uavType);
|
||||
void setUAVChannelOrder(uint32 physUnit, gslMemObject mem);
|
||||
bool isDone(GpuEvent* event);
|
||||
void waitForEvent(GpuEvent* event);
|
||||
void flushCUCaches(bool flushL2 = false) const;
|
||||
void eventBegin(EngineType engId)
|
||||
{
|
||||
m_eventQueue[engId].begin();
|
||||
const static bool Begin = true;
|
||||
profileEvent(engId, Begin);
|
||||
}
|
||||
void eventEnd(EngineType engId, GpuEvent& event)
|
||||
{
|
||||
const static bool End = false;
|
||||
profileEvent(engId, End);
|
||||
event.id = m_eventQueue[engId].end();
|
||||
event.engineId_ = engId;
|
||||
}
|
||||
|
||||
bool copyPartial(GpuEvent& event, gslMemObject srcMem, size_t* srcOffset,
|
||||
gslMemObject destMem, size_t* destOffset, size_t* size, CALmemcopyflags flags, bool enableRectCopy, uint32 bytesPerElement);
|
||||
|
||||
void setSamplerParameter(uint32 sampler, gslTexParameterPname param, CALvoid* vals);
|
||||
|
||||
bool recompileShader(CALimage srcImage, CALimage* newImage, const CALuint type);
|
||||
bool getMachineType(CALuint* pMachine, CALuint* pType, CALimage image);
|
||||
|
||||
bool moduleLoad(CALimage image, gslProgramObject* func, gslMemObject* constants);
|
||||
|
||||
gsl::gsCtx* cs() const { return m_cs; }
|
||||
gslRenderState rs() const { return m_rs; }
|
||||
|
||||
/// HW Debug support functions
|
||||
void InvalidateSqCaches(bool instInvalidate = true, bool dataInvalidate = true, bool tcL1 = true, bool tcL2 = true);
|
||||
|
||||
protected:
|
||||
void setScratchBuffer(gslMemObject mem, int32 engineId);
|
||||
virtual void profileEvent(EngineType engine, bool type) const {}
|
||||
|
||||
CALwaitType m_waitType; //!< Wait type
|
||||
|
||||
private:
|
||||
enum {
|
||||
MAX_OUTPUTS = 12,
|
||||
MAX_CONSTANTBUFFERS = 20,
|
||||
MAX_APICONSTANTBUFFERS = 16,
|
||||
MAX_SAMPLERS = 16,
|
||||
MAX_RESOURCES = 128,
|
||||
MAX_SCRATCHBUFFERS = 1,
|
||||
MAX_SHADERENGINES = 4,
|
||||
MAX_UAVS = 1024,
|
||||
};
|
||||
|
||||
const CALGSLDevice* m_Dev;
|
||||
const CALGSLDevice* dev() const { return m_Dev; }
|
||||
|
||||
gsl::gsCtx* m_cs;
|
||||
gslRenderState m_rs;
|
||||
gslConstantBufferObject m_constantBuffers[MAX_CONSTANTBUFFERS];
|
||||
gslUAVObject m_uavResources[MAX_UAVS];
|
||||
gslTextureResourceObject m_textureResources[MAX_RESOURCES];
|
||||
gslSamplerObject m_textureSamplers[MAX_SAMPLERS];
|
||||
gslDrawBuffers m_drawBuffers;
|
||||
gslScratchBufferObject m_scratchBuffers;
|
||||
EventQueue m_eventQueue[AllEngines];
|
||||
bool m_allowDMA;
|
||||
};
|
||||
|
||||
#endif // __GSLContext_h__
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,258 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __GSLDevice_h__
|
||||
#define __GSLDevice_h__
|
||||
|
||||
#include "backend.h"
|
||||
#include "atitypes.h"
|
||||
#include "gsl_types.h"
|
||||
#include "gsl_config.h"
|
||||
#include "thread/monitor.hpp"
|
||||
#include "gsl_types_internal.h"
|
||||
|
||||
#ifdef ATI_OS_LINUX
|
||||
typedef unsigned int IDirect3DDevice9;
|
||||
typedef unsigned int IDirect3DSurface9;
|
||||
typedef unsigned int IDirect3DQuery9;
|
||||
typedef unsigned int RECT;
|
||||
#else
|
||||
#undef APIENTRY
|
||||
#include <d3d9.h>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace gsl
|
||||
{
|
||||
class gsAdaptor;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USE_NONE,
|
||||
USE_CPDMA,
|
||||
USE_DRMDMA,
|
||||
USE_DRMDMA_L2T,
|
||||
USE_DRMDMA_T2L,
|
||||
} CopyType;
|
||||
|
||||
class CALGSLDevice
|
||||
{
|
||||
public:
|
||||
struct GLResAssociate {
|
||||
void* GLContext; //(IN) handle to HGLRC or GLXContext
|
||||
void* GLdeviceContext; //(IN) a handle to device context
|
||||
uint name; //(IN) gl identifier of the object
|
||||
uint type; // (IN) type of the interop object .
|
||||
uint flags; // (IN) flags assigned to 'GLResource' struct
|
||||
void* mbResHandle; // (OUT) Internal GL driver handle for the resource
|
||||
gslMemObject mem_base; // (OUT) Base memory object for the resource
|
||||
gslMemObject memObject; //(OUT) Alias gsl memory object for the resource
|
||||
gslMemObject fMaskObject; //(OUT) gsl memobject of the an MSAA resource F-mask.
|
||||
};
|
||||
|
||||
struct OpenParams {
|
||||
bool enableHighPerformanceState;
|
||||
bool reportAsOCL12Device;
|
||||
const char* sclkThreshold;
|
||||
const char* downHysteresis;
|
||||
const char* upHysteresis;
|
||||
const char* powerLimit;
|
||||
const char* mclkThreshold;
|
||||
const char* mclkUpHyst;
|
||||
const char* mclkDownHyst;
|
||||
};
|
||||
|
||||
CALGSLDevice();
|
||||
~CALGSLDevice();
|
||||
|
||||
bool open(uint32 gpuIndex, OpenParams& openData);
|
||||
void close();
|
||||
|
||||
gslMemObject resAlloc(const CALresourceDesc* desc) const;
|
||||
void* resMapLocal(size_t& pitch, gslMemObject mem, gslMapAccessType flags);
|
||||
void resUnmapLocal(gslMemObject mem);
|
||||
|
||||
void resFree(gslMemObject mem) const;
|
||||
void* resMapRemote(size_t& pitch, gslMemObject mem, gslMapAccessType flags) const;
|
||||
void resUnmapRemote(gslMemObject mem) const;
|
||||
|
||||
gslMemObject resGetHeap(size_t size) const;
|
||||
gslMemObject resAllocView(gslMemObject res, gslResource3D size,
|
||||
size_t offset, cmSurfFmt format, gslChannelOrder channelOrder,
|
||||
gslMemObjectAttribType resType, uint32 level, uint32 layer,
|
||||
uint32 flags, uint64 bytePitch = (uint64)-1) const;
|
||||
|
||||
bool associateD3D11Device(void* d3d11Device); //void* is of type ID3D11Device*
|
||||
bool associateD3D10Device(void* d3d10Device); //void* is of type ID3D10Device*
|
||||
bool associateD3D9Device(void* d3d9Device); //void* is of type IDirect3DDevice9*
|
||||
|
||||
gslMemObject resMapD3DResource(
|
||||
const CALresourceDesc* desc, uint64 sharedhandle, bool displayable) const;
|
||||
|
||||
bool glAssociate(CALvoid *GLplatformContext, CALvoid* GLdeviceContext);
|
||||
bool glDissociate(CALvoid *GLplatformContext, CALvoid* GLdeviceContext);
|
||||
//! @brief This function is called once for every interop resource on the first clEnqeueuAcquireGL.
|
||||
bool resGLAssociate(GLResAssociate & resData) const;
|
||||
//! @brief This function is called once for every interop resource on resource destruction.
|
||||
bool resGLFree (CALvoid* GLplatformContext,
|
||||
CALvoid* GLdeviceContext, gslMemObject mem, gslMemObject mem_base,
|
||||
CALvoid* mbResHandle, CALuint type) const;
|
||||
//! @brief Decompresses depth/MSAA surfaces.This function is called on every 'clEnqeueuAcquireGLObject'.
|
||||
bool resGLAcquire( CALvoid* GLplatformContext, CALvoid* mbResHandle, CALuint type) const;
|
||||
//! @brief This function is called on every 'clEnqeueuReleaseGLObject'.
|
||||
bool resGLRelease(CALvoid* GLplatformContext, CALvoid* mbResHandle, CALuint type) const;
|
||||
|
||||
gsl::gsAdaptor* getNative() const;
|
||||
CALuint getElfMachine() const { return m_elfmachine; };
|
||||
uint32 getGpuIndex() const { return m_gpuIndex; };
|
||||
|
||||
uint32 getMaxTextureSize() const;
|
||||
const CALdeviceattribs& getAttribs() const { return m_attribs; }
|
||||
const gslMemInfo& getMemInfo() const { return m_memInfo; }
|
||||
|
||||
uint32 getVPUMask() const { return m_vpuMask; }
|
||||
bool canDMA() const { return m_canDMA; }
|
||||
gslMemObject m_srcDRMDMAMem, m_dstDRMDMAMem; // memory object of flush buffer, used for DRMDMA flush
|
||||
|
||||
void PerformAdapterInitialization(bool ValidateOnly);
|
||||
void PerformFullInitialization() const;
|
||||
void CloseInitializedAdapter(bool ValidateOnly);
|
||||
|
||||
CopyType GetCopyType(gslMemObject srcMem, gslMemObject destMem, size_t* srcOffset,
|
||||
size_t* destOffset, bool allowDMA, uint32 flags, size_t size, bool enableCopyRect) const;
|
||||
|
||||
uint64 calcScratchBufferSize(uint32 regNum) const;
|
||||
|
||||
amd::Monitor& gslDeviceOps() const { return *gslDeviceOps_; }
|
||||
|
||||
void fillImageHwState(gslMemObject mem, void* hwState, uint32 hwStateSize) const;
|
||||
|
||||
void fillSamplerHwState(bool unnorm, uint32 min, uint32 mag, uint32 addr,
|
||||
float minLod, float maxLod, void* hwState, uint32 hwStateSize) const;
|
||||
|
||||
gslSamplerObject txSampler() const { return m_textureSampler; }
|
||||
|
||||
void convertInputChannelOrder(intp *channelOrder) const;
|
||||
|
||||
gsl::gsCtx* gslCtx() const { return m_cs; }
|
||||
|
||||
bool isComputeRingIDForced() const { return m_isComputeRingIDForced; }
|
||||
gslEngineID getforcedComputeEngineID() const { return m_forcedComputeEngineID; }
|
||||
|
||||
gslEngineID getFirstAvailableComputeEngineID() const { return static_cast<gslEngineID>(
|
||||
m_adp->findFirstAvailableComputeEngineID()); }
|
||||
|
||||
virtual bool gslSetClockMode(GSLClockModeInfo * clockModeInfo);
|
||||
protected:
|
||||
//
|
||||
/// channel order enumerants
|
||||
//
|
||||
//channelSwizzleMode and channelSwizzle match the hwl equivalent hwtxSwizzleMode and hwtxUnitSwizzle in hwl_tx_if.h.
|
||||
enum channelSwizzleMode {
|
||||
SWIZZLE_COMPONENT0, ///< Select Component0
|
||||
SWIZZLE_COMPONENT1, ///< Select Component1
|
||||
SWIZZLE_COMPONENT2, ///< Select Component2
|
||||
SWIZZLE_COMPONENT3, ///< Select Component3
|
||||
SWIZZLE_ZERO, ///< Select Zero
|
||||
SWIZZLE_ONE, ///< Select One
|
||||
};
|
||||
|
||||
//
|
||||
/// channel order swizzle type
|
||||
//
|
||||
typedef struct channelSwizzleRec
|
||||
{
|
||||
channelSwizzleMode r : 8; ///< Red channel of texture
|
||||
channelSwizzleMode g : 8; ///< Green channel of texture
|
||||
channelSwizzleMode b : 8; ///< Blue channel of texture
|
||||
channelSwizzleMode a : 8; ///< Alpha channel of texture
|
||||
} channelSwizzle;
|
||||
|
||||
uint m_nEngines;
|
||||
gslEngineDescriptor m_engines[GSL_ENGINEID_MAX];
|
||||
|
||||
private:
|
||||
gsl::gsAdaptor* m_adp;
|
||||
gsl::gsCtx* m_cs;
|
||||
gslRenderState m_rs;
|
||||
CALtarget m_target;
|
||||
CALuint m_elfmachine;
|
||||
uint32 m_vpuMask;
|
||||
uint32 m_chainIndex;
|
||||
int32 m_maxtexturesize;
|
||||
uint32 m_gpuIndex;
|
||||
void* m_nativeDisplayHandle;
|
||||
|
||||
gslDeviceModeEnum m_deviceMode;
|
||||
|
||||
typedef std::map<gslMemObject, intp> Hack;
|
||||
Hack m_hack;
|
||||
gslQueryObject m_mapQuery;
|
||||
gslQueryObject m_mapDMAQuery;
|
||||
|
||||
gslStaticRuntimeConfig m_scfg;
|
||||
gslDynamicRuntimeConfig m_dcfg;
|
||||
|
||||
//GL Extension specific
|
||||
bool initGLInteropPrivateExt(CALvoid* GLplatformContext, CALvoid* GLdeviceContext) const;
|
||||
bool glCanInterop(CALvoid* GLplatformContext, CALvoid* GLdeviceContext);
|
||||
|
||||
bool PerformDMACopy(gslMemObject srcMem, gslMemObject destMem, cmSurfFmt format, CALuint flags, bool isHwDebug = false);
|
||||
void Initialize(void);
|
||||
|
||||
bool SetupAdapter(int32 &asic_id);
|
||||
bool SetupContext(int32 &asic_id);
|
||||
void PerformAdapterInitialization_int(bool initLite);
|
||||
void PerformFullInitialization_int();
|
||||
|
||||
void getAttribs_int(gsl::gsCtx* cs);
|
||||
bool ResolveAperture(const gslMemObjectAttribTiling tiling) const;
|
||||
|
||||
void parsePowerParam(const char* element, gslRuntimeConfigUint32Value& pwrCount, gslRuntimeConfigUint32pValue& pwrPointer);
|
||||
|
||||
CALdeviceattribs m_attribs;
|
||||
gslMemInfo m_memInfo;
|
||||
gslTextureResourceObject m_textureResource;
|
||||
gslSamplerObject m_textureSampler;
|
||||
gslEngineID m_forcedComputeEngineID;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint m_canDMA : 1;
|
||||
uint m_allowDMA : 1;
|
||||
uint m_computeRing : 1;
|
||||
uint m_usePerVPUAdapterModel : 1;
|
||||
uint m_PerformLazyDeviceInit : 1;
|
||||
uint m_isComputeRingIDForced : 1;
|
||||
uint m_isSDMAL2TConstrained : 1;
|
||||
uint m_initLite : 1;
|
||||
uint m_fullInitialized : 1;
|
||||
};
|
||||
|
||||
uint m_flags;
|
||||
};
|
||||
|
||||
amd::Monitor* gslDeviceOps_; //!< Lock to serialize GSL device
|
||||
};
|
||||
|
||||
#endif // __GSLDevice_h__
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "gsl_ctx.h"
|
||||
#include "GSLDevice.h"
|
||||
|
||||
#if defined(ATI_OS_WIN)
|
||||
|
||||
#include <D3D10_1.h>
|
||||
|
||||
/**************************************************************************************************************
|
||||
* Note: ideally the DXX extension interfaces should be mapped from the DXX perforce branch.
|
||||
* This means CAL client spec will need to change to include headers directly from the DXX perforce tree.
|
||||
* However, CAL only cares about the DXX OpenCL extension interface class. The spec cannot change
|
||||
* without notification. So it is safe to use a local copy of the relevant DXX extension interface classes.
|
||||
**************************************************************************************************************/
|
||||
#include "DxxOpenCLInteropExt.h"
|
||||
|
||||
static bool
|
||||
queryD3D10DeviceGPUMask(ID3D10Device* pd3d10Device, UINT* pd3d10DeviceGPUMask)
|
||||
{
|
||||
HMODULE hDLL = NULL;
|
||||
IAmdDxExt* pExt = NULL;
|
||||
IAmdDxExtCLInterop* pCLExt = NULL;
|
||||
PFNAmdDxExtCreate AmdDxExtCreate;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Get a handle to the DXX DLL with extension API support
|
||||
#if defined _WIN64
|
||||
static const CHAR dxxModuleName[13] = "atidxx64.dll";
|
||||
#else
|
||||
static const CHAR dxxModuleName[13] = "atidxx32.dll";
|
||||
#endif
|
||||
|
||||
hDLL = GetModuleHandle(dxxModuleName);
|
||||
|
||||
if (hDLL == NULL)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
// Get the exported AmdDxExtCreate() function pointer
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
AmdDxExtCreate = reinterpret_cast<PFNAmdDxExtCreate>(GetProcAddress(hDLL, "AmdDxExtCreate"));
|
||||
if (AmdDxExtCreate == NULL)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the extension object
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = AmdDxExtCreate(pd3d10Device, &pExt);
|
||||
}
|
||||
|
||||
// Get the extension version information
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
AmdDxExtVersion extVersion;
|
||||
hr = pExt->GetVersion(&extVersion);
|
||||
|
||||
if (extVersion.majorVersion == 0)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the OpenCL Interop interface
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pCLExt = static_cast<IAmdDxExtCLInterop*>(pExt->GetExtInterface(AmdDxExtCLInteropID));
|
||||
if (pCLExt != NULL)
|
||||
{
|
||||
// Get the GPU mask using the CL Interop extension.
|
||||
pCLExt->QueryInteropGpuMask(pd3d10DeviceGPUMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCLExt != NULL)
|
||||
{
|
||||
pCLExt->Release();
|
||||
}
|
||||
|
||||
if (pExt != NULL)
|
||||
{
|
||||
pExt->Release();
|
||||
}
|
||||
|
||||
return (SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLDevice::associateD3D10Device(void* d3d10Device)
|
||||
{
|
||||
bool canInteroperate = false;
|
||||
|
||||
LUID calDevAdapterLuid = {0, 0};
|
||||
UINT calDevChainBitMask = 0;
|
||||
UINT d3d10DeviceGPUMask = 0;
|
||||
|
||||
ID3D10Device* pd3d10Device = static_cast<ID3D10Device*>(d3d10Device);
|
||||
|
||||
IDXGIDevice* pDXGIDevice;
|
||||
pd3d10Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
|
||||
|
||||
IDXGIAdapter* pDXGIAdapter;
|
||||
pDXGIDevice->GetAdapter(&pDXGIAdapter);
|
||||
|
||||
DXGI_ADAPTER_DESC adapterDesc;
|
||||
pDXGIAdapter->GetDesc(&adapterDesc);
|
||||
|
||||
// match the adapter
|
||||
if (m_adp->getMVPUinfo(&calDevAdapterLuid, &calDevChainBitMask))
|
||||
{
|
||||
canInteroperate = ((calDevAdapterLuid.HighPart == adapterDesc.AdapterLuid.HighPart) &&
|
||||
(calDevAdapterLuid.LowPart == adapterDesc.AdapterLuid.LowPart));
|
||||
}
|
||||
|
||||
// match the chain ID
|
||||
if (canInteroperate)
|
||||
{
|
||||
if (queryD3D10DeviceGPUMask(pd3d10Device, &d3d10DeviceGPUMask))
|
||||
{
|
||||
canInteroperate = (calDevChainBitMask & d3d10DeviceGPUMask) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// special handling for Intel iGPU + AMD dGPU in LDA mode (only occurs on a PX platform) where
|
||||
// the D3D10Device object is created on the Intel iGPU and passed to AMD dGPU (secondary) to interoperate.
|
||||
if (calDevChainBitMask > 1)
|
||||
{
|
||||
canInteroperate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pDXGIDevice->Release();
|
||||
pDXGIAdapter->Release();
|
||||
|
||||
return canInteroperate;
|
||||
}
|
||||
|
||||
gslMemObject
|
||||
CALGSLDevice::resMapD3DResource(const CALresourceDesc* desc, uint64 sharedhandle, bool displayable) const
|
||||
{
|
||||
//! @note: GSL device isn't thread safe
|
||||
amd::ScopedLock k(gslDeviceOps_);
|
||||
|
||||
gslMemObject mem = NULL;
|
||||
|
||||
gslMemObjectAttribs attribs(
|
||||
GSL_MOA_TEXTURE_2D, // type
|
||||
GSL_MOA_MEMORY_ALIAS, // location
|
||||
GSL_MOA_TILING_TILED, // tiling
|
||||
GSL_MOA_DISPLAYABLE_NO, // displayable
|
||||
ATIGL_FALSE, // mipmap
|
||||
1, // samples
|
||||
0, // cpu_address
|
||||
GSL_MOA_SIGNED_NO, // signed_format
|
||||
GSL_MOA_FORMAT_DERIVED, // numFormat
|
||||
DRIVER_MODULE_GLL, // module
|
||||
GSL_ALLOCATION_INSTANCED // alloc_type
|
||||
);
|
||||
|
||||
HANDLE h = (HANDLE)sharedhandle;
|
||||
attribs.cpu_address = h;
|
||||
attribs.alias_swizzle = 0;
|
||||
attribs.channelOrder = desc->channelOrder;
|
||||
attribs.type = desc->dimension;
|
||||
|
||||
switch (desc->dimension)
|
||||
{
|
||||
case GSL_MOA_BUFFER:
|
||||
attribs.tiling = GSL_MOA_TILING_LINEAR;
|
||||
mem = m_cs->createMemObject1D(desc->format, desc->size.width, &attribs);
|
||||
break;
|
||||
case GSL_MOA_TEXTURE_1D:
|
||||
attribs.tiling = GSL_MOA_TILING_LINEAR;
|
||||
mem = m_cs->createMemObject1D(desc->format, desc->size.width, &attribs);
|
||||
break;
|
||||
case GSL_MOA_TEXTURE_2D:
|
||||
{
|
||||
uint32 height = (uint32)desc->size.height;
|
||||
if (displayable)
|
||||
{
|
||||
attribs.displayable = GSL_MOA_DISPLAYABLE_YES;
|
||||
}
|
||||
mem = m_cs->createMemObject2D(desc->format, desc->size.width, height, &attribs);
|
||||
}
|
||||
break;
|
||||
case GSL_MOA_TEXTURE_3D:
|
||||
mem = m_cs->createMemObject3D(desc->format, desc->size.width,
|
||||
(uint32)desc->size.height, (uint32)desc->size.depth, &attribs);
|
||||
break;
|
||||
case GSL_MOA_TEXTURE_BUFFER:
|
||||
attribs.type = GSL_MOA_TEXTURE_BUFFER;
|
||||
mem = m_cs->createMemObject1D(desc->format, desc->size.width, &attribs);
|
||||
break;
|
||||
case GSL_MOA_TEXTURE_1D_ARRAY:
|
||||
mem = m_cs->createMemObject3D(desc->format, desc->size.width,
|
||||
1, (uint32)desc->size.height, &attribs);
|
||||
break;
|
||||
case GSL_MOA_TEXTURE_2D_ARRAY:
|
||||
mem = m_cs->createMemObject3D(desc->format, desc->size.width,
|
||||
(uint32)desc->size.height, (uint32)desc->size.depth, &attribs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
#else // !ATI_OS_WIN
|
||||
|
||||
bool
|
||||
CALGSLDevice::associateD3D10Device(void* d3d10Device)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
gslMemObject
|
||||
CALGSLDevice::resMapD3DResource(const CALresourceDesc* desc, uint64 sharedhandle, bool displayable) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // !ATI_OS_WIN
|
||||
@@ -1,174 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "gsl_ctx.h"
|
||||
#include "GSLDevice.h"
|
||||
|
||||
#if defined(ATI_OS_WIN)
|
||||
|
||||
#include <D3D11.h>
|
||||
|
||||
/**************************************************************************************************************
|
||||
* Note: ideally the DXX extension interfaces should be mapped from the DXX perforce branch.
|
||||
* This means CAL client spec will need to change to include headers directly from the DXX perforce tree.
|
||||
* However, CAL only cares about the DXX OpenCL extension interface class. The spec cannot change
|
||||
* without notification. So it is safe to use a local copy of the relevant DXX extension interface classes.
|
||||
**************************************************************************************************************/
|
||||
#include "DxxOpenCLInteropExt.h"
|
||||
|
||||
static bool
|
||||
queryD3D11DeviceGPUMask(ID3D11Device* pd3d11Device, UINT* pd3d11DeviceGPUMask)
|
||||
{
|
||||
HMODULE hDLL = NULL;
|
||||
IAmdDxExt* pExt = NULL;
|
||||
IAmdDxExtCLInterop* pCLExt = NULL;
|
||||
PFNAmdDxExtCreate11 AmdDxExtCreate11;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Get a handle to the DXX DLL with extension API support
|
||||
#if defined _WIN64
|
||||
static const CHAR dxxModuleName[13] = "atidxx64.dll";
|
||||
#else
|
||||
static const CHAR dxxModuleName[13] = "atidxx32.dll";
|
||||
#endif
|
||||
|
||||
hDLL = GetModuleHandle(dxxModuleName);
|
||||
|
||||
if (hDLL == NULL)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
// Get the exported AmdDxExtCreate() function pointer
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
AmdDxExtCreate11 = reinterpret_cast<PFNAmdDxExtCreate11>(GetProcAddress(hDLL, "AmdDxExtCreate11"));
|
||||
if (AmdDxExtCreate11 == NULL)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the extension object
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = AmdDxExtCreate11(pd3d11Device, &pExt);
|
||||
}
|
||||
|
||||
// Get the extension version information
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
AmdDxExtVersion extVersion;
|
||||
hr = pExt->GetVersion(&extVersion);
|
||||
|
||||
if (extVersion.majorVersion == 0)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the OpenCL Interop interface
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pCLExt = static_cast<IAmdDxExtCLInterop*>(pExt->GetExtInterface(AmdDxExtCLInteropID));
|
||||
if (pCLExt != NULL)
|
||||
{
|
||||
// Get the GPU mask using the CL Interop extension.
|
||||
pCLExt->QueryInteropGpuMask(pd3d11DeviceGPUMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCLExt != NULL)
|
||||
{
|
||||
pCLExt->Release();
|
||||
}
|
||||
|
||||
if (pExt != NULL)
|
||||
{
|
||||
pExt->Release();
|
||||
}
|
||||
|
||||
return (SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
bool
|
||||
CALGSLDevice::associateD3D11Device(void* d3d11Device)
|
||||
{
|
||||
bool canInteroperate = false;
|
||||
|
||||
LUID calDevAdapterLuid = {0, 0};
|
||||
UINT calDevChainBitMask = 0;
|
||||
UINT d3d11DeviceGPUMask = 0;
|
||||
|
||||
ID3D11Device* pd3d11Device = static_cast<ID3D11Device*>(d3d11Device);
|
||||
|
||||
IDXGIDevice* pDXGIDevice;
|
||||
pd3d11Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
|
||||
|
||||
IDXGIAdapter* pDXGIAdapter;
|
||||
pDXGIDevice->GetAdapter(&pDXGIAdapter);
|
||||
|
||||
DXGI_ADAPTER_DESC adapterDesc;
|
||||
pDXGIAdapter->GetDesc(&adapterDesc);
|
||||
|
||||
// match the adapter
|
||||
if (m_adp->getMVPUinfo(&calDevAdapterLuid, &calDevChainBitMask))
|
||||
{
|
||||
canInteroperate = ((calDevAdapterLuid.HighPart == adapterDesc.AdapterLuid.HighPart) &&
|
||||
(calDevAdapterLuid.LowPart == adapterDesc.AdapterLuid.LowPart));
|
||||
}
|
||||
|
||||
// match the chain ID
|
||||
if (canInteroperate)
|
||||
{
|
||||
if (queryD3D11DeviceGPUMask(pd3d11Device, &d3d11DeviceGPUMask))
|
||||
{
|
||||
canInteroperate = (calDevChainBitMask & d3d11DeviceGPUMask) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// special handling for Intel iGPU + AMD dGPU in LDA mode (only occurs on a PX platform) where
|
||||
// the D3D11Device object is created on the Intel iGPU and passed to AMD dGPU (secondary) to interoperate.
|
||||
if (calDevChainBitMask > 1)
|
||||
{
|
||||
canInteroperate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pDXGIDevice->Release();
|
||||
pDXGIAdapter->Release();
|
||||
|
||||
return canInteroperate;
|
||||
}
|
||||
|
||||
#else // !ATI_OS_WIN
|
||||
|
||||
bool
|
||||
CALGSLDevice::associateD3D11Device(void* d3d11Device)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // !ATI_OS_WIN
|
||||
@@ -1,77 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "gsl_ctx.h"
|
||||
#include "GSLDevice.h"
|
||||
|
||||
#if defined(ATI_OS_WIN)
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
/**************************************************************************************************************
|
||||
* Note: ideally the DXX extension interfaces should be mapped from the DXX perforce branch.
|
||||
* This means CAL client spec will need to change to include headers directly from the DXX perforce tree.
|
||||
* However, CAL only cares about the DXX OpenCL extension interface class. The spec cannot change
|
||||
* without notification. So it is safe to use a local copy of the relevant DXX extension interface classes.
|
||||
**************************************************************************************************************/
|
||||
#include "DxxOpenCLInteropExt.h"
|
||||
|
||||
|
||||
bool
|
||||
CALGSLDevice::associateD3D9Device(void* d3d9Device)
|
||||
{
|
||||
bool canInteroperate = false;
|
||||
D3DCAPS9 pCaps;
|
||||
LUID calDevAdapterLuid = {0, 0};
|
||||
UINT calDevChainBitMask = 0;
|
||||
IDirect3D9* p3d9dev;
|
||||
LUID d3d9deviceLuid = {0, 0};
|
||||
|
||||
IDirect3DDevice9* pd3d9Device = static_cast<IDirect3DDevice9*>(d3d9Device);
|
||||
|
||||
// Get D3D9 Device caps
|
||||
pd3d9Device->GetDeviceCaps(&pCaps);
|
||||
// Get 3D9 Device
|
||||
pd3d9Device->GetDirect3D(&p3d9dev);
|
||||
|
||||
IDirect3D9Ex* p3d9devEx = static_cast<IDirect3D9Ex*>(p3d9dev);
|
||||
p3d9devEx->GetAdapterLUID(pCaps.AdapterOrdinal, &d3d9deviceLuid);
|
||||
p3d9dev->Release();
|
||||
|
||||
// match the adapter
|
||||
if (m_adp->getMVPUinfo(&calDevAdapterLuid, &calDevChainBitMask))
|
||||
{
|
||||
canInteroperate = ((calDevAdapterLuid.HighPart == d3d9deviceLuid.HighPart) &&
|
||||
(calDevAdapterLuid.LowPart == d3d9deviceLuid.LowPart));
|
||||
}
|
||||
|
||||
return canInteroperate;
|
||||
}
|
||||
|
||||
#else // !ATI_OS_WIN
|
||||
|
||||
bool
|
||||
CALGSLDevice::associateD3D9Device(void* d3d9Device)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // !ATI_OS_WIN
|
||||
La diferencia del archivo ha sido suprimido porque es demasiado grande
Cargar Diff
@@ -1,154 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "os_if.h"
|
||||
#include "osws_if.h"
|
||||
|
||||
#include "atidefines.h"
|
||||
#include "atitypes.h"
|
||||
#include "scl_types.h"
|
||||
#include "SCInterface.h"
|
||||
|
||||
//
|
||||
// This file represents the entry points that are stubbed out to satisfy the
|
||||
// linker, but aren't used in the runtime of GSL operations.
|
||||
//
|
||||
|
||||
|
||||
enum fsComponentType {
|
||||
FS_BYTE,
|
||||
FS_UNSIGNED_BYTE,
|
||||
FS_SHORT,
|
||||
FS_UNSIGNED_SHORT,
|
||||
FS_INT,
|
||||
FS_UNSIGNED_INT,
|
||||
FS_FLOAT,
|
||||
FS_FLOAT16,
|
||||
};
|
||||
|
||||
enum fsInstrSet {
|
||||
FS_INSTR_KHAN, ///< Generate Khan based instruction set
|
||||
FS_INSTR_PELE ///< Generate Pele based instruction set
|
||||
};
|
||||
|
||||
enum fsUsage {
|
||||
FS_USAGE_HW, ///< An actual hardware stream
|
||||
FS_USAGE_SW ///< A place holder stream (to support SW path)
|
||||
};
|
||||
|
||||
struct fsInstr {
|
||||
fsUsage usage; ///< How the stream is going to be used (place holder or actual hardware stream)
|
||||
uint32 components; ///< Number of components to the input vector
|
||||
fsComponentType type; ///< Type of each component
|
||||
bool32 normalize; ///< Should the components be normalized to the -1..1 range
|
||||
uint32 stride; ///< Stride between vectors
|
||||
uint32 ivmOffset; ///< location in input vector memory
|
||||
};
|
||||
|
||||
|
||||
sclHandle CONV
|
||||
sclInit(const sclShaderConstantAddress* shaderStateConstTable,
|
||||
const sclProfile& profile,
|
||||
const sclLimits& fpLimits,
|
||||
const sclLimits& vpLimits)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CONV
|
||||
sclDestroy(sclHandle hSCL)
|
||||
{
|
||||
}
|
||||
|
||||
sclProgram* CONV
|
||||
sclCompile(sclHandle hSCL,
|
||||
const sclInputShader& shader,
|
||||
const sclCompilerParams& params,
|
||||
const sclLimits& limits)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sclProgramPair* CONV
|
||||
sclLink(sclHandle hSCL,
|
||||
const sclInputMultShaderPair *shader,
|
||||
const sclCompilerParams& params,
|
||||
const sclLimits& fpLimits,
|
||||
const sclLimits& vpLimits)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CONV
|
||||
sclFreeProgram(sclHandle hSCL,
|
||||
sclProgram* program)
|
||||
{
|
||||
}
|
||||
|
||||
sclShaderReplaceHandle CONV
|
||||
sclRegisterShaderString(sclHandle hSCL,
|
||||
const sclInputShader& src,
|
||||
const sclInputShader& dst)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CONV
|
||||
sclUnregisterShaderString(sclHandle hSCL,
|
||||
sclShaderReplaceHandle hReplacement)
|
||||
{
|
||||
}
|
||||
|
||||
bool32 CONV
|
||||
fsCompile(fsInstrSet instrSet,
|
||||
uint32 instrCount,
|
||||
const fsInstr* instr,
|
||||
void*& binary,
|
||||
uint32& length,
|
||||
bool32 dumpShader,
|
||||
bool32 doCacheOpt,
|
||||
const sclCompilerParamTessellation& tessParams)
|
||||
{
|
||||
return ATIGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void CONV
|
||||
fsFreeBinary(void* binary)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CONV
|
||||
oswsInit(HOSInstance hOSInst)
|
||||
{
|
||||
//
|
||||
// do nothing...
|
||||
//
|
||||
}
|
||||
|
||||
void CONV
|
||||
oswsExit()
|
||||
{
|
||||
//
|
||||
// do nothing...
|
||||
//
|
||||
}
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "gsl_ctx.h"
|
||||
#include "GSLContext.h"
|
||||
#include "backend.h"
|
||||
#include "GSLDevice.h"
|
||||
#include "amuABI.h"
|
||||
|
||||
bool
|
||||
getFuncInfoFromImage(CALimage image, CALfuncInfo *pFuncInfo)
|
||||
{
|
||||
if (image == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pFuncInfo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Initialize the pFuncInfo
|
||||
pFuncInfo->maxScratchRegsNeeded = 0;
|
||||
pFuncInfo->numSharedGPRUser = 0;
|
||||
pFuncInfo->numSharedGPRTotal = 0;
|
||||
pFuncInfo->numThreadPerGroup = 0;
|
||||
pFuncInfo->numThreadPerGroupX = 0;
|
||||
pFuncInfo->numThreadPerGroupY = 0;
|
||||
pFuncInfo->numThreadPerGroupZ = 0;
|
||||
pFuncInfo->totalNumThreadGroup = 0;
|
||||
pFuncInfo->numWavefrontPerSIMD = 0;
|
||||
pFuncInfo->setBufferForNumGroup = false;
|
||||
pFuncInfo->wavefrontSize = 0;
|
||||
pFuncInfo->numGPRsAvailable = 0;
|
||||
pFuncInfo->numGPRsUsed = 0;
|
||||
pFuncInfo->numSGPRsAvailable = 0;
|
||||
pFuncInfo->numSGPRsUsed = 0;
|
||||
pFuncInfo->numVGPRsAvailable = 0;
|
||||
pFuncInfo->numVGPRsUsed = 0;
|
||||
pFuncInfo->LDSSizeAvailable = 0;
|
||||
pFuncInfo->LDSSizeUsed = 0;
|
||||
pFuncInfo->stackSizeAvailable = 0;
|
||||
pFuncInfo->stackSizeUsed = 0;
|
||||
|
||||
//read data from image file
|
||||
AMUabiMultiBinary mb;
|
||||
amuABIMultiBinaryCreate(&mb);
|
||||
if (!amuABIMultiBinaryUnpack(mb, (void*) image))
|
||||
{
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int encodingCount;
|
||||
if (!amuABIMultiBinaryGetEncodingCount(&encodingCount, mb))
|
||||
{
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
return false;
|
||||
}
|
||||
|
||||
AMUabiEncoding encoding;
|
||||
//get encoding info for the first encoding
|
||||
if ((encodingCount > 0)&& !amuABIMultiBinaryGetEncoding( &encoding, mb, 0))
|
||||
{
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int machine, type;
|
||||
if (!amuABIEncodingGetSignature(&machine, &type, encoding))
|
||||
{
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!amuABIMultiBinaryFindEncoding(&encoding, mb, machine, type))
|
||||
{
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int progInfosCount = 0;
|
||||
CALProgramInfoEntry* pInfos = 0;
|
||||
if (!amuABIEncodingGetProgInfos(&progInfosCount, &pInfos, encoding))
|
||||
{
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (CALuint i =0; i < progInfosCount; i++)
|
||||
{
|
||||
switch(pInfos[i].address)
|
||||
{
|
||||
case AMU_ABI_CS_MAX_SCRATCH_REGS:
|
||||
pFuncInfo->maxScratchRegsNeeded = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_CS_NUM_SHARED_GPR_USER:
|
||||
pFuncInfo->numSharedGPRUser = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_CS_NUM_SHARED_GPR_TOTAL:
|
||||
pFuncInfo->numSharedGPRTotal = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_ECS_SETUP_MODE:
|
||||
break;
|
||||
case AMU_ABI_NUM_THREAD_PER_GROUP:
|
||||
pFuncInfo->numThreadPerGroup = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_NUM_THREAD_PER_GROUP_X:
|
||||
pFuncInfo->numThreadPerGroupX = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_NUM_THREAD_PER_GROUP_Y:
|
||||
pFuncInfo->numThreadPerGroupY = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_NUM_THREAD_PER_GROUP_Z:
|
||||
pFuncInfo->numThreadPerGroupZ = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_TOTAL_NUM_THREAD_GROUP:
|
||||
pFuncInfo->totalNumThreadGroup = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_NUM_WAVEFRONT_PER_SIMD:
|
||||
case AMU_ABI_MAX_WAVEFRONT_PER_SIMD: //CAL_USE_SC_PRM
|
||||
pFuncInfo->numWavefrontPerSIMD = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_IS_MAX_NUM_WAVE_PER_SIMD:
|
||||
break;
|
||||
case AMU_ABI_SET_BUFFER_FOR_NUM_GROUP:
|
||||
pFuncInfo->setBufferForNumGroup = (0 != pInfos[i].value) ? true : false;
|
||||
break;
|
||||
case AMU_ABI_WAVEFRONT_SIZE:
|
||||
pFuncInfo->wavefrontSize = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_NUM_GPR_AVAIL:
|
||||
pFuncInfo->numGPRsAvailable = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_NUM_GPR_USED:
|
||||
pFuncInfo->numGPRsUsed = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_LDS_SIZE_AVAIL:
|
||||
pFuncInfo->LDSSizeAvailable = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_LDS_SIZE_USED:
|
||||
pFuncInfo->LDSSizeUsed = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_STACK_SIZE_AVAIL:
|
||||
pFuncInfo->stackSizeAvailable = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_STACK_SIZE_USED:
|
||||
pFuncInfo->stackSizeUsed = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_SI_NUM_SGPRS_AVAIL:
|
||||
pFuncInfo->numSGPRsAvailable = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_SI_NUM_SGPRS:
|
||||
pFuncInfo->numSGPRsUsed = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_SI_NUM_VGPRS_AVAIL:
|
||||
pFuncInfo->numVGPRsAvailable = pInfos[i].value;
|
||||
break;
|
||||
case AMU_ABI_SI_NUM_VGPRS:
|
||||
pFuncInfo->numVGPRsUsed = pInfos[i].value;
|
||||
break;
|
||||
|
||||
default:
|
||||
//GSLAssert(0 && "Unknown address in program info");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
amuABIEncodingGetScratchRegisterCount(&pFuncInfo->maxScratchRegsNeeded, encoding);
|
||||
|
||||
amuABIMultiBinaryDestroy(mb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gslMemObjectAttribTiling g_CALBETiling_Tiled = GSL_MOA_TILING_TILED;
|
||||
@@ -1,225 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __BACKEND_H__
|
||||
#define __BACKEND_H__
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
//internal
|
||||
#include "gsl_enum.h"
|
||||
#include "gsl_types.h"
|
||||
#include "cm_enum.h"
|
||||
#include "caltarget.h"
|
||||
|
||||
typedef void CALvoid; /**< void type */
|
||||
typedef char CALchar; /**< ASCII character */
|
||||
typedef signed char CALbyte; /**< 1 byte signed integer value */
|
||||
typedef unsigned char CALubyte; /**< 1 byte unsigned integer value */
|
||||
typedef signed short CALshort; /**< 2 byte signed integer value */
|
||||
typedef unsigned short CALushort; /**< 2 byte unsigned integer value */
|
||||
typedef signed int CALint; /**< 4 byte signed integer value */
|
||||
typedef unsigned int CALuint; /**< 4 byte unsigned intger value */
|
||||
typedef float CALfloat; /**< 32-bit IEEE floating point value */
|
||||
typedef double CALdouble; /**< 64-bit IEEE floating point value */
|
||||
typedef signed long CALlong; /**< long value */
|
||||
typedef unsigned long CALulong; /**< unsigned long value */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
typedef signed __int64 CALint64; /**< 8 byte signed integer value */
|
||||
typedef unsigned __int64 CALuint64; /**< 8 byte unsigned integer value */
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
typedef signed long long CALint64; /**< 8 byte signed integer value */
|
||||
typedef unsigned long long CALuint64; /**< 8 byte unsigned integer value */
|
||||
|
||||
#else
|
||||
#error "Unsupported compiler type."
|
||||
#endif
|
||||
|
||||
/** Boolean type */
|
||||
typedef enum CALbooleanEnum {
|
||||
CAL_FALSE = 0, /**< Boolean false value */
|
||||
CAL_TRUE = 1 /**< Boolean true value */
|
||||
} CALboolean;
|
||||
|
||||
/** CAL image container */
|
||||
typedef struct CALimageRec* CALimage;
|
||||
|
||||
#define CAL_ASIC_INFO_MAX_LEN 128
|
||||
#define CAL_DRIVER_STORE_MAX_LEN 200
|
||||
|
||||
/** CAL device attributes */
|
||||
typedef struct CALdeviceattribsRec {
|
||||
CALuint struct_size; /**< Client filled out size of CALdeviceattribs struct */
|
||||
CALtarget target; /**< Asic identifier */
|
||||
CALuint localRAM; /**< Amount of local GPU RAM in megabytes */
|
||||
CALuint uncachedRemoteRAM; /**< Amount of uncached remote GPU memory in megabytes */
|
||||
CALuint cachedRemoteRAM; /**< Amount of cached remote GPU memory in megabytes */
|
||||
CALuint engineClock; /**< GPU device clock rate in megahertz */
|
||||
CALuint memoryClock; /**< GPU memory clock rate in megahertz */
|
||||
CALuint wavefrontSize; /**< Wavefront size */
|
||||
CALuint numberOfSIMD; /**< Number of SIMDs */
|
||||
CALuint numberOfCUsperShaderArray; /**< Number of CUs per shader array */
|
||||
bool doublePrecision; /**< double precision supported */
|
||||
CALuint numberOfShaderEngines; /**< Number of shader engines */
|
||||
CALuint totalVisibleHeap; /**< Amount of visible local GPU RAM in megabytes */
|
||||
CALuint totalInvisibleHeap; /**< Amount of invisible local GPU RAM in megabytes */
|
||||
CALuint totalDirectHeap; /**< Amount of direct GPU memory in megabytes */
|
||||
CALuint totalCoherentHeap; /**< Amount of coherent GPU memory in megabytes */
|
||||
CALuint totalRemoteSharedHeap; /**< Amount of remote Shared GPU memory in megabytes */
|
||||
CALuint totalCachedRemoteSharedHeap; /**< Amount of cached remote Shared GPU memory in megabytes */
|
||||
CALuint totalSDIHeap; /**< Amount of SDI memory allocated in CCC */
|
||||
CALuint pciTopologyInformation; /**< PCI topology information contains: bus, device and function number. */
|
||||
CALchar boardName[CAL_ASIC_INFO_MAX_LEN]; /**< Actual ASIC board name and not the internal name. */
|
||||
CALuint memBusWidth; /**< Memory busw width */
|
||||
CALuint numMemBanks; /**< Number of memory banks */
|
||||
CALuint counterFreq; /**< Ref clock counter frequency */
|
||||
double nanoSecondsPerTick; /**< Nano seconds per GPU tick */
|
||||
bool longIdleDetect; /**< Whether LongIdleDetect enabled */
|
||||
bool svmAtomics; /**< check if svm atomics support */
|
||||
CALuint64 vaStart; /**< VA start address */
|
||||
CALuint64 vaEnd; /**< VA end address */
|
||||
bool isWorkstation; /**< Whether Device is a Workstation/Server part */
|
||||
CALuint numOfVpu; /**< number of vpu in the device*/
|
||||
bool isOpenCL200Device; /**< the flag to mark if the device is OpenCL 200 */
|
||||
bool isSVMFineGrainSystem; /**< check if SVM finegrainsystem */
|
||||
bool isWDDM2Enabled; /**< check if WDDM2 is enabled */
|
||||
CALuint maxRTCUs; /**< The maximum number of RT CUs for RT queues */
|
||||
CALuint asicRevision; /**< The ASIC revision ID */
|
||||
CALchar driverStore[CAL_DRIVER_STORE_MAX_LEN];/**< Driver store location. */
|
||||
CALuint pcieDeviceID; /**< The ASIC PCIE device ID */
|
||||
CALuint pcieRevisionID; /**< The ASIC PCIE revision ID */
|
||||
} CALdeviceattribs;
|
||||
|
||||
|
||||
/** CAL resource allocation flags **/
|
||||
typedef enum CALresallocflagsEnum {
|
||||
CAL_RESALLOC_GLOBAL_BUFFER = 1, /**< used for global import/export buffer */
|
||||
} CALresallocflags;
|
||||
|
||||
|
||||
/** CAL function information **/
|
||||
typedef struct CALfuncInfoRec
|
||||
{
|
||||
CALuint maxScratchRegsNeeded; /**< Maximum number of scratch regs needed */
|
||||
CALuint numSharedGPRUser; /**< Number of shared GPRs */
|
||||
CALuint numSharedGPRTotal; /**< Number of shared GPRs including ones used by SC */
|
||||
CALuint numThreadPerGroup; /**< Flattend umber of threads per group */
|
||||
CALuint numThreadPerGroupX; /**< x dimension of numThreadPerGroup */
|
||||
CALuint numThreadPerGroupY; /**< y dimension of numThreadPerGroup */
|
||||
CALuint numThreadPerGroupZ; /**< z dimension of numThreadPerGroup */
|
||||
CALuint totalNumThreadGroup; /**< Total number of thread groups */
|
||||
CALuint numWavefrontPerSIMD; /**< Number of wavefronts per SIMD */
|
||||
bool setBufferForNumGroup; /**< Need to set up buffer for info on number of thread groups? */
|
||||
CALuint wavefrontSize; /**< number of threads per wavefront. */
|
||||
CALuint numGPRsAvailable; /**< number of GPRs available to the program */
|
||||
CALuint numGPRsUsed; /**< number of GPRs used by the program */
|
||||
CALuint LDSSizeAvailable; /**< LDS size available to the program */
|
||||
CALuint LDSSizeUsed; /**< LDS size used by the program */
|
||||
CALuint stackSizeAvailable; /**< stack size availabe to the program */
|
||||
CALuint stackSizeUsed; /**< stack size use by the program */
|
||||
CALuint numSGPRsAvailable; /**< number of SGPRs available to the program */
|
||||
CALuint numSGPRsUsed; /**< number of SGPRs used by the program */
|
||||
CALuint numVGPRsAvailable; /**< number of VGPRs available to the program */
|
||||
CALuint numVGPRsUsed; /**< number of VGPRs used by the program */
|
||||
} CALfuncInfo;
|
||||
|
||||
// flags for calCtxWaitForEvents
|
||||
typedef enum CALwaitTypeEnum
|
||||
{
|
||||
CAL_WAIT_POLLING = 0,
|
||||
CAL_WAIT_LOW_CPU_UTILIZATION = 1,
|
||||
} CALwaitType;
|
||||
|
||||
//
|
||||
// calResAllocView typedefs
|
||||
//
|
||||
typedef enum CALresallocviewflagsRec {
|
||||
CAL_RESALLOCVIEW_GLOBAL_BUFFER = CAL_RESALLOC_GLOBAL_BUFFER, /**< used for global import/export buffer */
|
||||
CAL_RESALLOCVIEW_LINEAR_ALIGNED = CAL_RESALLOC_GLOBAL_BUFFER, /**< 256 byte alignment restriction. */
|
||||
CAL_RESALLOCVIEW_LINEAR_UNALIGNED = 3, /**< no alignment restrictions */
|
||||
} CALresallocviewflags;
|
||||
|
||||
typedef struct CALresourceDescRec {
|
||||
gslMemObjectAttribLocation type;
|
||||
gslResource3D size;
|
||||
cmSurfFmt format;
|
||||
gslChannelOrder channelOrder;
|
||||
gslMemObjectAttribType dimension;
|
||||
CALuint mipLevels;
|
||||
CALvoid* systemMemory;
|
||||
CALuint flags;
|
||||
CALuint systemMemorySize;
|
||||
CALuint64 busAddress[2];
|
||||
mcaddr vaBase;
|
||||
gslMemObjectAttribSection section;
|
||||
CALuint minAlignment;
|
||||
bool isAllocSVM;
|
||||
bool isAllocExecute;
|
||||
} CALresourceDesc;
|
||||
|
||||
typedef enum CALresallocsliceviewflagsRec {
|
||||
CAL_RESALLOCSLICEVIEW_GLOBAL_BUFFER = CAL_RESALLOC_GLOBAL_BUFFER, /**< used for global import/export buffer */
|
||||
CAL_RESALLOCSLICEVIEW_LINEAR_ALIGNED = CAL_RESALLOC_GLOBAL_BUFFER, /**< 256 byte alignment restriction. */
|
||||
CAL_RESALLOCSLICEVIEW_LINEAR_UNALIGNED = CAL_RESALLOCVIEW_LINEAR_UNALIGNED, /**< no alignment restrictions */
|
||||
CAL_RESALLOCSLICEVIEW_LEVEL = 0x10, /**< sliceDesc.layer is not used, the whole level is only*/
|
||||
CAL_RESALLOCSLICEVIEW_LAYER = 0x20, /**< sliceDesc.layer is not used, the whole level is only*/
|
||||
CAL_RESALLOCSLICEVIEW_LEVEL_AND_LAYER = CAL_RESALLOCSLICEVIEW_LEVEL | CAL_RESALLOCSLICEVIEW_LAYER,
|
||||
} CALresallocsliceviewflags;
|
||||
|
||||
typedef enum CALmemcopyflagsEnum
|
||||
{
|
||||
CAL_MEMCOPY_DEFAULT = 0, /**< default CAL behavior of partial sync */
|
||||
CAL_MEMCOPY_SYNC = 1, /**< used to synchronize with the specified CAL context */
|
||||
CAL_MEMCOPY_ASYNC = 2, /**< used to indicate completely asynchronous behavior */
|
||||
} CALmemcopyflags;
|
||||
|
||||
class CALGSLDevice;
|
||||
|
||||
//! Engine types
|
||||
enum EngineType
|
||||
{
|
||||
MainEngine = 0,
|
||||
SdmaEngine,
|
||||
AllEngines
|
||||
};
|
||||
|
||||
struct GpuEvent
|
||||
{
|
||||
static constexpr unsigned int InvalidID = ((1<<30) - 1);
|
||||
|
||||
EngineType engineId_; ///< type of the id
|
||||
unsigned int id; ///< actual event id
|
||||
|
||||
//! GPU event default constructor
|
||||
GpuEvent(): engineId_(MainEngine), id(InvalidID) {}
|
||||
|
||||
//! Returns true if the current event is valid
|
||||
bool isValid() const { return (id != InvalidID) ? true : false; }
|
||||
|
||||
//! Set invalid event id
|
||||
void invalidate() { id = InvalidID; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __CALTARGET_H__
|
||||
#define __CALTARGET_H__
|
||||
|
||||
/** Device Kernel ISA */
|
||||
typedef enum CALtargetEnum {
|
||||
CAL_TARGET_600, /**< R600 GPU ISA */
|
||||
CAL_TARGET_610, /**< RV610 GPU ISA */
|
||||
CAL_TARGET_630, /**< RV630 GPU ISA */
|
||||
CAL_TARGET_670, /**< RV670 GPU ISA */
|
||||
CAL_TARGET_7XX, /**< R700 class GPU ISA */
|
||||
CAL_TARGET_770, /**< RV770 GPU ISA */
|
||||
CAL_TARGET_710, /**< RV710 GPU ISA */
|
||||
CAL_TARGET_730, /**< RV730 GPU ISA */
|
||||
CAL_TARGET_CYPRESS, /**< CYPRESS GPU ISA */
|
||||
CAL_TARGET_JUNIPER, /**< JUNIPER GPU ISA */
|
||||
CAL_TARGET_REDWOOD, /**< REDWOOD GPU ISA */
|
||||
CAL_TARGET_CEDAR, /**< CEDAR GPU ISA */
|
||||
//##BEGIN_PRIVATE##
|
||||
CAL_TARGET_SUMO, /**< SUMO GPU ISA */
|
||||
CAL_TARGET_SUPERSUMO, /**< SUPERSUMO GPU ISA */
|
||||
CAL_TARGET_WRESTLER, /**< WRESTLER GPU ISA */
|
||||
CAL_TARGET_CAYMAN, /**< CAYMAN GPU ISA */
|
||||
CAL_TARGET_KAUAI, /**< KAUAI GPU ISA */
|
||||
CAL_TARGET_BARTS , /**< BARTS GPU ISA */
|
||||
CAL_TARGET_TURKS , /**< TURKS GPU ISA */
|
||||
CAL_TARGET_CAICOS, /**< CAICOS GPU ISA */
|
||||
CAL_TARGET_TAHITI, /**< TAHITI GPU ISA*/
|
||||
CAL_TARGET_PITCAIRN, /**< PITCAIRN GPU ISA*/
|
||||
CAL_TARGET_CAPEVERDE, /**< CAPE VERDE GPU ISA*/
|
||||
CAL_TARGET_DEVASTATOR, /**< DEVASTATOR GPU ISA*/
|
||||
CAL_TARGET_SCRAPPER, /**< SCRAPPER GPU ISA*/
|
||||
CAL_TARGET_OLAND, /**< OLAND GPU ISA*/
|
||||
CAL_TARGET_BONAIRE, /**< BONAIRE GPU ISA*/
|
||||
CAL_TARGET_SPECTRE, /**< KAVERI1 GPU ISA*/
|
||||
CAL_TARGET_SPOOKY, /**< KAVERI2 GPU ISA*/
|
||||
CAL_TARGET_KALINDI, /**< KALINDI GPU ISA*/
|
||||
CAL_TARGET_HAINAN, /**< HAINAN GPU ISA*/
|
||||
CAL_TARGET_HAWAII, /**< HAWAII GPU ISA*/
|
||||
CAL_TARGET_ICELAND, /**< ICELAND GPU ISA*/
|
||||
CAL_TARGET_TONGA, /**< TONGA GPU ISA*/
|
||||
CAL_TARGET_GODAVARI, /**< MULLINS GPU ISA*/
|
||||
CAL_TARGET_FIJI, /**< FIJI GPU ISA*/
|
||||
CAL_TARGET_CARRIZO, /**< CARRIZO GPU ISA*/
|
||||
CAL_TARGET_ELLESMERE, /**< ELLESMERE GPU ISA*/
|
||||
CAL_TARGET_BAFFIN, /**< BAFFIN GPU ISA*/
|
||||
CAL_TARGET_GREENLAND, /**< GREENLAND GPU ISA*/
|
||||
CAL_TARGET_STONEY, /**< STONEY GPU ISA*/
|
||||
CAL_TARGET_LEXA, /**< LEXA GPU ISA*/
|
||||
CAL_TARGET_RAVEN, /**< RAVEN GPU ISA*/
|
||||
CAL_TARGET_RAVEN2, /**< RAVEN2 GPU ISA*/
|
||||
CAL_TARGET_RENOIR, /**< RENOIR GPU ISA*/
|
||||
CAL_TARGET_POLARIS22, /**< POLARIS22 GPU ISA*/
|
||||
CAL_TARGET_VEGA12, /**< VEGA12 GPU ISA*/
|
||||
CAL_TARGET_VEGA20, /**< VEGA20 GPU ISA*/
|
||||
CAL_TARGET_LAST = CAL_TARGET_VEGA20, /**< last */
|
||||
//##END_PRIVATE##
|
||||
} CALtarget;
|
||||
|
||||
#endif
|
||||
@@ -1,115 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "inifile.h"
|
||||
#include "ini_export.h"
|
||||
#include "ini_values.h"
|
||||
|
||||
#include "gsl_enum.h"
|
||||
|
||||
extern gslMemObjectAttribTiling g_CALBETiling_Tiled;
|
||||
|
||||
void
|
||||
getConfigFromFile(gslStaticRuntimeConfig& scfg,
|
||||
gslDynamicRuntimeConfig& dcfg)
|
||||
{
|
||||
const char* calIniFile = getenv("CAL_INI_FILE");
|
||||
IniFile iniFile(cmString(calIniFile ? calIniFile : INI_FILE));
|
||||
|
||||
CALboolean dumpIL = CAL_FALSE;
|
||||
CALboolean dumpISA = CAL_FALSE;
|
||||
CALboolean macro = CAL_TRUE;
|
||||
CALboolean micro = CAL_TRUE;
|
||||
CALboolean breakonload = CAL_FALSE;
|
||||
CALint useRectPrim = 0;
|
||||
CALboolean forceRemoteMemory = CAL_FALSE;
|
||||
CALboolean disableAsyncDma = CAL_FALSE;
|
||||
CALboolean disableVM = CAL_FALSE;
|
||||
|
||||
|
||||
dcfg.bEmulator.hasValue = ATIGL_TRUE;
|
||||
dcfg.DropFlush.hasValue = ATIGL_TRUE;
|
||||
dcfg.EnableCommandbufferDump.hasValue = ATIGL_TRUE;
|
||||
dcfg.WaitForIdleAfterSubmit.hasValue = ATIGL_TRUE;
|
||||
dcfg.FlushAfterRender.hasValue = ATIGL_TRUE;
|
||||
dcfg.nPatchDumpLevel.hasValue = ATIGL_TRUE;
|
||||
|
||||
cmString commandbufferDumpFilename;
|
||||
|
||||
iniFile.getValue(section, CAL_EMULATOR, (CALboolean*) &dcfg.bEmulator.value);
|
||||
iniFile.getValue(section, CAL_ENABLE_FORCE_ASIC_ID, (CALboolean*) &dcfg.forceAsicID.hasValue);
|
||||
iniFile.getValue(section, CAL_FORCE_ASIC_ID, (CALint*) &dcfg.forceAsicID.value);
|
||||
iniFile.getValue(section, CAL_DROPFLUSH, (CALboolean*) &dcfg.DropFlush.value);
|
||||
iniFile.getValue(section, CAL_ENABLEPACKETDUMP, (CALboolean*) &dcfg.EnableCommandbufferDump.value);
|
||||
|
||||
// Check if location string is longer than 128 then assign, if not default location will be C:\packet.txt in gsl_ctx.cpp: gsCtxManager::PacketDump()
|
||||
uintp length = commandbufferDumpFilename.length();
|
||||
if (length > 0 && length < sizeof(dcfg.CommandbufferDumpFilename))
|
||||
::strncpy(dcfg.CommandbufferDumpFilename, commandbufferDumpFilename.c_str(), sizeof(dcfg.CommandbufferDumpFilename) - 1);
|
||||
|
||||
iniFile.getValue(section, CAL_ENABLEPATCHDUMP, (CALint*) &dcfg.nPatchDumpLevel.value);
|
||||
iniFile.getValue(section, CAL_ENABLEMACROTILE, (CALboolean*) ¯o);
|
||||
iniFile.getValue(section, CAL_ENABLEMICROTILE, (CALboolean*) µ);
|
||||
iniFile.getValue(section, CAL_BREAK_ON_LOAD, (CALboolean*) &breakonload);
|
||||
iniFile.getValue(section, CAL_FORCE_REMOTE_MEMORY, (CALboolean*) &forceRemoteMemory);
|
||||
iniFile.getValue(section, CAL_DISABLE_ASYNC_DMA, (CALboolean*) &disableAsyncDma);
|
||||
iniFile.getValue(section, CAL_WAITFORIDLEAFTERSUBMIT, (CALboolean*) &dcfg.WaitForIdleAfterSubmit.value);
|
||||
iniFile.getValue(section, CAL_ENABLE_DUMP_IL, (CALboolean*) &dumpIL);
|
||||
iniFile.getValue(section, CAL_ENABLE_DUMP_ISA, (CALboolean*) &dumpISA);
|
||||
iniFile.getValue(section, CAL_ENABLE_FLUSH_AFTER_RENDER, (CALboolean*) &dcfg.FlushAfterRender.value);
|
||||
iniFile.getValue(section, CAL_DISABLE_VM, (CALboolean*) &disableVM);
|
||||
|
||||
if (disableVM)
|
||||
{
|
||||
scfg.VMMode = GSL_CONFIG_VM_MODE_FORCE_OFF;
|
||||
}
|
||||
|
||||
if (!macro && !micro)
|
||||
{
|
||||
g_CALBETiling_Tiled = GSL_MOA_TILING_LINEAR;
|
||||
}
|
||||
|
||||
if (breakonload)
|
||||
{
|
||||
#ifndef ATI_OS_LINUX
|
||||
__debugbreak();
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (forceRemoteMemory)
|
||||
{
|
||||
case 1:
|
||||
//
|
||||
// Also set linear, due to CAL expectations about different memory regions
|
||||
//
|
||||
g_CALBETiling_Tiled = GSL_MOA_TILING_LINEAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (disableAsyncDma)
|
||||
{
|
||||
dcfg.drmdmaMode.hasValue = ATIGL_TRUE;
|
||||
dcfg.drmdmaMode.value = GSL_CONFIG_DRMDMA_MODE_FORCE_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __INI_EXPORT_H__
|
||||
#define __INI_EXPORT_H__
|
||||
|
||||
#include "gsl_config.h"
|
||||
|
||||
void
|
||||
getConfigFromFile(gslStaticRuntimeConfig& scfg,
|
||||
gslDynamicRuntimeConfig& dcfg);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef __INI_VALUES_H__
|
||||
#define __INI_VALUES_H__
|
||||
|
||||
#include "cm_string.h"
|
||||
|
||||
|
||||
const cmString section("CAL");
|
||||
const cmString INI_FILE("cal.ini");
|
||||
|
||||
/* VSYNC COMMENTS
|
||||
0 - always off
|
||||
1 - app preference (default off)
|
||||
2 - app preference (default on)
|
||||
3 - always on
|
||||
*/
|
||||
const cmString CAL_OGLWAITVERTICALSYNC("VSyncControl");
|
||||
|
||||
// Private panel setting for V-sync control
|
||||
const cmString CAL_ENABLETEARFREESWAP("VSyncControl");
|
||||
|
||||
// Public panel setting to set max anisotropy: 0=app pref, 2=2x, 4=4x, 8=8x, 16=16x
|
||||
const cmString CAL_OGLMAXANISOTROPY("MaxAnisotropy");
|
||||
|
||||
// Public panel setting to select performance Aniso
|
||||
const cmString CAL_OGLANISOPERF("AnisoPerf");
|
||||
|
||||
|
||||
// Public panel setting to select quality mode
|
||||
const cmString CAL_OGLANISOQUAL("AnisoQuality");
|
||||
|
||||
// Public panel setting
|
||||
const cmString CAL_OGLANISOTYPE("AnisoType");
|
||||
|
||||
// Private panel
|
||||
const cmString CAL_ENABLEANISOTROPICFILTERING("AnisoFiltering");
|
||||
|
||||
// Public panel setting
|
||||
const cmString CAL_OGLALIASSLIDER("AnisoDegree");
|
||||
|
||||
// Public panel setting for LOD bias; ranges from 0(high quality) to 3(high performance);
|
||||
const cmString CAL_OGLLODBIAS("TextureLod");
|
||||
|
||||
// Public panel setting to force Z buffer depth
|
||||
const cmString CAL_OGLFORCEZBUFFERDEPTH("ForceZBufferDepth");
|
||||
|
||||
// Public panel setting to select alpha dither method
|
||||
const cmString CAL_OGLALPHADITHERMETHOD("DitherAlpha");
|
||||
|
||||
// Private Panel Setting for setting multisample value for FSAA
|
||||
const cmString CAL_MULTISAMPLE("Multisample");
|
||||
|
||||
// Public Panel setting for forcing AA
|
||||
const cmString CAL_ACE_OGLENABLEFSAA("AntiAlias");
|
||||
|
||||
// Public panel setting to Enable fast full scene anti-aliasing
|
||||
const cmString CAL_OGLENABLEFASTFULLSCENEAA("FSAAPerfMode");
|
||||
|
||||
//Private Panel setting to force FSAA on
|
||||
const cmString CAL_ENABLEFASTFULLSCENEAA("FastFullSceneAntiAlias");
|
||||
|
||||
|
||||
// Public panel setting to set full scene anti-aliasing scale.
|
||||
// Acceptable values are 0, 2-6
|
||||
const cmString CAL_OGLFULLSCENEAASCALE("AntiAliasSamples");
|
||||
|
||||
// Private panel setting to force FSAA, Acceptable values are 0, 2-6.
|
||||
const cmString CAL_FULLSCENEAASCALE("FullSceneAntiAliasScale");
|
||||
|
||||
// Public panel setting to enable triple-buffering
|
||||
const cmString CAL_OGLENABLETRIPLEBUFFERING("EnableTripleBuffering");
|
||||
|
||||
// Public panel setting to set texture optimization
|
||||
const cmString CAL_OGLTEXTUREOPT("TextureOpt");
|
||||
|
||||
// Public panel settings to set postprocessing shaders
|
||||
const cmString CAL_OGLSELECTEDSWAPEFFECT("SwapEffect");
|
||||
|
||||
// Public panel settings to control CatalystAI settings
|
||||
const cmString CAL_OGLCATALYSTAI("CatalystAI");
|
||||
|
||||
|
||||
// Public panel settings to set postprocessing shaders
|
||||
const cmString CAL_OGLSUPPORTEDSWAPEFFECTS("SupportedSwapEffects");
|
||||
|
||||
const cmString CAL_OGLCUSTOMSWAPSOURCEFILE("CustomSwapSourceFile");
|
||||
|
||||
//Public panel setting for allowing special pixel shaders to be applied at swap time.
|
||||
const cmString CAL_SPECIALSWAP("SpecialSwap");
|
||||
|
||||
//Public panel setting for special swap file
|
||||
const cmString CAL_SPECIALSWAPFILE("SpecialSwapFile");
|
||||
|
||||
|
||||
|
||||
// Private Panel specific Defines
|
||||
//
|
||||
|
||||
// Private panel setting to force SW path
|
||||
const cmString CAL_PICKSOFTWARE("PickSoftware");
|
||||
|
||||
// Private panel setting to force Microsoft path
|
||||
const cmString CAL_PICKSOFTWAREMICROSOFT("PickSoftwareMicrosoft");
|
||||
|
||||
// Private Panel setting to enable TCL (versus forcing SW TCL)
|
||||
const cmString CAL_ENABLETCL("EnableTCL");
|
||||
|
||||
// Private Panel setting to control HW Flips
|
||||
const cmString CAL_ALLOWHWFLIP("AllowHWFlip");
|
||||
|
||||
// Private Panel setting to allow Z compression
|
||||
const cmString CAL_ENABLEZCOMPRESSION("ZCompression");
|
||||
|
||||
// Private Panel setting to use fast z clears
|
||||
const cmString CAL_ENABLEFASTZMASKCLEAR("FastZMaskClear");
|
||||
|
||||
// Private Panel setting to enable hierarchical Z
|
||||
const cmString CAL_ENABLEHIERARCHICALZ("HierachicalZ");
|
||||
|
||||
// Private Panel setting to enable/disable cmask clears
|
||||
const cmString CAL_ENABLECMASKCLEARS("MaskClears");
|
||||
|
||||
// Private Panel setting to force cmask clear after swap
|
||||
const cmString CAL_CLEARCMASKAFTERSWAP("ClearCMaskAfterSwap");
|
||||
|
||||
// Private Panel setting to enable cmask compression
|
||||
const cmString CAL_ENABLECMASKCOMPRESSION("CMaskCompression");
|
||||
|
||||
// Private Panel setting to force LOD Bias
|
||||
const cmString CAL_LODBIAS("LODBias");
|
||||
|
||||
// Private Panel setting enable fast trilinear
|
||||
const cmString CAL_FASTTRILINEAR("FastTrilinear");
|
||||
|
||||
// Private Panel setting to force clears to be skipped
|
||||
const cmString CAL_DISABLECLEAR("DisableClear");
|
||||
|
||||
// Private Panel setting to control swapping
|
||||
const cmString CAL_DISABLESWAP("DisableSwap");
|
||||
|
||||
// Private Panel setting to force HW idle after submit
|
||||
const cmString CAL_WAITFORIDLEAFTERSUBMIT("WaitForIdleAfterSubmit");
|
||||
|
||||
// Private Panel setting to force single buffered rendering
|
||||
const cmString CAL_FORCESINGLEBUFFER("ForceSingleBuffer");
|
||||
|
||||
// Private Panel setting to force buffer config for single buffered
|
||||
// configs
|
||||
const cmString CAL_SINGLE_BUF_CONFIG("SingleBufferConfig");
|
||||
|
||||
// Private Panel setting to force buffer config for double buffered
|
||||
const cmString CAL_DOUBLE_BUF_CONFIG("DoubleBufferConfig");
|
||||
|
||||
// Private Panel setting to cause driver to breka on load
|
||||
const cmString CAL_BREAK_ON_LOAD("BreakOnLoad");
|
||||
|
||||
// Private Panel setting for asserting when we set an error
|
||||
const cmString CAL_ASSERTONERROR("AssertOnError");
|
||||
|
||||
// Private Panel setting to turn on shader dumping
|
||||
const cmString CAL_ENABLESHADERDUMP("EnableShaderDump");
|
||||
|
||||
// Private Panel setting to turn on packet dumping
|
||||
const cmString CAL_ENABLEPACKETDUMP("EnablePacketDump");
|
||||
|
||||
// Private Panel setting to set location of packet dump
|
||||
const cmString CAL_PACKETDUMPLOCATION("PacketDumpLocation");
|
||||
|
||||
// Private Panel setting to set what type of file to be written
|
||||
const cmString CAL_PACKETDUMPTYPE("PacketDumpType");
|
||||
|
||||
// Private Panel setting to select file overwrite
|
||||
const cmString CAL_ONLYSAVELASTPACKET("OnlySaveLastPacket");
|
||||
|
||||
// Private Panel setting to turn on vcop patchlist dumping
|
||||
const cmString CAL_ENABLEPATCHDUMP("EnablePatchDump");
|
||||
|
||||
// Private Panel setting to set dump file name
|
||||
const cmString CAL_DUMPFILENAME("DumpFilename");
|
||||
|
||||
// Private Panel setting to control level of HW detail dumped
|
||||
const cmString CAL_DUMPADDITIONALHWINFO("DumpAdditionalHWInfo");
|
||||
|
||||
|
||||
// Private Panel setting to select frames to dump
|
||||
const cmString CAL_FRAMESTORECORD("FrameStoreCord");
|
||||
|
||||
// Private Panel setting to drop all PM4 packets
|
||||
const cmString CAL_DROPFLUSH("DropFlush");
|
||||
|
||||
// Private Panel setting to furce use of dummy QS
|
||||
const cmString CAL_ENABLEDUMMYQS("DummyQS");
|
||||
|
||||
// Private Panel setting to stub post setup
|
||||
const cmString CAL_STUBPOSTSETUP("StubPostSetup");
|
||||
|
||||
// Private Panel setting to stub post TCL
|
||||
const cmString CAL_STUBPOSTTCL("StubPostTCL");
|
||||
|
||||
// Private Panel setting to disable RB3D
|
||||
const cmString CAL_DISABLERB3D("DisableR3D");
|
||||
|
||||
// Private Panel setting to disable alpha blend
|
||||
const cmString CAL_DISABLEALPHABLEND("DisableAlphaBlend");
|
||||
|
||||
// Private Panel setting to force use of tiny textures
|
||||
const cmString CAL_FORCETINYTEXTURES("ForceTinyTextures");
|
||||
|
||||
// Private Panel setting to prevent object allocation in AGP
|
||||
const cmString CAL_OBJBUFINAGP("OBJBufferInAGP");
|
||||
|
||||
// Private Panel setting to prevent object allcoation in local
|
||||
const cmString CAL_OBJBUFINLOCAL("OBJBufferInLocal");
|
||||
|
||||
// Private Panel setting to set the length of the swap queue
|
||||
const cmString CAL_SWAPQUEUELENGTH("SwapQueueLength");
|
||||
|
||||
// Private Panel setting to enable macro tiling for textures
|
||||
const cmString CAL_ENABLEMACROTILE("MacroTile");
|
||||
|
||||
// Private Panel setting to enable micro tiling for textures
|
||||
const cmString CAL_ENABLEMICROTILE("MicroTile");
|
||||
|
||||
// Private Panel setting for allowing early z
|
||||
const cmString CAL_ALLOWEARLYZ("AllowEarlyZ");
|
||||
|
||||
//Private Panel setting to allow for window to be broken into
|
||||
// multiple pieces(allows full use of C and Z mask on R300 at high res);
|
||||
const cmString CAL_ALLOWSPLITSCREEN("AllowSplitScreen");
|
||||
|
||||
//Private Panel setting for aniso threshold
|
||||
const cmString CAL_ANISOTHRESHOLD("AnisoThreshold");
|
||||
|
||||
//Private Panel setting for aniso bias
|
||||
const cmString CAL_ANISOLOD("AnisoLod");
|
||||
|
||||
//Private Panel setting fpr aniso bias
|
||||
const cmString CAL_ANISOBIAS("AnisoBias");
|
||||
|
||||
//Private Panel setting to control ainos theshold mode
|
||||
const cmString CAL_ANISOTHRESHMODE("AnisoThreshmode");
|
||||
|
||||
// Private Panel Setting for turnning off multi vpu mode(ie render everything to both) for the rest of a frame after a glCopyTexImage or glCopyTexSubImage happen.
|
||||
const cmString CAL_DISABLEMVPUONCOPYTEX("DisableMVPUOnCopyTexture");
|
||||
|
||||
// Private Panel Setting for forcing swap to happen on slave vpu(useful for debugging);
|
||||
const cmString CAL_FORCEMVPUSWAPONSLAVE("ForceMVPUSwapOnSlave");
|
||||
|
||||
// Private Panel Setting for skipping multi-vpu synchronization
|
||||
const cmString CAL_SKIPMVPUSYNCH("SkipMVPUSynch");
|
||||
|
||||
// Private Panel Setting for controlling the percent of screen rendered on the master vpu
|
||||
const cmString CAL_PERCENTONMASTERMVPU("PercentOnMasterMVPU");
|
||||
|
||||
// Private Panel Setting for controlling the mode of mvpu operation
|
||||
const cmString CAL_MODEMVPU("ModeMVPU");
|
||||
|
||||
// Private Panel Setting for drawing a line where the scissored split happened in mvpu mode
|
||||
const cmString CAL_DRAWSPLITLINEMVPU("DrawSplitLineMVPU");
|
||||
|
||||
// Private Panel Setting for controlling whether or not to unroll loops in the GLSL parser
|
||||
const cmString CAL_UNROLL_LOOPS("UnrollLoops");
|
||||
|
||||
// Private Panel Spare setting 1
|
||||
const cmString CAL_SPARE1("Spare1");
|
||||
|
||||
// Private Panel Spare setting 2
|
||||
const cmString CAL_SPARE2("Spare2");
|
||||
|
||||
// Private Panel Spare setting 3
|
||||
const cmString CAL_SPARE3("Spare3");
|
||||
|
||||
// Private Panel Spare setting 4
|
||||
const cmString CAL_SPARE4("Spare4");
|
||||
|
||||
// Private Panel Spare setting 5
|
||||
const cmString CAL_SPARE5("Spare5");
|
||||
|
||||
// Private Panel Spare setting 6
|
||||
const cmString CAL_SPARE6("Spare6");
|
||||
|
||||
// Private Panel Spare setting 7
|
||||
const cmString CAL_SPARE7("Spare7");
|
||||
|
||||
// Private Panel Spare setting 8
|
||||
const cmString CAL_SPARE8("Spare8");
|
||||
|
||||
// Private Panel Spare setting 9
|
||||
const cmString CAL_SPARE9("Spare9");
|
||||
|
||||
// Private Panel Spare setting 10
|
||||
const cmString CAL_SPARE10("Spare10");
|
||||
|
||||
// Private Panel Spare setting 11 - accepts numbers, not just 0 and 1
|
||||
const cmString CAL_SPARE11("Spare11");
|
||||
|
||||
// Private Panel Spare setting 12 - accepts numbers, not just 0 and 1
|
||||
const cmString CAL_SPARE12("Spare12");
|
||||
|
||||
// Private Panel Spare setting 12 - accepts numbers, not just 0 and 1
|
||||
const cmString CAL_PS3ENABLE("PS3Enable");
|
||||
|
||||
// Private Panel setting for asserting when we punt to SW
|
||||
const cmString CAL_ASSERTONSWPUNT("OrcaAssertOnSWPunt");
|
||||
|
||||
// Private Panel setting for logging when we punt to SW
|
||||
const cmString CAL_LOGSWPUNTCASES("OrcaLogSWPuntCases");
|
||||
|
||||
// Private Panel setting to set punt log file name
|
||||
const cmString CAL_PUNTLOGFILENAME("OrcaPuntLogFileName");
|
||||
|
||||
// softVAP mode
|
||||
const cmString CAL_SOFTVAP("SoftVAP");
|
||||
|
||||
// softVAP il compile mode
|
||||
const cmString CAL_SVPOFFLINECOMPILE("SvpOfflineCompile");
|
||||
|
||||
const cmString CAL_EMULATOR("Emulator");
|
||||
|
||||
const cmString CAL_ENABLE_FORCE_ASIC_ID("EnableForceAsicID");
|
||||
const cmString CAL_FORCE_ASIC_ID("ForceAsicID");
|
||||
const cmString CAL_FORCE_REMOTE_MEMORY("ForceRemoteMemory");
|
||||
const cmString CAL_DISABLE_ASYNC_DMA("DisableAsyncDma");
|
||||
const cmString CAL_ENABLE_DUMP_IL("DumpIL");
|
||||
const cmString CAL_ENABLE_DUMP_ISA("DumpISA");
|
||||
|
||||
// TDR
|
||||
const cmString CAL_ENABLE_FLUSH_AFTER_RENDER("FlushAfterRender");
|
||||
|
||||
// VM Disabling
|
||||
const cmString CAL_DISABLE_VM("DisableVM");
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,556 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
//
|
||||
// Trade secret of ATI Technologies, Inc.
|
||||
// Copyright 2005, ATI Technologies, Inc., (unpublished)
|
||||
//
|
||||
// All rights reserved. This notice is intended as a precaution against
|
||||
// inadvertent publication and does not imply publication or any waiver
|
||||
// of confidentiality. The year included in the foregoing notice is the
|
||||
// year of creation of the work.
|
||||
//
|
||||
|
||||
/// @file inifile.cpp
|
||||
/// @brief INI File Parser
|
||||
|
||||
#include "inifile.h"
|
||||
#include "cm_string.h"
|
||||
#include "inifile_parser.h"
|
||||
#include "assert.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IniValueString members
|
||||
*/
|
||||
|
||||
IniValueString::IniValueString()
|
||||
{
|
||||
value = cmString("");
|
||||
}
|
||||
|
||||
IniValueString::IniValueString(const IniValueString& val)
|
||||
{
|
||||
value = val.value;
|
||||
}
|
||||
|
||||
IniValueString::IniValueString(cmString val)
|
||||
{
|
||||
value = val;
|
||||
}
|
||||
|
||||
IniValueString& IniValueString::operator=(IniValueString& v)
|
||||
{
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CALboolean IniValueString::getValue(cmString* value)
|
||||
{
|
||||
*value = this->value;
|
||||
return CAL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* IniValueBool members
|
||||
*/
|
||||
|
||||
IniValueBool::IniValueBool()
|
||||
{
|
||||
value = CAL_FALSE;
|
||||
}
|
||||
|
||||
IniValueBool::IniValueBool(const IniValueBool& val)
|
||||
{
|
||||
value = val.value;
|
||||
}
|
||||
|
||||
IniValueBool::IniValueBool(CALboolean val)
|
||||
{
|
||||
value = val;
|
||||
}
|
||||
|
||||
IniValueBool& IniValueBool::operator=(IniValueBool& v)
|
||||
{
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CALboolean IniValueBool::getValue(CALboolean* value)
|
||||
{
|
||||
*value = this->value;
|
||||
return CAL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* IniValueInt members
|
||||
*/
|
||||
|
||||
IniValueInt::IniValueInt()
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
|
||||
IniValueInt::IniValueInt(const IniValueInt& val)
|
||||
{
|
||||
value = val.value;
|
||||
}
|
||||
|
||||
IniValueInt::IniValueInt(CALint val)
|
||||
{
|
||||
value = val;
|
||||
}
|
||||
|
||||
IniValueInt& IniValueInt::operator=(IniValueInt& v)
|
||||
{
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CALboolean IniValueInt::getValue(CALint* value)
|
||||
{
|
||||
*value = this->value;
|
||||
return CAL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* IniValueFloat members
|
||||
*/
|
||||
|
||||
IniValueFloat::IniValueFloat()
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
|
||||
IniValueFloat::IniValueFloat(const IniValueFloat& val)
|
||||
{
|
||||
value = val.value;
|
||||
}
|
||||
|
||||
IniValueFloat::IniValueFloat(CALfloat val)
|
||||
{
|
||||
value = val;
|
||||
}
|
||||
|
||||
IniValueFloat& IniValueFloat::operator=(IniValueFloat& v)
|
||||
{
|
||||
value = v.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CALboolean IniValueFloat::getValue(CALfloat* value)
|
||||
{
|
||||
*value = this->value;
|
||||
return CAL_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* IniSection Members
|
||||
*/
|
||||
IniSection::IniSection()
|
||||
{
|
||||
name = cmString("");
|
||||
}
|
||||
|
||||
IniSection::IniSection(const IniSection& s)
|
||||
{
|
||||
name = s.name;
|
||||
for(EntryDBIterator iter = s.entryDB.begin() ; iter != s.entryDB.end(); ++iter)
|
||||
{
|
||||
entryDB[iter->first] = iter->second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IniSection::IniSection(cmString n)
|
||||
{
|
||||
name = n;
|
||||
}
|
||||
|
||||
IniSection::~IniSection()
|
||||
{
|
||||
for(EntryDBIterator iter = entryDB.begin() ; iter != entryDB.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
entryDB.clear();
|
||||
}
|
||||
|
||||
IniSection& IniSection::operator=(IniSection& s)
|
||||
{
|
||||
name = s.name;;
|
||||
entryDB.clear();
|
||||
for(EntryDBIterator iter = s.entryDB.begin() ; iter != s.entryDB.end(); iter++)
|
||||
{
|
||||
entryDB[iter->first] = iter->second;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void IniSection::addEntry(cmString name, IniValue* value)
|
||||
{
|
||||
IniValue* v = findEntry(name);
|
||||
if (v)
|
||||
{
|
||||
delete v;
|
||||
}
|
||||
entryDB[name] = value;
|
||||
}
|
||||
|
||||
IniValue* IniSection::findEntry(cmString name)
|
||||
{
|
||||
EntryDBIterator iter = entryDB.find(name);
|
||||
if(iter != entryDB.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* IniFile members
|
||||
*/
|
||||
|
||||
IniFile::IniFile(cmString filename)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
SanityTest();
|
||||
#endif
|
||||
|
||||
std::ifstream in(filename.c_str());
|
||||
IniFileParser::Parse(in, *this);
|
||||
}
|
||||
|
||||
IniFile::IniFile(std::istream& in)
|
||||
{
|
||||
IniFileParser::Parse(in, *this);
|
||||
}
|
||||
|
||||
IniFile::~IniFile()
|
||||
{
|
||||
for(SectionDBIterator iter = sectionDB.begin() ; iter != sectionDB.end(); iter++)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
sectionDB.clear();
|
||||
}
|
||||
|
||||
const cmString IniSection::getName () const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void IniFile::addSection(IniSection* section)
|
||||
{
|
||||
IniSection* v = findSection(section->getName());
|
||||
if (v)
|
||||
{
|
||||
delete v;
|
||||
}
|
||||
sectionDB[section->getName()] = section;
|
||||
}
|
||||
|
||||
IniSection* IniFile::findSection(cmString section)
|
||||
{
|
||||
SectionDBIterator iter = sectionDB.find(section);
|
||||
if (iter != sectionDB.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IniValue* IniFile::getValue(cmString section, cmString entry)
|
||||
{
|
||||
IniSection* s = findSection(section);
|
||||
if(s == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s->findEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
CALboolean IniFile::getValue(cmString section, cmString entry, CALboolean* value)
|
||||
{
|
||||
IniValue* v = getValue(section, entry);
|
||||
if (v != NULL)
|
||||
{
|
||||
return v->getValue(value);
|
||||
}
|
||||
return CAL_FALSE;
|
||||
}
|
||||
|
||||
CALboolean IniFile::getValue(cmString section, cmString entry, CALint* value)
|
||||
{
|
||||
IniValue* v = getValue(section, entry);
|
||||
if (v != NULL)
|
||||
{
|
||||
return v->getValue(value);
|
||||
}
|
||||
return CAL_FALSE;
|
||||
}
|
||||
|
||||
CALboolean IniFile::getValue(cmString section, cmString entry, CALfloat* value)
|
||||
{
|
||||
IniValue* v = getValue(section, entry);
|
||||
if (v != NULL)
|
||||
{
|
||||
return v->getValue(value);
|
||||
}
|
||||
return CAL_FALSE;
|
||||
}
|
||||
|
||||
CALboolean IniFile::getValue(cmString section, cmString entry, cmString* value)
|
||||
{
|
||||
IniValue* v = getValue(section, entry);
|
||||
if (v != NULL)
|
||||
{
|
||||
return v->getValue(value);
|
||||
}
|
||||
return CAL_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug only methods
|
||||
*
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
|
||||
void IniValueString::printAST()
|
||||
{
|
||||
std::cerr << value.c_str() << " [string]\n";
|
||||
}
|
||||
|
||||
void IniValueBool::printAST()
|
||||
{
|
||||
std::cerr << value << " [bool]\n";
|
||||
}
|
||||
|
||||
|
||||
void IniValueInt::printAST()
|
||||
{
|
||||
std::cerr << value << " [int]\n";
|
||||
}
|
||||
|
||||
void IniValueFloat::printAST()
|
||||
{
|
||||
std::cerr << value << " [float]\n";
|
||||
}
|
||||
|
||||
void IniSection::printAST()
|
||||
{
|
||||
for(EntryDBIterator iter = entryDB.begin() ; iter != entryDB.end(); ++iter)
|
||||
{
|
||||
cmString name = iter->first;
|
||||
IniValue *v = iter->second;
|
||||
|
||||
std::cerr << name.c_str() << " = ";
|
||||
v->printAST();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IniFile::printAST()
|
||||
{
|
||||
for(SectionDBIterator iter = sectionDB.begin() ; iter != sectionDB.end(); ++iter)
|
||||
{
|
||||
IniSection* s = iter->second;
|
||||
std::cerr << "[" << s->getName().c_str() << "]\n";
|
||||
s->printAST();
|
||||
}
|
||||
std::cerr << "\n";
|
||||
}
|
||||
|
||||
void IniFile::SanityTest()
|
||||
{
|
||||
//std::cerr << "Running IniFile Sanity...\n";
|
||||
|
||||
static const cmString section("section");
|
||||
|
||||
|
||||
static const std::string file1(
|
||||
"[section]\n\
|
||||
bool1=true\n\
|
||||
bool2=false\n\
|
||||
int=3\n\
|
||||
float=1.1111\n\
|
||||
string=abc def\n");
|
||||
|
||||
std::istringstream s1(file1);
|
||||
IniFile* iniFile = new IniFile(s1);
|
||||
//iniFile->printAST();
|
||||
|
||||
CALboolean b;
|
||||
|
||||
assert(iniFile->getValue(section, cmString("bool1"), &b) == CAL_TRUE);
|
||||
assert(b == CAL_TRUE);
|
||||
|
||||
assert(iniFile->getValue(section, cmString("bool2"), &b) == CAL_TRUE);
|
||||
assert(b == CAL_FALSE);
|
||||
|
||||
CALint i;
|
||||
assert(iniFile->getValue(section, cmString("int"), &i) == CAL_TRUE);
|
||||
assert(i == 3);
|
||||
|
||||
|
||||
CALfloat f;
|
||||
assert(iniFile->getValue(section, cmString("float"), &f) == CAL_TRUE);
|
||||
assert(f == 1.1111f);
|
||||
|
||||
cmString s;
|
||||
assert(iniFile->getValue(section, cmString("string"), &s) == CAL_TRUE);
|
||||
assert(s == cmString("abc def"));
|
||||
|
||||
i = -1;
|
||||
// Wrong section
|
||||
assert(iniFile->getValue(cmString("dummy"), cmString("int"), &i) == CAL_FALSE);
|
||||
assert(i == -1);
|
||||
|
||||
// Wrong entry
|
||||
assert(iniFile->getValue(section, cmString("dummy"), &i) == CAL_FALSE);
|
||||
assert(i == -1);
|
||||
|
||||
|
||||
static const std::string file2(
|
||||
"[section]\n\
|
||||
bool1=1true\n\
|
||||
bool2=false2\n\
|
||||
int=3a\n\
|
||||
float=1.1111b\n\
|
||||
string=1\n");
|
||||
|
||||
delete iniFile;
|
||||
|
||||
std::istringstream s2(file2);
|
||||
iniFile = new IniFile(s2);
|
||||
//iniFile->printAST();
|
||||
|
||||
cmString str;
|
||||
|
||||
b = CAL_FALSE;
|
||||
// try to get a bool, then a string
|
||||
assert(iniFile->getValue(section, cmString("bool1"), &b) == CAL_FALSE);
|
||||
assert(b == CAL_FALSE);
|
||||
assert(iniFile->getValue(section, cmString("bool1"), &str) == CAL_TRUE);
|
||||
assert(str == cmString("1true"));
|
||||
|
||||
// try to get a bool, then a string
|
||||
assert(iniFile->getValue(section, cmString("bool2"), &b) == CAL_FALSE);
|
||||
assert(b == CAL_FALSE);
|
||||
assert(iniFile->getValue(section, cmString("bool2"), &str) == CAL_TRUE);
|
||||
assert(str == cmString("false2"));
|
||||
|
||||
i = -1;
|
||||
// try to get an int, then a string
|
||||
assert(iniFile->getValue(section, cmString("int"), &i) == CAL_FALSE);
|
||||
assert(i == -1);
|
||||
assert(iniFile->getValue(section, cmString("int"), &str) == CAL_TRUE);
|
||||
assert(str == cmString("3a"));
|
||||
|
||||
|
||||
f = -1.1f;
|
||||
// try to get a float, then a string
|
||||
assert(iniFile->getValue(section, cmString("float"), &f) == CAL_FALSE);
|
||||
assert(f == -1.1f);
|
||||
assert(iniFile->getValue(section, cmString("float"), &str) == CAL_TRUE);
|
||||
assert(str == cmString("1.1111b"));
|
||||
|
||||
// try to get a string, value is an int
|
||||
assert(iniFile->getValue(section, cmString("string"), &str) == CAL_FALSE);
|
||||
assert(str == cmString("1.1111b"));
|
||||
assert(iniFile->getValue(section, cmString("string"), &i) == CAL_TRUE);
|
||||
assert(i == 1);
|
||||
|
||||
static const cmString section1("section1");
|
||||
static const cmString section2("section2");
|
||||
static const cmString section3("section3");
|
||||
|
||||
static const std::string file3(
|
||||
"[section1\n\
|
||||
bool1=false\n\
|
||||
bool2=false\n\
|
||||
int=1\n\
|
||||
float=1.1\n\
|
||||
string=abc\n\
|
||||
[section2]\n\
|
||||
bool1=true\n\
|
||||
bool2=true\n\
|
||||
int=2\n\
|
||||
float=1.2\n\
|
||||
string=def\n\
|
||||
[section3]\n\
|
||||
int=3\n\
|
||||
[section2]\n\
|
||||
float=1.3\n");
|
||||
|
||||
delete iniFile;
|
||||
|
||||
std::istringstream s3(file3);
|
||||
iniFile = new IniFile(s3);
|
||||
//iniFile->printAST();
|
||||
|
||||
// section1 should not exist (syntax error)
|
||||
assert(iniFile->getValue(section1, cmString("bool1"), &str) == CAL_FALSE);
|
||||
assert(iniFile->getValue(section1, cmString("bool2"), &str) == CAL_FALSE);
|
||||
assert(iniFile->getValue(section1, cmString("int"), &str) == CAL_FALSE);
|
||||
assert(iniFile->getValue(section1, cmString("float"), &str) == CAL_FALSE);
|
||||
assert(iniFile->getValue(section1, cmString("string"), &str) == CAL_FALSE);
|
||||
|
||||
// section2 should exist, only with the float
|
||||
assert(iniFile->getValue(section2, cmString("bool1"), &b) == CAL_FALSE);
|
||||
assert(iniFile->getValue(section2, cmString("bool2"), &b) == CAL_FALSE);
|
||||
assert(iniFile->getValue(section2, cmString("int"), &i) == CAL_FALSE);
|
||||
|
||||
// overridden
|
||||
assert(iniFile->getValue(section2, cmString("float"), &f) == CAL_TRUE);
|
||||
assert(f == 1.3f);
|
||||
|
||||
assert(iniFile->getValue(section2, cmString("string"), &str) == CAL_FALSE);
|
||||
|
||||
// section3 had a differant int
|
||||
assert(iniFile->getValue(section3, cmString("int"), &i) == CAL_TRUE);
|
||||
assert(i == 3);
|
||||
|
||||
delete iniFile;
|
||||
|
||||
//std::cerr << "Done!";
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,184 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef INIFILE_H
|
||||
#define INIFILE_H
|
||||
//
|
||||
// Trade secret of ATI Technologies, Inc.
|
||||
// Copyright 2005, ATI Technologies, Inc., (unpublished)
|
||||
//
|
||||
// All rights reserved. This notice is intended as a precaution against
|
||||
// inadvertent publication and does not imply publication or any waiver
|
||||
// of confidentiality. The year included in the foregoing notice is the
|
||||
// year of creation of the work.
|
||||
//
|
||||
|
||||
/// @file inifile.h
|
||||
/// @brief INI File Parser
|
||||
|
||||
#include "cm_string.h"
|
||||
#include "backend.h"
|
||||
|
||||
#include <map>
|
||||
#include <istream>
|
||||
|
||||
class IniValue
|
||||
{
|
||||
public:
|
||||
virtual ~IniValue() {}
|
||||
virtual CALboolean getValue(CALboolean* value) { return CAL_FALSE; };
|
||||
virtual CALboolean getValue(CALint* value) { return CAL_FALSE; };
|
||||
virtual CALboolean getValue(CALfloat* value) { return CAL_FALSE; };
|
||||
virtual CALboolean getValue(cmString* value) { return CAL_FALSE; };
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void printAST() {};
|
||||
#endif
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class IniValueBool : public IniValue
|
||||
{
|
||||
public:
|
||||
IniValueBool();
|
||||
IniValueBool(const IniValueBool& val);
|
||||
IniValueBool(CALboolean val);
|
||||
IniValueBool& operator=(IniValueBool& v);
|
||||
|
||||
CALboolean getValue(CALboolean* value);
|
||||
|
||||
#ifdef DEBUG
|
||||
void printAST();
|
||||
#endif
|
||||
private:
|
||||
CALboolean value;
|
||||
};
|
||||
|
||||
class IniValueString : public IniValue
|
||||
{
|
||||
public:
|
||||
IniValueString();
|
||||
IniValueString(const IniValueString& val);
|
||||
IniValueString(cmString val);
|
||||
IniValueString& operator=(IniValueString& v);
|
||||
|
||||
CALboolean getValue(cmString* value);
|
||||
|
||||
#ifdef DEBUG
|
||||
void printAST();
|
||||
#endif
|
||||
private:
|
||||
cmString value;
|
||||
};
|
||||
|
||||
class IniValueInt : public IniValue
|
||||
{
|
||||
public:
|
||||
IniValueInt();
|
||||
IniValueInt(const IniValueInt& val);
|
||||
IniValueInt(CALint val);
|
||||
IniValueInt& operator=(IniValueInt& v);
|
||||
|
||||
CALboolean getValue(CALint* value);
|
||||
void printAST();
|
||||
private:
|
||||
CALint value;
|
||||
};
|
||||
|
||||
class IniValueFloat : public IniValue
|
||||
{
|
||||
public:
|
||||
IniValueFloat();
|
||||
IniValueFloat(const IniValueFloat& val);
|
||||
IniValueFloat(CALfloat val);
|
||||
IniValueFloat& operator=(IniValueFloat& v);
|
||||
|
||||
CALboolean getValue(CALfloat* value);
|
||||
|
||||
#ifdef DEBUG
|
||||
void printAST();
|
||||
#endif
|
||||
private:
|
||||
CALfloat value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class IniSection
|
||||
{
|
||||
public:
|
||||
IniSection();
|
||||
IniSection(const IniSection& s);
|
||||
IniSection(cmString n);
|
||||
~IniSection();
|
||||
|
||||
IniSection& operator=(IniSection& s);
|
||||
|
||||
void addEntry(cmString name, IniValue* value);
|
||||
IniValue* findEntry(cmString name);
|
||||
const cmString getName();
|
||||
#ifdef DEBUG
|
||||
void printAST();
|
||||
#endif
|
||||
private:
|
||||
typedef std::map<cmString, IniValue*> EntryDB;
|
||||
typedef EntryDB::const_iterator EntryDBIterator;
|
||||
typedef std::pair<cmString, IniValue*> EntryDBPair;
|
||||
|
||||
cmString name;
|
||||
EntryDB entryDB;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class IniFile
|
||||
{
|
||||
public:
|
||||
IniFile(cmString filename);
|
||||
IniFile(std::istream& in);
|
||||
~IniFile();
|
||||
|
||||
CALboolean getValue(cmString section, cmString entry, CALboolean* value);
|
||||
CALboolean getValue(cmString section, cmString entry, CALint* value);
|
||||
CALboolean getValue(cmString section, cmString entry, CALfloat* value);
|
||||
CALboolean getValue(cmString section, cmString entry, cmString* value);
|
||||
|
||||
// should be protected
|
||||
void addSection(IniSection* section);
|
||||
IniSection* findSection(cmString section);
|
||||
#ifdef DEBUG
|
||||
void printAST();
|
||||
static void SanityTest();
|
||||
#endif
|
||||
private:
|
||||
typedef std::map<cmString, IniSection*> SectionDB;
|
||||
typedef SectionDB::const_iterator SectionDBIterator;
|
||||
typedef std::pair<cmString, IniSection*> SectionDBPair;
|
||||
|
||||
IniValue* getValue(cmString section, cmString entry);
|
||||
|
||||
|
||||
SectionDB sectionDB;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,245 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
//
|
||||
// Trade secret of ATI Technologies, Inc.
|
||||
// Copyright 2005, ATI Technologies, Inc., (unpublished)
|
||||
//
|
||||
// All rights reserved. This notice is intended as a precaution against
|
||||
// inadvertent publication and does not imply publication or any waiver
|
||||
// of confidentiality. The year included in the foregoing notice is the
|
||||
// year of creation of the work.
|
||||
//
|
||||
|
||||
/// @file inifile_parser.cpp
|
||||
/// @brief INI File Parser Implementation
|
||||
|
||||
#include "inifile.h"
|
||||
#include "inifile_parser.h"
|
||||
|
||||
#include "cm_string.h"
|
||||
|
||||
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
|
||||
void IniFileParser::Parse(std::istream& in, IniFile& iniFile)
|
||||
{
|
||||
CALuint count = 0;
|
||||
std::string line;
|
||||
bool inSection = false;
|
||||
|
||||
std::string sectionName;
|
||||
|
||||
IniSection* section = NULL;
|
||||
while(std::getline(in, line)) {
|
||||
count++;
|
||||
cleanup(line);
|
||||
if(line.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(parseSectionName(line, sectionName))
|
||||
{
|
||||
section = new IniSection(cmString(sectionName.c_str()));
|
||||
iniFile.addSection(section);
|
||||
inSection = true;
|
||||
}
|
||||
else if(inSection)
|
||||
{
|
||||
parseLine(line, section, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IniFileParser::parseLine( std::string line, IniSection* section, CALuint count ) {
|
||||
std::string::size_type equals = line.find( '=' );
|
||||
if ( equals == std::string::npos ) {
|
||||
#ifdef DEBUG
|
||||
std::cerr << "IniFileParser: Could not parse line " << count << ", ignoring.\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name( line, 0, equals );
|
||||
IniValue* value = parseValue( std::string( line, equals + 1, std::string::npos));
|
||||
|
||||
section->addEntry(cmString(trim(name).c_str()), value);
|
||||
}
|
||||
|
||||
void IniFileParser::cleanup( std::string& line ) {
|
||||
std::string copy = line;
|
||||
unsigned int begin = 0;
|
||||
while ( begin != line.size() && isspace(line[begin]))
|
||||
{
|
||||
++begin;
|
||||
}
|
||||
|
||||
bool inQuote = false;
|
||||
unsigned int end;
|
||||
for(end = begin; end != line.size(); ++end)
|
||||
{
|
||||
if ( line[end] == '\"' )
|
||||
{
|
||||
inQuote = !inQuote;
|
||||
}
|
||||
// comments starts with # or ;
|
||||
else if ( (line[end] == '#' || line[end] == ';') && !inQuote )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if ( line[ end ] == '\\' )
|
||||
{
|
||||
++end; // ignore next character
|
||||
if ( end == line.size() ) {
|
||||
#ifdef DEBUG
|
||||
std::cerr << "INIFileParser: Error parsing file: \\ character "
|
||||
"at the end of line (sorry, not supported)\n";
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ( end > begin && isspace( line[ end - 1 ] ) ) --end;
|
||||
// This is used over assign so that we don't have memcpy overrun
|
||||
// errors in valgrind.
|
||||
line = line.substr(begin, end - begin);
|
||||
}
|
||||
|
||||
class isint
|
||||
{
|
||||
public:
|
||||
isint()
|
||||
{
|
||||
is_int = true;
|
||||
}
|
||||
void operator() (char c)
|
||||
{
|
||||
is_int = is_int && isdigit(c);
|
||||
}
|
||||
bool is_int;
|
||||
};
|
||||
|
||||
class isfloat
|
||||
{
|
||||
public:
|
||||
isfloat()
|
||||
{
|
||||
is_float = true;
|
||||
}
|
||||
void operator() (char c)
|
||||
{
|
||||
is_float = is_float && (isdigit(c) || c == '.');
|
||||
}
|
||||
bool is_float;
|
||||
};
|
||||
|
||||
int cmp_nocase(const std::string& s1, const std::string& s2)
|
||||
{
|
||||
std::string::const_iterator p1 = s1.begin();
|
||||
std::string::const_iterator p2 = s2.begin();
|
||||
|
||||
while( p1 != s1.end() && p2 != s2.end())
|
||||
{
|
||||
if(toupper(*p1) != toupper(*p2))
|
||||
{
|
||||
return (toupper(*p1) < toupper(*p2)) ? -1 : 1;
|
||||
}
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
return static_cast<int>(s2.size()-s1.size());
|
||||
}
|
||||
|
||||
IniValue* IniFileParser::parseValue(std::string& value ) {
|
||||
std::string trimmed = trim(value);
|
||||
|
||||
std::stringstream ss(trimmed);
|
||||
|
||||
// look for a boolean
|
||||
static const std::string strTrue("true");
|
||||
static const std::string strFalse("false");
|
||||
if(cmp_nocase(trimmed, strTrue) == 0)
|
||||
{
|
||||
return new IniValueBool(CAL_TRUE);
|
||||
}
|
||||
if(cmp_nocase(trimmed, strFalse) == 0)
|
||||
{
|
||||
return new IniValueBool(CAL_FALSE);
|
||||
}
|
||||
|
||||
// try now to get an int
|
||||
isint ii;
|
||||
ii = std::for_each(trimmed.begin(),trimmed.end(), ii);
|
||||
if(ii.is_int)
|
||||
{
|
||||
CALint intValue = 0;
|
||||
ss >> intValue;
|
||||
return new IniValueInt(intValue);
|
||||
}
|
||||
|
||||
// if not an int, try to get a float
|
||||
isfloat isf;
|
||||
isf = std::for_each(trimmed.begin(),trimmed.end(), isf);
|
||||
if(isf.is_float)
|
||||
{
|
||||
CALfloat floatValue;
|
||||
// mbeuchat: Remove STL conversion of string to float. When compiled
|
||||
// on Linux, DK g++ with optimization requires linking against
|
||||
// libstdc++-6.0.9 which is not available on all Linux systems.
|
||||
// ss >> floatValue;
|
||||
floatValue = (float)atof(ss.str().c_str());
|
||||
return new IniValueFloat(floatValue);
|
||||
}
|
||||
|
||||
// finally, default to a string
|
||||
return new IniValueString(cmString(trimmed.c_str()));
|
||||
}
|
||||
|
||||
bool IniFileParser::parseSectionName(std::string line, std::string& section )
|
||||
{
|
||||
if ( line[ 0 ] != '[' ) return false;
|
||||
if ( line[ line.size() - 1 ] != ']' ) return false;
|
||||
|
||||
section.assign( line, 1, line.size() - 2 );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string IniFileParser::trim(std::string const& source, char const* delims) {
|
||||
std::string result(source);
|
||||
std::string::size_type index = result.find_last_not_of(delims);
|
||||
if(index != std::string::npos)
|
||||
result.erase(++index);
|
||||
|
||||
index = result.find_first_not_of(delims);
|
||||
if(index != std::string::npos)
|
||||
result.erase(0, index);
|
||||
else
|
||||
result.erase();
|
||||
return result;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef INIFILE_PARSER_H
|
||||
#define INIFILE_PARSER_H
|
||||
//
|
||||
// Trade secret of ATI Technologies, Inc.
|
||||
// Copyright 2005, ATI Technologies, Inc., (unpublished)
|
||||
//
|
||||
// All rights reserved. This notice is intended as a precaution against
|
||||
// inadvertent publication and does not imply publication or any waiver
|
||||
// of confidentiality. The year included in the foregoing notice is the
|
||||
// year of creation of the work.
|
||||
//
|
||||
|
||||
/// @file inifile_parser.h
|
||||
/// @brief INI File Parser Implementation
|
||||
|
||||
// if compiled from OGTST, add the following, normally defined in atitypes.h
|
||||
|
||||
#include "inifile.h"
|
||||
#include "cm_string.h"
|
||||
|
||||
#include <istream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
class IniFileParser
|
||||
{
|
||||
public:
|
||||
static void Parse(std::istream& in, IniFile& iniFile);
|
||||
|
||||
private:
|
||||
static void parseLine( std::string line, IniSection* section, CALuint count );
|
||||
static bool parseSectionName(std::string line, std::string& section );
|
||||
static IniValue* parseValue(std::string value );
|
||||
static void cleanup( std::string& line );
|
||||
static std::string trim(std::string const& source, char const* delims = " \t\r\n");
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -307,36 +307,7 @@ static constexpr MemoryFormat MemoryFormatMap[] = {
|
||||
Pal::ChNumFormat::X32Y32_Float,
|
||||
{Pal::ChannelSwizzle::X, Pal::ChannelSwizzle::Y, Pal::ChannelSwizzle::Zero,
|
||||
Pal::ChannelSwizzle::One}},
|
||||
/*
|
||||
// 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_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_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},
|
||||
Pal::ChNumFormat::X10Y10Z10W2_Unorm,
|
||||
|
||||
@@ -1755,14 +1755,14 @@ bool Device::bindExternalDevice(uint flags, void* const pDevice[], void* pContex
|
||||
#ifdef _WIN32
|
||||
if (flags & amd::Context::Flags::D3D10DeviceKhr) {
|
||||
if (!associateD3D10Device(pDevice[amd::Context::DeviceFlagIdx::D3D10DeviceKhrIdx])) {
|
||||
LogError("Failed gslD3D10Associate()");
|
||||
LogError("Failed associateD3D10Device()");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & amd::Context::Flags::D3D11DeviceKhr) {
|
||||
if (!associateD3D11Device(pDevice[amd::Context::DeviceFlagIdx::D3D11DeviceKhrIdx])) {
|
||||
LogError("Failed gslD3D11Associate()");
|
||||
LogError("Failed associateD3D11Device()");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1783,10 +1783,10 @@ bool Device::bindExternalDevice(uint flags, void* const pDevice[], void* pContex
|
||||
#endif //_WIN32
|
||||
|
||||
if (flags & amd::Context::Flags::GLDeviceKhr) {
|
||||
// Attempt to associate GSL-OGL
|
||||
// Attempt to associate PAL-OGL
|
||||
if (!glAssociate(pContext, pDevice[amd::Context::DeviceFlagIdx::GLDeviceKhrIdx])) {
|
||||
if (!validateOnly) {
|
||||
LogError("Failed gslGLAssociate()");
|
||||
LogError("Failed glAssociate()");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1803,10 +1803,10 @@ bool Device::unbindExternalDevice(uint flags, void* const pDevice[], void* pCont
|
||||
|
||||
void* glDevice = pDevice[amd::Context::DeviceFlagIdx::GLDeviceKhrIdx];
|
||||
if (glDevice != nullptr) {
|
||||
// Dissociate GSL-OGL
|
||||
// Dissociate PAL-OGL
|
||||
if (!glDissociate(pContext, glDevice)) {
|
||||
if (validateOnly) {
|
||||
LogWarning("Failed gslGLDiassociate()");
|
||||
LogWarning("Failed glDissociate()");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ class Device : public NullDevice {
|
||||
//! Initialize heap resources if uninitialized
|
||||
bool initializeHeapResources();
|
||||
|
||||
//! Set GSL sampler to the specified state
|
||||
//! Set HW sampler to the specified state
|
||||
void fillHwSampler(uint32_t state, //!< Sampler's OpenCL state
|
||||
void* hwState, //!< Sampler's HW state
|
||||
uint32_t hwStateSize, //!< Size of sampler's HW state
|
||||
|
||||
@@ -980,7 +980,7 @@ bool Resource::CreateInterop(CreateParams* params) {
|
||||
|
||||
dev().iDev()->CreateImageViewSrds(1, &viewInfo, hwState_);
|
||||
//! It's a workaround for D24S8 format, since PAL doesn't support this format
|
||||
//! and GSL decompresses 24bit DEPTH into D24S8 for OGL compatibility
|
||||
//! and OGL decompresses 24bit DEPTH into D24S8 for OGL compatibility
|
||||
if ((desc().format_.image_channel_order == CL_DEPTH_STENCIL) &&
|
||||
(desc().format_.image_channel_data_type == CL_UNORM_INT24)) {
|
||||
if (dev().settings().gfx10Plus_) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#ifndef WITHOUT_GPU_BACKEND
|
||||
#ifndef WITHOUT_HSA_BACKEND
|
||||
|
||||
#include "top.hpp"
|
||||
#include "os/os.hpp"
|
||||
@@ -232,4 +232,4 @@ void Settings::override() {
|
||||
}
|
||||
} // namespace roc
|
||||
|
||||
#endif // WITHOUT_GPU_BACKEND
|
||||
#endif // WITHOUT_HSA_BACKEND
|
||||
|
||||
@@ -84,15 +84,11 @@ namespace amd {
|
||||
bool IS_HIP = false;
|
||||
std::atomic_bool IS_PROFILER_ON(false);
|
||||
|
||||
#if defined(WITH_GPU_DEVICE)
|
||||
bool IS_LEGACY = true;
|
||||
#else
|
||||
#if !defined(_WIN32) && defined(WITH_PAL_DEVICE)
|
||||
bool IS_LEGACY = true;
|
||||
#else
|
||||
bool IS_LEGACY = false;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// static
|
||||
char* Flag::envstr_;
|
||||
|
||||
@@ -143,7 +143,7 @@ release(bool, GPU_IFH_MODE, false, \
|
||||
release(bool, GPU_MIPMAP, true, \
|
||||
"Enables GPU mipmap extension") \
|
||||
release(uint, GPU_ENABLE_PAL, 2, \
|
||||
"Enables PAL backend. 0 - GSL(default), 1 - PAL, 2 - GSL and PAL") \
|
||||
"Enables PAL backend. 0 - ROC, 1 - PAL, 2 - ROC or PAL") \
|
||||
release(bool, DISABLE_DEFERRED_ALLOC, false, \
|
||||
"Disables deferred memory allocation on device") \
|
||||
release(int, AMD_GPU_FORCE_SINGLE_FP_DENORM, -1, \
|
||||
|
||||
Referencia en una nueva incidencia
Block a user