From 446a78a134b7a2b32b0aa8aebd4c6d1fb88f0fe3 Mon Sep 17 00:00:00 2001 From: "Kopryk, Kamil" Date: Tue, 28 Dec 2021 22:17:46 +0000 Subject: [PATCH] Force stateless addressing mode for PVC PVC will support buffers greater than 4GB, hence we have to use stateless accessing mode as default. Signed-off-by: Kopryk, Kamil --- level_zero/core/test/unit_tests/main.cpp | 2 +- .../unit_test/built_ins/built_in_tests.cpp | 7 ++- .../command_queue/command_enqueue_fixture.h | 12 +++-- .../enqueue_read_buffer_rect_tests.cpp | 4 +- .../enqueue_write_buffer_rect_tests.cpp | 5 +- opencl/test/unit_test/main.cpp | 2 +- .../test/unit_test/mem_obj/buffer_tests.cpp | 7 ++- .../test/unit_test/offline_compiler/main.cpp | 2 + .../ocloc_validator_tests.cpp | 2 - .../offline_compiler_tests.cpp | 51 +++++++++++++++++++ ...d_write_buffer_scenarios_windows_tests.cpp | 4 +- .../pvc/test_hw_info_config_pvc.cpp | 5 ++ .../source/offline_compiler.cpp | 3 +- .../source/helpers/compiler_hw_info_config.h | 2 + .../compiler_hw_info_config_bdw_and_later.inl | 5 ++ .../source/xe_hpc_core/enable_xe_hpc_core.cpp | 2 + .../test/common/test_macros/test_excludes.cpp | 1 + shared/test/unit_test/main.cpp | 2 +- 18 files changed, 99 insertions(+), 19 deletions(-) diff --git a/level_zero/core/test/unit_tests/main.cpp b/level_zero/core/test/unit_tests/main.cpp index 9dfd4bbf2f..31e290be27 100644 --- a/level_zero/core/test/unit_tests/main.cpp +++ b/level_zero/core/test/unit_tests/main.cpp @@ -51,7 +51,7 @@ TestEnvironment *environment = nullptr; using namespace L0::ult; -PRODUCT_FAMILY productFamily = NEO::DEFAULT_TEST_PLATFORM::hwInfo.platform.eProductFamily; +extern PRODUCT_FAMILY productFamily; extern GFXCORE_FAMILY renderCoreFamily; int32_t revId = -1; uint32_t euPerSubSlice = 0; diff --git a/opencl/test/unit_test/built_ins/built_in_tests.cpp b/opencl/test/unit_test/built_ins/built_in_tests.cpp index 4cf3ffa705..c31bafa248 100644 --- a/opencl/test/unit_test/built_ins/built_in_tests.cpp +++ b/opencl/test/unit_test/built_ins/built_in_tests.cpp @@ -9,6 +9,7 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/gmm_helper/gmm.h" #include "shared/source/gmm_helper/gmm_helper.h" +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/source/helpers/file_io.h" #include "shared/source/helpers/hash.h" #include "shared/source/helpers/string.h" @@ -613,7 +614,8 @@ HWCMDTEST_P(IGFX_GEN8_CORE, AuxBuiltInTests, givenAuxTranslationKernelWhenSettin } HWTEST2_P(AuxBuiltInTests, givenAuxToNonAuxTranslationWhenSettingSurfaceStateThenSetValidAuxMode, AuxBuiltinsMatcher) { - if (this->pDevice->areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired()) { GTEST_SKIP(); } @@ -669,7 +671,8 @@ HWTEST2_P(AuxBuiltInTests, givenAuxToNonAuxTranslationWhenSettingSurfaceStateThe } HWTEST2_P(AuxBuiltInTests, givenNonAuxToAuxTranslationWhenSettingSurfaceStateThenSetValidAuxMode, AuxBuiltinsMatcher) { - if (this->pDevice->areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired()) { GTEST_SKIP(); } diff --git a/opencl/test/unit_test/command_queue/command_enqueue_fixture.h b/opencl/test/unit_test/command_queue/command_enqueue_fixture.h index df61ba0282..a1d88e2da4 100644 --- a/opencl/test/unit_test/command_queue/command_enqueue_fixture.h +++ b/opencl/test/unit_test/command_queue/command_enqueue_fixture.h @@ -6,6 +6,7 @@ */ #pragma once +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/test/common/mocks/mock_memory_manager.h" #include "opencl/source/command_queue/command_queue_hw.h" @@ -115,14 +116,17 @@ struct CommandQueueStateful : public CommandQueueHw { void enqueueHandlerHook(const unsigned int commandType, const MultiDispatchInfo &dispatchInfo) override { auto kernel = dispatchInfo.begin()->getKernel(); auto &device = dispatchInfo.begin()->getClDevice(); - if (!device.areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(device.getHardwareInfo().platform.eProductFamily); + + if (compilerHwInfoConfig.isForceToStatelessRequired()) { + EXPECT_TRUE(kernel->getKernelInfo().kernelDescriptor.kernelAttributes.supportsBuffersBiggerThan4Gb()); + EXPECT_FALSE(kernel->getKernelInfo().getArgDescriptorAt(0).as().isPureStateful()); + } else { EXPECT_FALSE(kernel->getKernelInfo().kernelDescriptor.kernelAttributes.supportsBuffersBiggerThan4Gb()); + if (HwHelperHw::get().isStatelesToStatefullWithOffsetSupported()) { EXPECT_TRUE(kernel->allBufferArgsStateful); } - } else { - EXPECT_TRUE(kernel->getKernelInfo().kernelDescriptor.kernelAttributes.supportsBuffersBiggerThan4Gb()); - EXPECT_FALSE(kernel->getKernelInfo().getArgDescriptorAt(0).as().isPureStateful()); } } }; diff --git a/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp index 0da4bfbceb..921c411e47 100644 --- a/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp @@ -6,6 +6,7 @@ */ #include "shared/source/built_ins/built_ins.h" +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/test_macros/test.h" #include "shared/test/unit_test/utilities/base_object_utils.h" @@ -549,7 +550,8 @@ HWTEST_F(EnqueueReadBufferRectTest, givenInOrderQueueAndDstPtrEqualSrcPtrAndNonZ HWTEST_F(EnqueueReadWriteBufferRectDispatch, givenOffsetResultingInMisalignedPtrWhenEnqueueReadBufferRectForNon3DCaseIsCalledThenAddressInStateBaseAddressIsAlignedAndMatchesKernelDispatchInfoParams) { hwInfo->capabilityTable.blitterOperationsSupported = false; initializeFixture(); - if (device->areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired()) { GTEST_SKIP(); } diff --git a/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp index 5499140edc..20ca448480 100644 --- a/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp @@ -6,6 +6,7 @@ */ #include "shared/source/built_ins/built_ins.h" +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/test_macros/test.h" #include "shared/test/unit_test/utilities/base_object_utils.h" @@ -549,10 +550,10 @@ HWTEST_F(EnqueueReadWriteBufferRectDispatch, givenOffsetResultingInMisalignedPtr hwInfo->capabilityTable.blitterOperationsSupported = false; initializeFixture(); - if (device->areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired()) { GTEST_SKIP(); } - auto cmdQ = std::make_unique>(context.get(), device.get(), &properties); buffer->forceDisallowCPUCopy = true; diff --git a/opencl/test/unit_test/main.cpp b/opencl/test/unit_test/main.cpp index 07354905a7..fbca7ff34f 100644 --- a/opencl/test/unit_test/main.cpp +++ b/opencl/test/unit_test/main.cpp @@ -64,7 +64,7 @@ bool disabled = false; using namespace NEO; -PRODUCT_FAMILY productFamily = DEFAULT_TEST_PLATFORM::hwInfo.platform.eProductFamily; +extern PRODUCT_FAMILY productFamily; extern GFXCORE_FAMILY renderCoreFamily; extern std::string lastTest; diff --git a/opencl/test/unit_test/mem_obj/buffer_tests.cpp b/opencl/test/unit_test/mem_obj/buffer_tests.cpp index 95b8ecbe53..13ccd6bad8 100644 --- a/opencl/test/unit_test/mem_obj/buffer_tests.cpp +++ b/opencl/test/unit_test/mem_obj/buffer_tests.cpp @@ -7,6 +7,7 @@ #include "shared/source/gmm_helper/gmm_helper.h" #include "shared/source/helpers/array_count.h" +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/source/helpers/hw_helper.h" #include "shared/source/memory_manager/memory_operations_handler.h" #include "shared/source/memory_manager/unified_memory_manager.h" @@ -1821,7 +1822,8 @@ class BufferL3CacheTests : public ::testing::TestWithParam { }; HWTEST_P(BufferL3CacheTests, givenMisalignedAndAlignedBufferWhenClEnqueueWriteImageThenL3CacheIsOn) { - if (ctx.getDevice(0)->areSharedSystemAllocationsAllowed() || !ctx.getDevice(0)->getHardwareInfo().capabilityTable.supportsImages) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired() || !ctx.getDevice(0)->getHardwareInfo().capabilityTable.supportsImages) { GTEST_SKIP(); } using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; @@ -1857,7 +1859,8 @@ HWTEST_P(BufferL3CacheTests, givenMisalignedAndAlignedBufferWhenClEnqueueWriteIm } HWTEST_P(BufferL3CacheTests, givenMisalignedAndAlignedBufferWhenClEnqueueWriteBufferRectThenL3CacheIsOn) { - if (ctx.getDevice(0)->areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired()) { GTEST_SKIP(); } using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; diff --git a/opencl/test/unit_test/offline_compiler/main.cpp b/opencl/test/unit_test/offline_compiler/main.cpp index 3ce63836f7..465c7f9179 100644 --- a/opencl/test/unit_test/offline_compiler/main.cpp +++ b/opencl/test/unit_test/offline_compiler/main.cpp @@ -20,6 +20,7 @@ const char *fSeparator = "/"; #endif Environment *gEnvironment; +extern PRODUCT_FAMILY productFamily; extern GFXCORE_FAMILY renderCoreFamily; std::string getRunPath() { @@ -94,6 +95,7 @@ int main(int argc, char **argv) { if (NEO::hardwarePrefix[productId] && (0 == strcmp(devicePrefix.c_str(), NEO::hardwarePrefix[productId]))) { if (NEO::hardwareInfoTable[productId]) { renderCoreFamily = NEO::hardwareInfoTable[productId]->platform.eRenderCoreFamily; + productFamily = NEO::hardwareInfoTable[productId]->platform.eProductFamily; break; } } diff --git a/opencl/test/unit_test/offline_compiler/ocloc_validator_tests.cpp b/opencl/test/unit_test/offline_compiler/ocloc_validator_tests.cpp index 0019fc80b6..af8b99b264 100644 --- a/opencl/test/unit_test/offline_compiler/ocloc_validator_tests.cpp +++ b/opencl/test/unit_test/offline_compiler/ocloc_validator_tests.cpp @@ -13,8 +13,6 @@ #include "gtest/gtest.h" -PRODUCT_FAMILY productFamily; - TEST(OclocValidate, WhenFileArgIsMissingThenFail) { std::map files; MockOclocArgHelper argHelper{files}; diff --git a/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp b/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp index e81d2d692a..966c1b71c7 100644 --- a/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp +++ b/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp @@ -12,10 +12,13 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/device_binary_format/elf/elf_decoder.h" #include "shared/source/device_binary_format/elf/ocl_elf.h" +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/source/helpers/file_io.h" #include "shared/source/helpers/hw_info.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" +#include "shared/test/common/helpers/variable_backup.h" #include "shared/test/common/mocks/mock_compilers.h" +#include "shared/test/common/test_macros/test.h" #include "shared/test/unit_test/device_binary_format/zebin_tests.h" #include "compiler_options.h" @@ -1561,6 +1564,54 @@ TEST(OfflineCompilerTest, givenInputOptionsAndOclockOptionsFileWithForceStosOptW EXPECT_EQ(std::string::npos, found); } +struct OfflineCompilerStatelessToStatefulTests : public ::testing::Test { + void SetUp() override { + mockOfflineCompiler = std::make_unique(); + mockOfflineCompiler->deviceName = gEnvironment->devicePrefix; + mockOfflineCompiler->initHardwareInfo(mockOfflineCompiler->deviceName); + } + void runTest() const { + std::pair testParams[] = {{true, false}, {false, true}}; + + for (const auto &[forceStatelessToStatefulOptimization, containsGreaterThan4gbBuffersRequired] : testParams) { + auto internalOptions = mockOfflineCompiler->internalOptions; + mockOfflineCompiler->forceStatelessToStatefulOptimization = forceStatelessToStatefulOptimization; + mockOfflineCompiler->appendExtraInternalOptions(mockOfflineCompiler->hwInfo, internalOptions); + auto found = internalOptions.find(NEO::CompilerOptions::greaterThan4gbBuffersRequired.data()); + + if (containsGreaterThan4gbBuffersRequired) { + EXPECT_NE(std::string::npos, found); + } else { + EXPECT_EQ(std::string::npos, found); + } + } + } + + std::unique_ptr mockOfflineCompiler; +}; + +TEST_F(OfflineCompilerStatelessToStatefulTests, whenAppendExtraInternalOptionsThenInternalOptionsAreCorrect) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(mockOfflineCompiler->hwInfo.platform.eProductFamily); + if (!compilerHwInfoConfig.isForceToStatelessRequired()) { + GTEST_SKIP(); + } + runTest(); +} + +template +class MockCompilerHwInfoConfigHw : public CompilerHwInfoConfigHw { + public: + bool isForceToStatelessRequired() const override { + return true; + } +}; + +HWTEST2_F(OfflineCompilerStatelessToStatefulTests, givenMockWhenAppendExtraInternalOptionsThenInternalOptionsAreCorrect, MatchAny) { + MockCompilerHwInfoConfigHw mockCompilerHwInfoConfig; + VariableBackup backupMockHwInfoConfig(&CompilerHwInfoConfigFactory[productFamily], &mockCompilerHwInfoConfig); + runTest(); +} + TEST(OfflineCompilerTest, givenNonExistingFilenameWhenUsedToReadOptionsThenReadOptionsFromFileReturnsFalse) { std::string options; std::string file("non_existing_file"); diff --git a/opencl/test/unit_test/scenarios/windows/enqueue_read_write_buffer_scenarios_windows_tests.cpp b/opencl/test/unit_test/scenarios/windows/enqueue_read_write_buffer_scenarios_windows_tests.cpp index b8624a8df0..acb9739782 100644 --- a/opencl/test/unit_test/scenarios/windows/enqueue_read_write_buffer_scenarios_windows_tests.cpp +++ b/opencl/test/unit_test/scenarios/windows/enqueue_read_write_buffer_scenarios_windows_tests.cpp @@ -5,6 +5,7 @@ * */ +#include "shared/source/helpers/compiler_hw_info_config.h" #include "shared/source/memory_manager/internal_allocation_storage.h" #include "shared/source/os_interface/os_interface.h" #include "shared/source/os_interface/windows/wddm_device_command_stream.h" @@ -81,7 +82,8 @@ HWTEST_F(EnqueueBufferWindowsTest, givenMisalignedHostPtrWhenEnqueueReadBufferCa GTEST_SKIP(); } initializeFixture(); - if (device->areSharedSystemAllocationsAllowed()) { + const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily); + if (compilerHwInfoConfig.isForceToStatelessRequired()) { GTEST_SKIP(); } auto cmdQ = std::make_unique>(context.get(), device.get(), &properties); diff --git a/opencl/test/unit_test/xe_hpc_core/pvc/test_hw_info_config_pvc.cpp b/opencl/test/unit_test/xe_hpc_core/pvc/test_hw_info_config_pvc.cpp index 428bbc9521..7425de269e 100644 --- a/opencl/test/unit_test/xe_hpc_core/pvc/test_hw_info_config_pvc.cpp +++ b/opencl/test/unit_test/xe_hpc_core/pvc/test_hw_info_config_pvc.cpp @@ -72,6 +72,11 @@ PVCTEST_F(PvcHwInfoConfig, givenHwInfoConfigAndProgramPipeControlPriorToNonPipel EXPECT_FALSE(hwInfoConfig.isPipeControlPriorToNonPipelinedStateCommandsWARequired(hwInfo, isRcs)); } +using CompilerHwInfoConfigHelperTestsPvc = ::testing::Test; +PVCTEST_F(CompilerHwInfoConfigHelperTestsPvc, givenPvcWhenIsForceToStatelessRequiredIsCalledThenReturnsTrue) { + EXPECT_TRUE(CompilerHwInfoConfig::get(productFamily)->isForceToStatelessRequired()); +} + using PvcHwInfo = ::testing::Test; PVCTEST_F(PvcHwInfo, givenPvcWhenConfiguringThenDisableCccs) { diff --git a/shared/offline_compiler/source/offline_compiler.cpp b/shared/offline_compiler/source/offline_compiler.cpp index 19eaa69d70..7aae301db5 100644 --- a/shared/offline_compiler/source/offline_compiler.cpp +++ b/shared/offline_compiler/source/offline_compiler.cpp @@ -771,8 +771,7 @@ void OfflineCompiler::setStatelessToStatefullBufferOffsetFlag() { void OfflineCompiler::appendExtraInternalOptions(const HardwareInfo &hwInfo, std::string &internalOptions) { const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(hwInfo.platform.eProductFamily); - auto sharedSystemMemCapabilitiesSupported = (hwInfo.capabilityTable.sharedSystemMemCapabilities > 0); - if (sharedSystemMemCapabilitiesSupported && !forceStatelessToStatefulOptimization) { + if (compilerHwInfoConfig.isForceToStatelessRequired() && !forceStatelessToStatefulOptimization) { CompilerOptions::concatenateAppend(internalOptions, CompilerOptions::greaterThan4gbBuffersRequired); } if (compilerHwInfoConfig.isForceEmuInt32DivRemSPRequired()) { diff --git a/shared/source/helpers/compiler_hw_info_config.h b/shared/source/helpers/compiler_hw_info_config.h index 543fe15a4d..ba25e9fb7f 100644 --- a/shared/source/helpers/compiler_hw_info_config.h +++ b/shared/source/helpers/compiler_hw_info_config.h @@ -26,6 +26,7 @@ class CompilerHwInfoConfig { virtual bool isMidThreadPreemptionSupported(const HardwareInfo &hwInfo) const = 0; virtual bool isForceEmuInt32DivRemSPRequired() const = 0; virtual bool isStatelessToStatefulBufferOffsetSupported() const = 0; + virtual bool isForceToStatelessRequired() const = 0; }; template @@ -39,6 +40,7 @@ class CompilerHwInfoConfigHw : public CompilerHwInfoConfig { bool isMidThreadPreemptionSupported(const HardwareInfo &hwInfo) const override; bool isForceEmuInt32DivRemSPRequired() const override; bool isStatelessToStatefulBufferOffsetSupported() const override; + bool isForceToStatelessRequired() const override; protected: CompilerHwInfoConfigHw() = default; diff --git a/shared/source/helpers/compiler_hw_info_config_bdw_and_later.inl b/shared/source/helpers/compiler_hw_info_config_bdw_and_later.inl index d2a5c15bc1..4f459842b3 100644 --- a/shared/source/helpers/compiler_hw_info_config_bdw_and_later.inl +++ b/shared/source/helpers/compiler_hw_info_config_bdw_and_later.inl @@ -16,4 +16,9 @@ bool CompilerHwInfoConfigHw::isMidThreadPreemptionSupported(const Ha return hwInfo.featureTable.flags.ftrGpGpuMidThreadLevelPreempt; } +template +bool CompilerHwInfoConfigHw::isForceToStatelessRequired() const { + return false; +} + } // namespace NEO diff --git a/shared/source/xe_hpc_core/enable_xe_hpc_core.cpp b/shared/source/xe_hpc_core/enable_xe_hpc_core.cpp index 5b954d921f..03d26545a2 100644 --- a/shared/source/xe_hpc_core/enable_xe_hpc_core.cpp +++ b/shared/source/xe_hpc_core/enable_xe_hpc_core.cpp @@ -15,6 +15,8 @@ namespace NEO { #ifdef SUPPORT_PVC static EnableGfxProductHw enableGfxProductHwPVC; + +#include "shared/source/xe_hpc_core/compiler_hw_info_config_pvc.inl" static EnableCompilerHwInfoConfig enableCompilerHwInfoConfigPVC; #endif diff --git a/shared/test/common/test_macros/test_excludes.cpp b/shared/test/common/test_macros/test_excludes.cpp index df412e6c44..7edbdbb950 100644 --- a/shared/test/common/test_macros/test_excludes.cpp +++ b/shared/test/common/test_macros/test_excludes.cpp @@ -16,6 +16,7 @@ using namespace NEO; +PRODUCT_FAMILY productFamily = {}; GFXCORE_FAMILY renderCoreFamily = {}; static std::unique_ptr>> pProductExcludesPerTest; diff --git a/shared/test/unit_test/main.cpp b/shared/test/unit_test/main.cpp index f6e20eb992..012da88532 100644 --- a/shared/test/unit_test/main.cpp +++ b/shared/test/unit_test/main.cpp @@ -66,7 +66,7 @@ bool disabled = false; using namespace NEO; -PRODUCT_FAMILY productFamily = DEFAULT_TEST_PLATFORM::hwInfo.platform.eProductFamily; +extern PRODUCT_FAMILY productFamily; extern GFXCORE_FAMILY renderCoreFamily; extern std::string lastTest;