Encode dispatch kernel with global bindless heaps

Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
Maciej Plewka
2020-11-26 09:04:26 +00:00
committed by Compute-Runtime-Automation
parent be90b9ff93
commit 7a5c9d39b5
14 changed files with 478 additions and 149 deletions

View File

@@ -178,7 +178,7 @@ HWTEST_F(CommandListAppendLaunchKernel, WhenAppendingMultipleTimesThenSshIsNotDe
auto sshHeapSize = ssh->getMaxAvailableSpace(); auto sshHeapSize = ssh->getMaxAvailableSpace();
auto initialAllocation = ssh->getGraphicsAllocation(); auto initialAllocation = ssh->getGraphicsAllocation();
EXPECT_NE(nullptr, initialAllocation); EXPECT_NE(nullptr, initialAllocation);
const_cast<KernelDescriptor::AddressingMode &>(kernel->getKernelDescriptor().kernelAttributes.bufferAddressingMode) = KernelDescriptor::BindfulAndStateless;
for (size_t i = 0; i < sshHeapSize / kernelSshSize + 1; i++) { for (size_t i = 0; i < sshHeapSize / kernelSshSize + 1; i++) {
auto result = commandList->appendLaunchKernel(kernel->toHandle(), &groupCount, nullptr, 0, nullptr); auto result = commandList->appendLaunchKernel(kernel->toHandle(), &groupCount, nullptr, 0, nullptr);
ASSERT_EQ(ZE_RESULT_SUCCESS, result); ASSERT_EQ(ZE_RESULT_SUCCESS, result);

View File

@@ -241,7 +241,7 @@ size_t HardwareCommandsHelper<GfxFamily>::sendIndirectState(
uint32_t samplerCount = 0; uint32_t samplerCount = 0;
if (patchInfo.samplerStateArray) { if (patchInfo.samplerStateArray) {
samplerCount = patchInfo.samplerStateArray->Count; samplerCount = patchInfo.samplerStateArray->Count;
samplerStateOffset = EncodeStates<GfxFamily>::copySamplerState(&dsh, patchInfo.samplerStateArray->Offset, samplerCount, patchInfo.samplerStateArray->BorderColorOffset, kernel.getDynamicStateHeap()); samplerStateOffset = EncodeStates<GfxFamily>::copySamplerState(&dsh, patchInfo.samplerStateArray->Offset, samplerCount, patchInfo.samplerStateArray->BorderColorOffset, kernel.getDynamicStateHeap(), device.getBindlessHeapsHelper());
} }
auto threadPayload = kernel.getKernelInfo().patchInfo.threadPayload; auto threadPayload = kernel.getKernelInfo().patchInfo.threadPayload;

View File

@@ -21,6 +21,7 @@ namespace NEO {
class GmmHelper; class GmmHelper;
struct HardwareInfo; struct HardwareInfo;
class IndirectHeap; class IndirectHeap;
class BindlessHeapsHelper;
template <typename GfxFamily> template <typename GfxFamily>
struct EncodeDispatchKernel { struct EncodeDispatchKernel {
@@ -46,8 +47,6 @@ struct EncodeDispatchKernel {
static size_t estimateEncodeDispatchKernelCmdsSize(Device *device); static size_t estimateEncodeDispatchKernelCmdsSize(Device *device);
static void patchBindlessSurfaceStateOffsets(const size_t sshOffset, const KernelDescriptor &kernelDesc, uint8_t *crossThread);
static bool isRuntimeLocalIdsGenerationRequired(uint32_t activeChannels, static bool isRuntimeLocalIdsGenerationRequired(uint32_t activeChannels,
size_t *lws, size_t *lws,
std::array<uint8_t, 3> walkOrder, std::array<uint8_t, 3> walkOrder,
@@ -84,6 +83,7 @@ struct EncodeStates {
using BINDING_TABLE_STATE = typename GfxFamily::BINDING_TABLE_STATE; using BINDING_TABLE_STATE = typename GfxFamily::BINDING_TABLE_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename GfxFamily::INTERFACE_DESCRIPTOR_DATA; using INTERFACE_DESCRIPTOR_DATA = typename GfxFamily::INTERFACE_DESCRIPTOR_DATA;
using SAMPLER_STATE = typename GfxFamily::SAMPLER_STATE; using SAMPLER_STATE = typename GfxFamily::SAMPLER_STATE;
using SAMPLER_BORDER_COLOR_STATE = typename GfxFamily::SAMPLER_BORDER_COLOR_STATE;
static const uint32_t alignIndirectStatePointer = MemoryConstants::cacheLineSize; static const uint32_t alignIndirectStatePointer = MemoryConstants::cacheLineSize;
static const size_t alignInterfaceDescriptorData = MemoryConstants::cacheLineSize; static const size_t alignInterfaceDescriptorData = MemoryConstants::cacheLineSize;
@@ -92,7 +92,8 @@ struct EncodeStates {
uint32_t samplerStateOffset, uint32_t samplerStateOffset,
uint32_t samplerCount, uint32_t samplerCount,
uint32_t borderColorOffset, uint32_t borderColorOffset,
const void *fnDynamicStateHeap); const void *fnDynamicStateHeap,
BindlessHeapsHelper *bindlessHeapHelper);
static void adjustStateComputeMode(LinearStream &csr, uint32_t numGrfRequired, void *const stateComputeModePtr, bool isMultiOsContextCapable, bool requiresCoherency); static void adjustStateComputeMode(LinearStream &csr, uint32_t numGrfRequired, void *const stateComputeModePtr, bool isMultiOsContextCapable, bool requiresCoherency);

View File

@@ -12,6 +12,8 @@
#include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/execution_environment.h"
#include "shared/source/gmm_helper/gmm.h" #include "shared/source/gmm_helper/gmm.h"
#include "shared/source/gmm_helper/gmm_helper.h" #include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/api_specific_config.h"
#include "shared/source/helpers/bindless_heaps_helper.h"
#include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/hw_helper.h"
#include "shared/source/helpers/local_id_gen.h" #include "shared/source/helpers/local_id_gen.h"
#include "shared/source/helpers/preamble.h" #include "shared/source/helpers/preamble.h"
@@ -30,22 +32,44 @@ uint32_t EncodeStates<Family>::copySamplerState(IndirectHeap *dsh,
uint32_t samplerStateOffset, uint32_t samplerStateOffset,
uint32_t samplerCount, uint32_t samplerCount,
uint32_t borderColorOffset, uint32_t borderColorOffset,
const void *fnDynamicStateHeap) { const void *fnDynamicStateHeap,
BindlessHeapsHelper *bindlessHeapHelper) {
auto sizeSamplerState = sizeof(SAMPLER_STATE) * samplerCount; auto sizeSamplerState = sizeof(SAMPLER_STATE) * samplerCount;
auto borderColorSize = samplerStateOffset - borderColorOffset; auto borderColorSize = samplerStateOffset - borderColorOffset;
SAMPLER_STATE *dstSamplerState = nullptr;
uint32_t samplerStateOffsetInDsh = 0;
dsh->align(EncodeStates<Family>::alignIndirectStatePointer); dsh->align(EncodeStates<Family>::alignIndirectStatePointer);
auto borderColorOffsetInDsh = static_cast<uint32_t>(dsh->getUsed()); uint32_t borderColorOffsetInDsh = 0;
if (!ApiSpecificConfig::getBindlessConfiguration()) {
borderColorOffsetInDsh = static_cast<uint32_t>(dsh->getUsed());
auto borderColor = dsh->getSpace(borderColorSize);
auto borderColor = dsh->getSpace(borderColorSize); memcpy_s(borderColor, borderColorSize, ptrOffset(fnDynamicStateHeap, borderColorOffset),
borderColorSize);
memcpy_s(borderColor, borderColorSize, ptrOffset(fnDynamicStateHeap, borderColorOffset), dsh->align(INTERFACE_DESCRIPTOR_DATA::SAMPLERSTATEPOINTER_ALIGN_SIZE);
borderColorSize); samplerStateOffsetInDsh = static_cast<uint32_t>(dsh->getUsed());
dsh->align(INTERFACE_DESCRIPTOR_DATA::SAMPLERSTATEPOINTER_ALIGN_SIZE); dstSamplerState = reinterpret_cast<SAMPLER_STATE *>(dsh->getSpace(sizeSamplerState));
auto samplerStateOffsetInDsh = static_cast<uint32_t>(dsh->getUsed()); } else {
auto borderColor = reinterpret_cast<const SAMPLER_BORDER_COLOR_STATE *>(ptrOffset(fnDynamicStateHeap, borderColorOffset));
auto dstSamplerState = reinterpret_cast<SAMPLER_STATE *>(dsh->getSpace(sizeSamplerState)); if (borderColor->getBorderColorRed() != 0.0f ||
borderColor->getBorderColorGreen() != 0.0f ||
borderColor->getBorderColorBlue() != 0.0f ||
(borderColor->getBorderColorAlpha() != 0.0f && borderColor->getBorderColorAlpha() != 1.0f)) {
UNRECOVERABLE_IF(true);
} else if (borderColor->getBorderColorAlpha() == 0.0f) {
borderColorOffsetInDsh = bindlessHeapHelper->getDefaultBorderColorOffset();
} else {
borderColorOffsetInDsh = bindlessHeapHelper->getAlphaBorderColorOffset();
}
dsh->align(INTERFACE_DESCRIPTOR_DATA::SAMPLERSTATEPOINTER_ALIGN_SIZE);
auto samplerStateInDsh = bindlessHeapHelper->allocateSSInHeap(sizeSamplerState, nullptr, BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
dstSamplerState = reinterpret_cast<SAMPLER_STATE *>(samplerStateInDsh.ssPtr);
samplerStateOffsetInDsh = static_cast<uint32_t>(samplerStateInDsh.surfaceStateOffset);
}
auto srcSamplerState = reinterpret_cast<const SAMPLER_STATE *>(ptrOffset(fnDynamicStateHeap, samplerStateOffset)); auto srcSamplerState = reinterpret_cast<const SAMPLER_STATE *>(ptrOffset(fnDynamicStateHeap, samplerStateOffset));
SAMPLER_STATE state = {}; SAMPLER_STATE state = {};
@@ -56,7 +80,7 @@ uint32_t EncodeStates<Family>::copySamplerState(IndirectHeap *dsh,
} }
return samplerStateOffsetInDsh; return samplerStateOffsetInDsh;
} } // namespace NEO
template <typename Family> template <typename Family>
size_t EncodeStates<Family>::getAdjustStateComputeModeSize() { size_t EncodeStates<Family>::getAdjustStateComputeModeSize() {
@@ -382,40 +406,6 @@ void *EncodeDispatchKernel<Family>::getInterfaceDescriptor(CommandContainer &con
return &interfaceDescriptorData[container.nextIddInBlock++]; return &interfaceDescriptorData[container.nextIddInBlock++];
} }
template <typename Family>
void EncodeDispatchKernel<Family>::patchBindlessSurfaceStateOffsets(const size_t sshOffset, const KernelDescriptor &kernelDesc, uint8_t *crossThread) {
auto &hwHelper = HwHelperHw<Family>::get();
for (const auto &argT : kernelDesc.payloadMappings.explicitArgs) {
CrossThreadDataOffset bindless = undefined<CrossThreadDataOffset>;
SurfaceStateHeapOffset bindful = undefined<SurfaceStateHeapOffset>;
switch (argT.type) {
case ArgDescriptor::ArgTPointer: {
auto &arg = argT.as<NEO::ArgDescPointer>();
bindless = arg.bindless;
bindful = arg.bindful;
} break;
case ArgDescriptor::ArgTImage: {
auto &arg = argT.as<NEO::ArgDescImage>();
bindless = arg.bindless;
bindful = arg.bindful;
} break;
default:
break;
}
if (NEO::isValidOffset(bindless)) {
auto patchLocation = ptrOffset(crossThread, bindless);
auto bindlessOffset = static_cast<uint32_t>(sshOffset) + bindful;
auto patchValue = hwHelper.getBindlessSurfaceExtendedMessageDescriptorValue(bindlessOffset);
patchWithRequiredSize(patchLocation, sizeof(patchValue), patchValue);
}
}
}
template <typename Family> template <typename Family>
bool EncodeDispatchKernel<Family>::inlineDataProgrammingRequired(const KernelDescriptor &kernelDesc) { bool EncodeDispatchKernel<Family>::inlineDataProgrammingRequired(const KernelDescriptor &kernelDesc) {
auto checkKernelForInlineData = true; auto checkKernelForInlineData = true;

View File

@@ -11,6 +11,7 @@
#include "shared/source/command_stream/preemption.h" #include "shared/source/command_stream/preemption.h"
#include "shared/source/execution_environment/execution_environment.h" #include "shared/source/execution_environment/execution_environment.h"
#include "shared/source/gmm_helper/gmm_helper.h" #include "shared/source/gmm_helper/gmm_helper.h"
#include "shared/source/helpers/api_specific_config.h"
#include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/hw_helper.h"
#include "shared/source/helpers/simd_helper.h" #include "shared/source/helpers/simd_helper.h"
#include "shared/source/helpers/state_base_address.h" #include "shared/source/helpers/state_base_address.h"
@@ -79,22 +80,25 @@ void EncodeDispatchKernel<Family>::encode(CommandContainer &container,
uint32_t bindingTableStateCount = kernelDescriptor.payloadMappings.bindingTable.numEntries; uint32_t bindingTableStateCount = kernelDescriptor.payloadMappings.bindingTable.numEntries;
uint32_t bindingTablePointer = 0u; uint32_t bindingTablePointer = 0u;
bool isBindlessKernel = kernelDescriptor.kernelAttributes.bufferAddressingMode == KernelDescriptor::BindlessAndStateless;
if (!isBindlessKernel) {
if (bindingTableStateCount > 0u) { if (bindingTableStateCount > 0u) {
auto ssh = container.getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, dispatchInterface->getSurfaceStateHeapDataSize(), BINDING_TABLE_STATE::SURFACESTATEPOINTER_ALIGN_SIZE); auto ssh = container.getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, dispatchInterface->getSurfaceStateHeapDataSize(), BINDING_TABLE_STATE::SURFACESTATEPOINTER_ALIGN_SIZE);
sshOffset = ssh->getUsed(); sshOffset = ssh->getUsed();
bindingTablePointer = static_cast<uint32_t>(EncodeSurfaceState<Family>::pushBindingTableAndSurfaceStates( bindingTablePointer = static_cast<uint32_t>(EncodeSurfaceState<Family>::pushBindingTableAndSurfaceStates(
*ssh, bindingTableStateCount, *ssh, bindingTableStateCount,
dispatchInterface->getSurfaceStateHeapData(), dispatchInterface->getSurfaceStateHeapData(),
dispatchInterface->getSurfaceStateHeapDataSize(), bindingTableStateCount, dispatchInterface->getSurfaceStateHeapDataSize(), bindingTableStateCount,
kernelDescriptor.payloadMappings.bindingTable.tableOffset)); kernelDescriptor.payloadMappings.bindingTable.tableOffset));
}
idd.setBindingTablePointer(bindingTablePointer);
} }
idd.setBindingTablePointer(bindingTablePointer);
PreemptionHelper::programInterfaceDescriptorDataPreemption<Family>(&idd, preemptionMode); PreemptionHelper::programInterfaceDescriptorDataPreemption<Family>(&idd, preemptionMode);
auto heap = container.getIndirectHeap(HeapType::DYNAMIC_STATE); auto heap = ApiSpecificConfig::getBindlessConfiguration() ? device->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::GLOBAL_DSH) : container.getIndirectHeap(HeapType::DYNAMIC_STATE);
UNRECOVERABLE_IF(!heap); UNRECOVERABLE_IF(!heap);
uint32_t samplerStateOffset = 0; uint32_t samplerStateOffset = 0;
@@ -105,7 +109,11 @@ void EncodeDispatchKernel<Family>::encode(CommandContainer &container,
samplerStateOffset = EncodeStates<Family>::copySamplerState(heap, kernelDescriptor.payloadMappings.samplerTable.tableOffset, samplerStateOffset = EncodeStates<Family>::copySamplerState(heap, kernelDescriptor.payloadMappings.samplerTable.tableOffset,
kernelDescriptor.payloadMappings.samplerTable.numSamplers, kernelDescriptor.payloadMappings.samplerTable.numSamplers,
kernelDescriptor.payloadMappings.samplerTable.borderColor, kernelDescriptor.payloadMappings.samplerTable.borderColor,
dispatchInterface->getDynamicStateHeapData()); dispatchInterface->getDynamicStateHeapData(),
device->getBindlessHeapsHelper());
if (ApiSpecificConfig::getBindlessConfiguration()) {
container.getResidencyContainer().push_back(device->getBindlessHeapsHelper()->getHeap(NEO::BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH)->getGraphicsAllocation());
}
} }
idd.setSamplerStatePointer(samplerStateOffset); idd.setSamplerStatePointer(samplerStateOffset);
@@ -139,10 +147,6 @@ void EncodeDispatchKernel<Family>::encode(CommandContainer &container,
EncodeIndirectParams<Family>::setGlobalWorkSizeIndirect(container, kernelDescriptor.payloadMappings.dispatchTraits.globalWorkSize, gpuPtr, dispatchInterface->getGroupSize()); EncodeIndirectParams<Family>::setGlobalWorkSizeIndirect(container, kernelDescriptor.payloadMappings.dispatchTraits.globalWorkSize, gpuPtr, dispatchInterface->getGroupSize());
} }
if (kernelDescriptor.payloadMappings.bindingTable.numEntries > 0) {
patchBindlessSurfaceStateOffsets(sshOffset, dispatchInterface->getKernelDescriptor(), reinterpret_cast<uint8_t *>(ptr));
}
ptr = ptrOffset(ptr, sizeCrossThreadData); ptr = ptrOffset(ptr, sizeCrossThreadData);
memcpy_s(ptr, sizePerThreadDataForWholeGroup, memcpy_s(ptr, sizePerThreadDataForWholeGroup,
dispatchInterface->getPerThreadData(), sizePerThreadDataForWholeGroup); dispatchInterface->getPerThreadData(), sizePerThreadDataForWholeGroup);

View File

@@ -5344,4 +5344,61 @@ typedef struct tagASYNC_SLICE_COUNT_SELECT_REGISTER {
} ASYNC_SLICE_COUNT_SELECT_REGISTER; } ASYNC_SLICE_COUNT_SELECT_REGISTER;
STATIC_ASSERT(4 == sizeof(ASYNC_SLICE_COUNT_SELECT_REGISTER)); STATIC_ASSERT(4 == sizeof(ASYNC_SLICE_COUNT_SELECT_REGISTER));
typedef struct tagSAMPLER_BORDER_COLOR_STATE {
union tagTheStructure {
struct tagCommon {
// DWORD 0
float BorderColorRed;
// DWORD 1
float BorderColorGreen;
// DWORD 2
float BorderColorBlue;
// DWORD 3
float BorderColorAlpha;
} Common;
uint32_t RawData[4];
} TheStructure;
inline void init(void) {
memset(&TheStructure, 0, sizeof(TheStructure));
TheStructure.Common.BorderColorRed = 0.0;
TheStructure.Common.BorderColorGreen = 0.0;
TheStructure.Common.BorderColorBlue = 0.0;
TheStructure.Common.BorderColorAlpha = 0.0;
}
static tagSAMPLER_BORDER_COLOR_STATE sInit(void) {
SAMPLER_BORDER_COLOR_STATE state;
state.init();
return state;
}
inline uint32_t &getRawData(const uint32_t index) {
UNRECOVERABLE_IF(index >= 4);
return TheStructure.RawData[index];
}
inline void setBorderColorRed(const float value) {
TheStructure.Common.BorderColorRed = value;
}
inline float getBorderColorRed(void) const {
return TheStructure.Common.BorderColorRed;
}
inline void setBorderColorGreen(const float value) {
TheStructure.Common.BorderColorGreen = value;
}
inline float getBorderColorGreen(void) const {
return TheStructure.Common.BorderColorGreen;
}
inline void setBorderColorBlue(const float value) {
TheStructure.Common.BorderColorBlue = value;
}
inline float getBorderColorBlue(void) const {
return TheStructure.Common.BorderColorBlue;
}
inline void setBorderColorAlpha(const float value) {
TheStructure.Common.BorderColorAlpha = value;
}
inline float getBorderColorAlpha(void) const {
return TheStructure.Common.BorderColorAlpha;
}
} SAMPLER_BORDER_COLOR_STATE;
STATIC_ASSERT(16 == sizeof(SAMPLER_BORDER_COLOR_STATE));
#pragma pack() #pragma pack()

View File

@@ -6003,4 +6003,61 @@ typedef struct tagXY_FAST_COLOR_BLT {
} XY_FAST_COLOR_BLT; } XY_FAST_COLOR_BLT;
STATIC_ASSERT(48 == sizeof(XY_FAST_COLOR_BLT)); STATIC_ASSERT(48 == sizeof(XY_FAST_COLOR_BLT));
typedef struct tagSAMPLER_BORDER_COLOR_STATE {
union tagTheStructure {
struct tagCommon {
// DWORD 0
float BorderColorRed;
// DWORD 1
float BorderColorGreen;
// DWORD 2
float BorderColorBlue;
// DWORD 3
float BorderColorAlpha;
} Common;
uint32_t RawData[4];
} TheStructure;
inline void init(void) {
memset(&TheStructure, 0, sizeof(TheStructure));
TheStructure.Common.BorderColorRed = 0.0;
TheStructure.Common.BorderColorGreen = 0.0;
TheStructure.Common.BorderColorBlue = 0.0;
TheStructure.Common.BorderColorAlpha = 0.0;
}
static tagSAMPLER_BORDER_COLOR_STATE sInit(void) {
SAMPLER_BORDER_COLOR_STATE state;
state.init();
return state;
}
inline uint32_t &getRawData(const uint32_t index) {
UNRECOVERABLE_IF(index >= 4);
return TheStructure.RawData[index];
}
inline void setBorderColorRed(const float value) {
TheStructure.Common.BorderColorRed = value;
}
inline float getBorderColorRed(void) const {
return TheStructure.Common.BorderColorRed;
}
inline void setBorderColorGreen(const float value) {
TheStructure.Common.BorderColorGreen = value;
}
inline float getBorderColorGreen(void) const {
return TheStructure.Common.BorderColorGreen;
}
inline void setBorderColorBlue(const float value) {
TheStructure.Common.BorderColorBlue = value;
}
inline float getBorderColorBlue(void) const {
return TheStructure.Common.BorderColorBlue;
}
inline void setBorderColorAlpha(const float value) {
TheStructure.Common.BorderColorAlpha = value;
}
inline float getBorderColorAlpha(void) const {
return TheStructure.Common.BorderColorAlpha;
}
} SAMPLER_BORDER_COLOR_STATE;
STATIC_ASSERT(16 == sizeof(SAMPLER_BORDER_COLOR_STATE));
#pragma pack() #pragma pack()

View File

@@ -4881,4 +4881,61 @@ typedef struct tagGPGPU_CSR_BASE_ADDRESS {
} GPGPU_CSR_BASE_ADDRESS; } GPGPU_CSR_BASE_ADDRESS;
STATIC_ASSERT(12 == sizeof(GPGPU_CSR_BASE_ADDRESS)); STATIC_ASSERT(12 == sizeof(GPGPU_CSR_BASE_ADDRESS));
typedef struct tagSAMPLER_BORDER_COLOR_STATE {
union tagTheStructure {
struct tagCommon {
// DWORD 0
float BorderColorRed;
// DWORD 1
float BorderColorGreen;
// DWORD 2
float BorderColorBlue;
// DWORD 3
float BorderColorAlpha;
} Common;
uint32_t RawData[4];
} TheStructure;
inline void init(void) {
memset(&TheStructure, 0, sizeof(TheStructure));
TheStructure.Common.BorderColorRed = 0.0;
TheStructure.Common.BorderColorGreen = 0.0;
TheStructure.Common.BorderColorBlue = 0.0;
TheStructure.Common.BorderColorAlpha = 0.0;
}
static tagSAMPLER_BORDER_COLOR_STATE sInit(void) {
SAMPLER_BORDER_COLOR_STATE state;
state.init();
return state;
}
inline uint32_t &getRawData(const uint32_t index) {
UNRECOVERABLE_IF(index >= 4);
return TheStructure.RawData[index];
}
inline void setBorderColorRed(const float value) {
TheStructure.Common.BorderColorRed = value;
}
inline float getBorderColorRed(void) const {
return TheStructure.Common.BorderColorRed;
}
inline void setBorderColorGreen(const float value) {
TheStructure.Common.BorderColorGreen = value;
}
inline float getBorderColorGreen(void) const {
return TheStructure.Common.BorderColorGreen;
}
inline void setBorderColorBlue(const float value) {
TheStructure.Common.BorderColorBlue = value;
}
inline float getBorderColorBlue(void) const {
return TheStructure.Common.BorderColorBlue;
}
inline void setBorderColorAlpha(const float value) {
TheStructure.Common.BorderColorAlpha = value;
}
inline float getBorderColorAlpha(void) const {
return TheStructure.Common.BorderColorAlpha;
}
} SAMPLER_BORDER_COLOR_STATE;
STATIC_ASSERT(16 == sizeof(SAMPLER_BORDER_COLOR_STATE));
#pragma pack() #pragma pack()

View File

@@ -5038,4 +5038,61 @@ typedef struct tagMI_STORE_DATA_IMM {
} MI_STORE_DATA_IMM; } MI_STORE_DATA_IMM;
STATIC_ASSERT(20 == sizeof(MI_STORE_DATA_IMM)); STATIC_ASSERT(20 == sizeof(MI_STORE_DATA_IMM));
typedef struct tagSAMPLER_BORDER_COLOR_STATE {
union tagTheStructure {
struct tagCommon {
// DWORD 0
float BorderColorRed;
// DWORD 1
float BorderColorGreen;
// DWORD 2
float BorderColorBlue;
// DWORD 3
float BorderColorAlpha;
} Common;
uint32_t RawData[4];
} TheStructure;
inline void init(void) {
memset(&TheStructure, 0, sizeof(TheStructure));
TheStructure.Common.BorderColorRed = 0.0;
TheStructure.Common.BorderColorGreen = 0.0;
TheStructure.Common.BorderColorBlue = 0.0;
TheStructure.Common.BorderColorAlpha = 0.0;
}
static tagSAMPLER_BORDER_COLOR_STATE sInit(void) {
SAMPLER_BORDER_COLOR_STATE state;
state.init();
return state;
}
inline uint32_t &getRawData(const uint32_t index) {
UNRECOVERABLE_IF(index >= 4);
return TheStructure.RawData[index];
}
inline void setBorderColorRed(const float value) {
TheStructure.Common.BorderColorRed = value;
}
inline float getBorderColorRed(void) const {
return TheStructure.Common.BorderColorRed;
}
inline void setBorderColorGreen(const float value) {
TheStructure.Common.BorderColorGreen = value;
}
inline float getBorderColorGreen(void) const {
return TheStructure.Common.BorderColorGreen;
}
inline void setBorderColorBlue(const float value) {
TheStructure.Common.BorderColorBlue = value;
}
inline float getBorderColorBlue(void) const {
return TheStructure.Common.BorderColorBlue;
}
inline void setBorderColorAlpha(const float value) {
TheStructure.Common.BorderColorAlpha = value;
}
inline float getBorderColorAlpha(void) const {
return TheStructure.Common.BorderColorAlpha;
}
} SAMPLER_BORDER_COLOR_STATE;
STATIC_ASSERT(16 == sizeof(SAMPLER_BORDER_COLOR_STATE));
#pragma pack() #pragma pack()

View File

@@ -14,6 +14,7 @@
namespace NEO { namespace NEO {
constexpr size_t globalSshAllocationSize = 4 * MemoryConstants::pageSize64k; constexpr size_t globalSshAllocationSize = 4 * MemoryConstants::pageSize64k;
constexpr size_t borderColorAlphaOffset = alignUp(4 * sizeof(float), MemoryConstants::cacheLineSize);
using BindlesHeapType = BindlessHeapsHelper::BindlesHeapType; using BindlesHeapType = BindlessHeapsHelper::BindlesHeapType;
BindlessHeapsHelper::BindlessHeapsHelper(MemoryManager *memManager, bool isMultiOsContextCapable, const uint32_t rootDeviceIndex) : memManager(memManager), isMultiOsContextCapable(isMultiOsContextCapable), rootDeviceIndex(rootDeviceIndex) { BindlessHeapsHelper::BindlessHeapsHelper(MemoryManager *memManager, bool isMultiOsContextCapable, const uint32_t rootDeviceIndex) : memManager(memManager), isMultiOsContextCapable(isMultiOsContextCapable), rootDeviceIndex(rootDeviceIndex) {
@@ -30,7 +31,7 @@ BindlessHeapsHelper::BindlessHeapsHelper(MemoryManager *memManager, bool isMulti
float borderColorDefault[4] = {0, 0, 0, 0}; float borderColorDefault[4] = {0, 0, 0, 0};
memcpy_s(borderColorStates->getUnderlyingBuffer(), sizeof(borderColorDefault), borderColorDefault, sizeof(borderColorDefault)); memcpy_s(borderColorStates->getUnderlyingBuffer(), sizeof(borderColorDefault), borderColorDefault, sizeof(borderColorDefault));
float borderColorAlpha[4] = {0, 0, 0, 1.0}; float borderColorAlpha[4] = {0, 0, 0, 1.0};
memcpy_s(ptrOffset(borderColorStates->getUnderlyingBuffer(), sizeof(borderColorDefault)), sizeof(borderColorAlpha), borderColorAlpha, sizeof(borderColorAlpha)); memcpy_s(ptrOffset(borderColorStates->getUnderlyingBuffer(), borderColorAlphaOffset), sizeof(borderColorAlpha), borderColorAlpha, sizeof(borderColorDefault));
} }
BindlessHeapsHelper::~BindlessHeapsHelper() { BindlessHeapsHelper::~BindlessHeapsHelper() {
@@ -87,7 +88,11 @@ uint32_t BindlessHeapsHelper::getDefaultBorderColorOffset() {
return static_cast<uint32_t>(borderColorStates->getGpuAddress() - borderColorStates->getGpuBaseAddress()); return static_cast<uint32_t>(borderColorStates->getGpuAddress() - borderColorStates->getGpuBaseAddress());
} }
uint32_t BindlessHeapsHelper::getAlphaBorderColorOffset() { uint32_t BindlessHeapsHelper::getAlphaBorderColorOffset() {
return getDefaultBorderColorOffset() + 4 * sizeof(float); return getDefaultBorderColorOffset() + borderColorAlphaOffset;
}
IndirectHeap *BindlessHeapsHelper::getHeap(BindlesHeapType heapType) {
return surfaceStateHeaps[heapType].get();
} }
void BindlessHeapsHelper::growHeap(BindlesHeapType heapType) { void BindlessHeapsHelper::growHeap(BindlesHeapType heapType) {

View File

@@ -45,6 +45,7 @@ class BindlessHeapsHelper {
void *getSpaceInHeap(size_t ssSize, BindlesHeapType heapType); void *getSpaceInHeap(size_t ssSize, BindlesHeapType heapType);
uint32_t getDefaultBorderColorOffset(); uint32_t getDefaultBorderColorOffset();
uint32_t getAlphaBorderColorOffset(); uint32_t getAlphaBorderColorOffset();
IndirectHeap *getHeap(BindlesHeapType heapType);
protected: protected:
void growHeap(BindlesHeapType heapType); void growHeap(BindlesHeapType heapType);

View File

@@ -14,6 +14,7 @@
#include "shared/test/unit_test/cmd_parse/gen_cmd_parse.h" #include "shared/test/unit_test/cmd_parse/gen_cmd_parse.h"
#include "shared/test/unit_test/device_binary_format/patchtokens_tests.h" #include "shared/test/unit_test/device_binary_format/patchtokens_tests.h"
#include "shared/test/unit_test/fixtures/command_container_fixture.h" #include "shared/test/unit_test/fixtures/command_container_fixture.h"
#include "shared/test/unit_test/fixtures/front_window_fixture.h"
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h" #include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
#include "shared/test/unit_test/mocks/mock_device.h" #include "shared/test/unit_test/mocks/mock_device.h"
#include "shared/test/unit_test/mocks/mock_dispatch_kernel_encoder_interface.h" #include "shared/test/unit_test/mocks/mock_dispatch_kernel_encoder_interface.h"
@@ -691,123 +692,60 @@ HWCMDTEST_F(IGFX_GEN8_CORE, CommandEncodeStatesTest, giveNextIddInBlockZeorWhenD
using EncodeDispatchKernelTest = Test<CommandEncodeStatesFixture>; using EncodeDispatchKernelTest = Test<CommandEncodeStatesFixture>;
HWTEST_F(EncodeDispatchKernelTest, givenBindlessBufferArgWhenDispatchingKernelThenSurfaceStateOffsetInCrossThreadDataIsProgrammed) { using Platforms = IsAtLeastProduct<IGFX_SKYLAKE>;
HWTEST2_F(EncodeDispatchKernelTest, givenBindfulKernelWhenDispatchingKernelThenSshFromContainerIsUsed, Platforms) {
using BINDING_TABLE_STATE = typename FamilyType::BINDING_TABLE_STATE; using BINDING_TABLE_STATE = typename FamilyType::BINDING_TABLE_STATE;
using DataPortBindlessSurfaceExtendedMessageDescriptor = typename FamilyType::DataPortBindlessSurfaceExtendedMessageDescriptor; using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
using WALKER = typename FamilyType::WALKER_TYPE;
uint32_t numBindingTable = 1; uint32_t numBindingTable = 1;
BINDING_TABLE_STATE bindingTableState; BINDING_TABLE_STATE bindingTableState;
bindingTableState.sInit(); bindingTableState.sInit();
auto ssh = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
auto ioh = cmdContainer->getIndirectHeap(HeapType::INDIRECT_OBJECT);
size_t sizeUsed = 0x20;
ssh->getSpace(sizeUsed);
sizeUsed = ssh->getUsed();
uint32_t dims[] = {1, 1, 1}; uint32_t dims[] = {1, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder()); std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
std::vector<uint8_t> storage;
NEO::PatchTokenBinary::KernelFromPatchtokens kernelTokens = PatchTokensTestData::ValidEmptyKernel::create(storage);
kernelTokens.tokens.kernelArgs.resize(1);
kernelTokens.tokens.kernelArgs[0].objectType = NEO::PatchTokenBinary::ArgObjectType::Buffer;
const uint32_t iohOffset = dispatchInterface->getCrossThreadDataSize() + 4;
const uint32_t surfaceStateOffset = 128;
iOpenCL::SPatchStatelessGlobalMemoryObjectKernelArgument globalMemArg = {};
globalMemArg.Token = iOpenCL::PATCH_TOKEN_STATELESS_GLOBAL_MEMORY_OBJECT_KERNEL_ARGUMENT;
globalMemArg.ArgumentNumber = 0;
globalMemArg.DataParamOffset = iohOffset;
globalMemArg.DataParamSize = 4;
globalMemArg.SurfaceStateHeapOffset = surfaceStateOffset;
auto surfaceStateOffsetOnHeap = static_cast<uint32_t>(alignUp(sizeUsed, BINDING_TABLE_STATE::SURFACESTATEPOINTER_ALIGN_SIZE)) + surfaceStateOffset;
auto patchLocation = reinterpret_cast<uint32_t *>(ptrOffset(ioh->getCpuBase(), iohOffset));
*patchLocation = 0xdead;
kernelTokens.tokens.kernelArgs[0].objectArg = &globalMemArg;
NEO::populateKernelDescriptor(dispatchInterface->kernelDescriptor, kernelTokens, sizeof(void *));
dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.numEntries = numBindingTable; dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.numEntries = numBindingTable;
dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.tableOffset = 0U; dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.tableOffset = 0U;
dispatchInterface->kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::BindfulAndStateless;
auto &arg = dispatchInterface->kernelDescriptor.payloadMappings.explicitArgs[0].as<NEO::ArgDescPointer>();
arg.bindless = iohOffset;
arg.bindful = surfaceStateOffset;
const uint8_t *sshData = reinterpret_cast<uint8_t *>(&bindingTableState); const uint8_t *sshData = reinterpret_cast<uint8_t *>(&bindingTableState);
EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapData()).WillRepeatedly(::testing::Return(sshData)); EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapData()).WillRepeatedly(::testing::Return(sshData));
EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapDataSize()).WillRepeatedly(::testing::Return(static_cast<uint32_t>(sizeof(BINDING_TABLE_STATE)))); EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapDataSize()).WillRepeatedly(::testing::Return(static_cast<uint32_t>(sizeof(BINDING_TABLE_STATE))));
auto usedBefore = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE)->getUsed();
bool requiresUncachedMocs = false; bool requiresUncachedMocs = false;
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled, requiresUncachedMocs); EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled, requiresUncachedMocs);
auto usedAfter = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE)->getUsed();
DataPortBindlessSurfaceExtendedMessageDescriptor extMessageDesc; EXPECT_NE(usedAfter, usedBefore);
extMessageDesc.setBindlessSurfaceOffset(surfaceStateOffsetOnHeap);
auto expectedOffset = extMessageDesc.getBindlessSurfaceOffsetToPatch();
EXPECT_EQ(expectedOffset, *patchLocation);
} }
HWTEST_F(EncodeDispatchKernelTest, givenBindlessImageArgWhenDispatchingKernelThenSurfaceStateOffsetInCrossThreadDataIsProgrammed) { HWTEST2_F(EncodeDispatchKernelTest, givenBindlessKernelWhenDispatchingKernelThenThenSshFromContainerIsNotUsed, Platforms) {
using BINDING_TABLE_STATE = typename FamilyType::BINDING_TABLE_STATE; using BINDING_TABLE_STATE = typename FamilyType::BINDING_TABLE_STATE;
using DataPortBindlessSurfaceExtendedMessageDescriptor = typename FamilyType::DataPortBindlessSurfaceExtendedMessageDescriptor; using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
using WALKER = typename FamilyType::WALKER_TYPE;
uint32_t numBindingTable = 1; uint32_t numBindingTable = 1;
BINDING_TABLE_STATE bindingTableState; BINDING_TABLE_STATE bindingTableState;
bindingTableState.sInit(); bindingTableState.sInit();
auto ssh = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
auto ioh = cmdContainer->getIndirectHeap(HeapType::INDIRECT_OBJECT);
size_t sizeUsed = 0x20;
ssh->getSpace(sizeUsed);
sizeUsed = ssh->getUsed();
uint32_t dims[] = {1, 1, 1}; uint32_t dims[] = {1, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder()); std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
std::vector<uint8_t> storage;
NEO::PatchTokenBinary::KernelFromPatchtokens kernelTokens = PatchTokensTestData::ValidEmptyKernel::create(storage);
kernelTokens.tokens.kernelArgs.resize(1);
kernelTokens.tokens.kernelArgs[0].objectType = NEO::PatchTokenBinary::ArgObjectType::Image;
const uint32_t iohOffset = dispatchInterface->getCrossThreadDataSize() + 4;
const uint32_t surfaceStateOffset = 128;
iOpenCL::SPatchImageMemoryObjectKernelArgument imageArg = {};
imageArg.Token = iOpenCL::PATCH_TOKEN_IMAGE_MEMORY_OBJECT_KERNEL_ARGUMENT;
imageArg.ArgumentNumber = 0;
imageArg.Offset = surfaceStateOffset;
auto surfaceStateOffsetOnHeap = static_cast<uint32_t>(alignUp(sizeUsed, BINDING_TABLE_STATE::SURFACESTATEPOINTER_ALIGN_SIZE)) + surfaceStateOffset;
auto patchLocation = reinterpret_cast<uint32_t *>(ptrOffset(ioh->getCpuBase(), iohOffset));
*patchLocation = 0xdead;
kernelTokens.tokens.kernelArgs[0].objectArg = &imageArg;
NEO::populateKernelDescriptor(dispatchInterface->kernelDescriptor, kernelTokens, sizeof(void *));
dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.numEntries = numBindingTable; dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.numEntries = numBindingTable;
dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.tableOffset = 0U; dispatchInterface->kernelDescriptor.payloadMappings.bindingTable.tableOffset = 0U;
dispatchInterface->kernelDescriptor.kernelAttributes.bufferAddressingMode = KernelDescriptor::BindlessAndStateless;
auto &arg = dispatchInterface->kernelDescriptor.payloadMappings.explicitArgs[0].as<NEO::ArgDescImage>();
arg.bindless = iohOffset;
arg.bindful = surfaceStateOffset;
const uint8_t *sshData = reinterpret_cast<uint8_t *>(&bindingTableState); const uint8_t *sshData = reinterpret_cast<uint8_t *>(&bindingTableState);
EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapData()).WillRepeatedly(::testing::Return(sshData)); EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapData()).WillRepeatedly(::testing::Return(sshData));
EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapDataSize()).WillRepeatedly(::testing::Return(static_cast<uint32_t>(sizeof(BINDING_TABLE_STATE)))); EXPECT_CALL(*dispatchInterface.get(), getSurfaceStateHeapDataSize()).WillRepeatedly(::testing::Return(static_cast<uint32_t>(sizeof(BINDING_TABLE_STATE))));
bool requiresUncachedMocs = false; bool requiresUncachedMocs = false;
auto usedBefore = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE)->getUsed();
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled, requiresUncachedMocs); EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled, requiresUncachedMocs);
auto usedAfter = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE)->getUsed();
DataPortBindlessSurfaceExtendedMessageDescriptor extMessageDesc; EXPECT_EQ(usedAfter, usedBefore);
extMessageDesc.setBindlessSurfaceOffset(surfaceStateOffsetOnHeap);
auto expectedOffset = extMessageDesc.getBindlessSurfaceOffsetToPatch();
EXPECT_EQ(expectedOffset, *patchLocation);
} }
HWTEST_F(EncodeDispatchKernelTest, givenNonBindlessOrStatelessArgWhenDispatchingKernelThenSurfaceStateOffsetInCrossThreadDataIsNotPatched) { HWTEST_F(EncodeDispatchKernelTest, givenNonBindlessOrStatelessArgWhenDispatchingKernelThenSurfaceStateOffsetInCrossThreadDataIsNotPatched) {
@@ -1082,3 +1020,57 @@ HWCMDTEST_F(IGFX_GEN8_CORE, InterfaceDescriptorDataTests, givenVariousValuesWhen
EncodeDispatchKernel<FamilyType>::programBarrierEnable(idd, 2, hwInfo); EncodeDispatchKernel<FamilyType>::programBarrierEnable(idd, 2, hwInfo);
EXPECT_TRUE(idd.getBarrierEnable()); EXPECT_TRUE(idd.getBarrierEnable());
} }
using BindlessCommandEncodeStatesTest = Test<MemManagerFixture>;
HWTEST_F(BindlessCommandEncodeStatesTest, givenGlobalBindlessHeapsWhenDispatchingKernelWithSamplerThenGlobalDshInResidnecyContainer) {
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
auto cmdContainer = std::make_unique<CommandContainer>();
cmdContainer->initialize(pDevice);
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
uint32_t numSamplers = 1;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
dispatchInterface->kernelDescriptor.payloadMappings.samplerTable.numSamplers = numSamplers;
dispatchInterface->kernelDescriptor.payloadMappings.samplerTable.tableOffset = 0U;
dispatchInterface->kernelDescriptor.payloadMappings.samplerTable.borderColor = 0U;
const uint8_t *dshData = reinterpret_cast<uint8_t *>(&samplerState);
EXPECT_CALL(*dispatchInterface.get(), getDynamicStateHeapData()).WillRepeatedly(::testing::Return(dshData));
bool requiresUncachedMocs = false;
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled, requiresUncachedMocs);
EXPECT_NE(std::find(cmdContainer->getResidencyContainer().begin(), cmdContainer->getResidencyContainer().end(), pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::GLOBAL_DSH)->getGraphicsAllocation()), cmdContainer->getResidencyContainer().end());
}
HWTEST_F(BindlessCommandEncodeStatesTest, givenBindlessModeDisabledelWithSamplerThenGlobalDshIsNotResidnecyContainer) {
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(0);
auto cmdContainer = std::make_unique<CommandContainer>();
cmdContainer->initialize(pDevice);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
using INTERFACE_DESCRIPTOR_DATA = typename FamilyType::INTERFACE_DESCRIPTOR_DATA;
uint32_t numSamplers = 1;
SAMPLER_STATE samplerState;
memset(&samplerState, 2, sizeof(SAMPLER_STATE));
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t dims[] = {2, 1, 1};
std::unique_ptr<MockDispatchKernelEncoder> dispatchInterface(new MockDispatchKernelEncoder());
dispatchInterface->kernelDescriptor.payloadMappings.samplerTable.numSamplers = numSamplers;
dispatchInterface->kernelDescriptor.payloadMappings.samplerTable.tableOffset = 0U;
dispatchInterface->kernelDescriptor.payloadMappings.samplerTable.borderColor = 0U;
const uint8_t *dshData = reinterpret_cast<uint8_t *>(&samplerState);
EXPECT_CALL(*dispatchInterface.get(), getDynamicStateHeapData()).WillRepeatedly(::testing::Return(dshData));
bool requiresUncachedMocs = false;
EncodeDispatchKernel<FamilyType>::encode(*cmdContainer.get(), dims, false, false, dispatchInterface.get(), 0, pDevice, NEO::PreemptionMode::Disabled, requiresUncachedMocs);
EXPECT_EQ(std::find(cmdContainer->getResidencyContainer().begin(), cmdContainer->getResidencyContainer().end(), pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::GLOBAL_DSH)->getGraphicsAllocation()), cmdContainer->getResidencyContainer().end());
}

View File

@@ -7,25 +7,132 @@
#include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/hw_helper.h"
#include "shared/source/helpers/ptr_math.h" #include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/string.h"
#include "shared/test/unit_test/cmd_parse/gen_cmd_parse.h" #include "shared/test/unit_test/cmd_parse/gen_cmd_parse.h"
#include "shared/test/unit_test/fixtures/command_container_fixture.h" #include "shared/test/unit_test/fixtures/command_container_fixture.h"
#include "shared/test/unit_test/fixtures/front_window_fixture.h"
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
using namespace NEO; using namespace NEO;
using CommandEncodeStatesTest = Test<CommandEncodeStatesFixture>; using CommandEncodeStatesTest = Test<CommandEncodeStatesFixture>;
HWTEST_F(CommandEncodeStatesTest, encodeCopySamplerState) { HWTEST_F(CommandEncodeStatesTest, GivenCommandStreamWhenEncodeCopySamplerStateThenIndirectStatePointerIsCorrect) {
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE; using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1; uint32_t numSamplers = 1;
SAMPLER_STATE samplerState; SAMPLER_STATE samplerState;
auto dsh = cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE); auto dsh = cmdContainer->getIndirectHeap(HeapType::DYNAMIC_STATE);
auto usedBefore = dsh->getUsed(); auto usedBefore = dsh->getUsed();
auto samplerStateOffset = EncodeStates<FamilyType>::copySamplerState(dsh, 0, numSamplers, 0, &samplerState); auto samplerStateOffset = EncodeStates<FamilyType>::copySamplerState(dsh, 0, numSamplers, 0, &samplerState, nullptr);
auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(ptrOffset(dsh->getCpuBase(), samplerStateOffset)); auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(ptrOffset(dsh->getCpuBase(), samplerStateOffset));
EXPECT_EQ(pSmplr->getIndirectStatePointer(), usedBefore); EXPECT_EQ(pSmplr->getIndirectStatePointer(), usedBefore);
} }
using BindlessCommandEncodeStatesTest = Test<MemManagerFixture>;
HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorWithoutAlphaThenBorderColorPtrReturned) {
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t borderColorSize = 0x40;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
EncodeStates<FamilyType>::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper());
auto expectedValue = pDevice->getBindlessHeapsHelper()->getDefaultBorderColorOffset();
auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(dsh->getGraphicsAllocation()->getUnderlyingBuffer());
EXPECT_EQ(pSmplr->getIndirectStatePointer(), expectedValue);
}
HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorWithAlphaThenBorderColorPtrOffseted) {
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t borderColorSize = 0x40;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
samplerState.setBorderColorAlpha(1.0);
auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
EncodeStates<FamilyType>::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper());
auto expectedValue = pDevice->getBindlessHeapsHelper()->getAlphaBorderColorOffset();
auto pSmplr = reinterpret_cast<SAMPLER_STATE *>(dsh->getGraphicsAllocation()->getUnderlyingBuffer());
EXPECT_EQ(pSmplr->getIndirectStatePointer(), expectedValue);
}
HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsRedChanelIsNotZeroThenExceptionThrown) {
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t borderColorSize = 0x40;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
samplerState.setBorderColorRed(0.5);
auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
EXPECT_THROW(EncodeStates<FamilyType>::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception);
}
HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsGreenChanelIsNotZeroThenExceptionThrown) {
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t borderColorSize = 0x40;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
samplerState.setBorderColorGreen(0.5);
auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
EXPECT_THROW(EncodeStates<FamilyType>::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception);
}
HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsBlueChanelIsNotZeroThenExceptionThrown) {
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t borderColorSize = 0x40;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
samplerState.setBorderColorBlue(0.5);
auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
EXPECT_THROW(EncodeStates<FamilyType>::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception);
}
HWTEST_F(BindlessCommandEncodeStatesTest, GivenBindlessEnabledWhenBorderColorsAlphaChanelIsNotZeroOrOneThenExceptionThrown) {
using SAMPLER_BORDER_COLOR_STATE = typename FamilyType::SAMPLER_BORDER_COLOR_STATE;
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
using SAMPLER_STATE = typename FamilyType::SAMPLER_STATE;
uint32_t numSamplers = 1;
pDevice->bindlessHeapHelper.reset(new NEO::BindlessHeapsHelper(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()));
uint32_t borderColorSize = 0x40;
SAMPLER_BORDER_COLOR_STATE samplerState;
samplerState.init();
samplerState.setBorderColorAlpha(0.5);
auto dsh = pDevice->getBindlessHeapsHelper()->getHeap(BindlessHeapsHelper::BindlesHeapType::GLOBAL_DSH);
EXPECT_THROW(EncodeStates<FamilyType>::copySamplerState(dsh, borderColorSize, numSamplers, 0, &samplerState, pDevice->getBindlessHeapsHelper()), std::exception);
}
HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenAllocationProvidedThenUseAllocationAsInput) { HWTEST_F(CommandEncodeStatesTest, givenCreatedSurfaceStateBufferWhenAllocationProvidedThenUseAllocationAsInput) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;

View File

@@ -140,8 +140,9 @@ TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenGetDefaultBorderColo
} }
TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenGetAlphaBorderColorOffsetCalledThenCorrectOffsetReturned) { TEST_F(BindlessHeapsHelperTests, givenBindlessHepaHelperWhenGetAlphaBorderColorOffsetCalledThenCorrectOffsetReturned) {
auto borderColorSize = 0x40;
auto bindlessHeapHelper = std::make_unique<MockBindlesHeapsHelper>(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex()); auto bindlessHeapHelper = std::make_unique<MockBindlesHeapsHelper>(pDevice->getMemoryManager(), pDevice->getNumAvailableDevices() > 1, pDevice->getRootDeviceIndex());
auto expectedOffset = bindlessHeapHelper->borderColorStates->getGpuAddress() - bindlessHeapHelper->borderColorStates->getGpuBaseAddress() + 4 * sizeof(float); auto expectedOffset = bindlessHeapHelper->borderColorStates->getGpuAddress() - bindlessHeapHelper->borderColorStates->getGpuBaseAddress() + borderColorSize;
EXPECT_EQ(bindlessHeapHelper->getAlphaBorderColorOffset(), expectedOffset); EXPECT_EQ(bindlessHeapHelper->getAlphaBorderColorOffset(), expectedOffset);
} }