Fichiers
rocm-systems/rocclr/runtime/device/gpu/gslbe/src/rt/GSLDevice.cpp
T
foreman 4da269fbb6 P4 to Git Change 1201301 by skudchad@skudchad_test_win_opencl2 on 2015/10/19 19:19:44
SWDEV-77172 - IOMMUv2 changes for Windows 10
	- Pass the GPUVM offset to MonitoredFence GPUVA as well
	- Other minor changes for SVM

	ReviewBoardURL = http://ocltc.amd.com/reviews/r/8729/diff/

Affected files ...

... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gslbe/src/rt/GSLDevice.cpp#148 edit
2015-10-19 19:29:07 -04:00

1373 lignes
44 KiB
C++

#include "gsl_ctx.h"
#include "GSLDevice.h"
#include "EventQueue.h"
#include "ini_export.h"
#include "GSLContext.h"
#include "cm_if.h"
#include "utils/flags.hpp"
#include "query/QueryObject.h"
#include "memory/MemObject.h"
#include "sampler/SamplerObject.h"
#include "texture/TextureResourceObject.h"
extern gslMemObjectAttribTiling g_CALBETiling_Tiled;
void
CALGSLDevice::resFree(gslMemObject mem) const
{
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
m_cs->destroyMemObject(mem);
}
void CALGSLDevice::Initialize()
{
m_adp = 0;
m_cs = 0;
m_rs = 0;
m_textureResource = 0;
m_textureSampler = 0;
m_target = (CALtarget)0xffffffff;
m_srcDRMDMAMem = NULL ;
m_dstDRMDMAMem = NULL ;
m_nativeDisplayHandle = NULL;
m_deviceMode = GSL_DEVICE_MODE_GFX;
m_gpuIndex = 0;
m_usePerVPUAdapterModel = false;
m_chainIndex = 0;
m_vpuMask = 1;
m_PerformLazyDeviceInit = false;
m_computeRing = false;
m_isComputeRingIDForced = false;
m_forcedComputeEngineID = GSL_ENGINEID_INVALID;
gslDeviceOps_ = NULL;
}
CALGSLDevice::CALGSLDevice()
{
Initialize();
}
CALGSLDevice::~CALGSLDevice()
{
assert(m_adp == 0); /// CALBE client must call close explicitly. Check that here
delete gslDeviceOps_;
switch(m_deviceMode)
{
case GSL_DEVICE_MODE_NONE:
case GSL_DEVICE_MODE_CONSOLE:
delete static_cast<char*>(m_nativeDisplayHandle);
break;
case GSL_DEVICE_MODE_GFX:
break;
}
}
gsl::gsAdaptor*
CALGSLDevice::getNative() const
{
return m_adp;
}
uint32
CALGSLDevice::getMaxTextureSize() const
{
return static_cast<uint32>(m_maxtexturesize);
}
void
CALGSLDevice::getAttribs_int(gsl::gsCtx* cs)
{
m_attribs.struct_size = sizeof(CALdeviceattribs);
m_attribs.target = m_target;
gslMemInfo memInfo;
cs->getMemInfo(&memInfo, GSL_MEMINFO_BASIC);
m_attribs.localRAM = (uint32)((memInfo.cardMemTotalBytes + memInfo.cardExtMemTotalBytes) / (1024 * 1024));
m_attribs.uncachedRemoteRAM = (uint32)(memInfo.agpMemTotalBytes / (1024 * 1024));
m_attribs.cachedRemoteRAM = (uint32)(memInfo.agpMemTotalCacheableBytes / (1024 * 1024));
m_attribs.totalVisibleHeap = (uint32) (memInfo.cardMemTotalBytes / (1024 * 1024));
m_attribs.totalInvisibleHeap = (uint32) (memInfo.cardExtMemTotalBytes / (1024 * 1024));
m_attribs.totalDirectHeap = (uint32) (memInfo.directTotalBytes / (1024 * 1024));
m_attribs.totalCoherentHeap = (uint32) (memInfo.coherentTotalBytes / (1024 * 1024));
m_attribs.totalRemoteSharedHeap = (uint32) (memInfo.sharedTotalBytes / (1024 * 1024));
m_attribs.totalCachedRemoteSharedHeap = (uint32) (memInfo.sharedCacheableTotalBytes / (1024 * 1024));
m_attribs.totalSDIHeap = (uint32) (memInfo.busAddressableTotalBytes / (1024 * 1024));
m_attribs.engineClock = cs->getMaxEngineClock();
m_attribs.memoryClock = cs->getMaxMemoryClock();
m_attribs.numberOfSIMD = cs->getNumSIMD();
m_attribs.numberOfCUsperShaderArray = cs->getNumCUsPerShaderArray();
m_attribs.wavefrontSize = cs->getWaveFrontSize();
m_attribs.doublePrecision = cs->getIsDoublePrecisionSupported();
m_attribs.memBusWidth = cs->getVramBitWidth();
m_attribs.numMemBanks = cs->getVramBanks();
m_attribs.isWorkstation = cs->getIsWorkstation();
m_attribs.numberOfShaderEngines = cs->getNumShaderEngines();
m_attribs.pciTopologyInformation = m_adp->getLocationId();
const uint8* boardName = cs->getString(GSL_GS_RENDERER);
::strncpy(m_attribs.boardName, (char*)boardName, CAL_ASIC_INFO_MAX_LEN * sizeof(char));
m_attribs.counterFreq = cs->getCounterFreq();
m_attribs.nanoSecondsPerTick = 1000000000.0 / cs->getCounterFreq();
m_attribs.longIdleDetect = cs->getLongIdleDetect();
m_attribs.svmAtomics = m_adp->pAsicInfo->svmAtomics;
m_attribs.vaStart = static_cast<CALuint64>(m_adp->pAsicInfo->vaStart);
m_attribs.vaEnd = static_cast<CALuint64>(m_adp->pAsicInfo->vaEnd);
m_attribs.numOfVpu = m_adp->pAsicInfo->numberOfVPU;
m_attribs.isOpenCL200Device = m_adp->pAsicInfo->bIsOpen2Device;
m_attribs.isSVMFineGrainSystem = m_adp->pAsicInfo->svmFineGrainSystem;
m_attribs.isWDDM2Enabled = m_adp->pAsicInfo->vaAvailable && m_adp->pAsicInfo->bNoVATranslation;
}
bool
CALGSLDevice::open(uint32 gpuIndex, bool enableHighPerformanceState, bool reportAsOCL12Device)
{
gslDeviceOps_ = new amd::Monitor("GSL Device Ops Lock", true);
if (NULL == gslDeviceOps_) {
return false;
}
unsigned int chainIndex = 0;
#ifdef ATI_OS_WIN
m_gpuIndex = gpuIndex;
m_usePerVPUAdapterModel = true;
m_PerformLazyDeviceInit = true;
#else
void * nativeHandle;
gslDeviceMode deviceMode;
gsAdaptor::getDeviceInitData(gpuIndex, &deviceMode, &chainIndex, &nativeHandle);
m_nativeDisplayHandle = nativeHandle;
m_deviceMode = deviceMode;
#endif
m_chainIndex = chainIndex;
m_vpuMask = 1 << chainIndex;
//
// CALBE is required to explicitly manage multiple opens and closes
// assert on the condition for correct usage
//
assert(m_adp == 0);
memset(&m_dcfg, 0, sizeof(m_dcfg));
extern void getConfigFromFile(gslStaticRuntimeConfig &scfg, gslDynamicRuntimeConfig &dcfg);
getConfigFromFile(m_scfg, m_dcfg);
m_scfg.UsePerVPUAdapterModel.hasValue = true;
m_scfg.UsePerVPUAdapterModel.value = m_usePerVPUAdapterModel;
m_scfg.DX10SamplerResources.hasValue = true;
m_scfg.DX10SamplerResources.value = true;
m_scfg.vpuMask.hasValue = true;
m_scfg.vpuMask.value = m_vpuMask;
m_scfg.bEnableHighPerformanceState.hasValue = true;
m_scfg.bEnableHighPerformanceState.value = enableHighPerformanceState;
m_dcfg.disableMarkUsedInCmdBuf.hasValue = true;
m_dcfg.disableMarkUsedInCmdBuf.value = false;
// Enable immediate memory release
m_dcfg.immediateMemoryRelease.hasValue = true;
m_dcfg.immediateMemoryRelease.value = true;
m_dcfg.bEnableSvm.hasValue = true;
m_dcfg.bEnableSvm.value = reportAsOCL12Device ? false : OPENCL_MAJOR >= 2;
m_dcfg.bEnableFlatAddressing.hasValue = true;
#if defined(ATI_BITS_32) && defined(ATI_OS_LINUX)
m_dcfg.bEnableFlatAddressing.value = false;
#else
m_dcfg.bEnableFlatAddressing.value = reportAsOCL12Device ? false : (OPENCL_MAJOR >= 2);
#endif
//we can use environment variable CAL_ENABLE_ASYNC_DMA to force dma on or off when we need it
char *s = NULL;
if((s = getenv("CAL_ENABLE_ASYNC_DMA")))
{
m_dcfg.drmdmaMode.hasValue = true;
m_dcfg.drmdmaMode.value = (atoi(s) == 0) ? GSL_CONFIG_DRMDMA_MODE_FORCE_OFF : GSL_CONFIG_DRMDMA_MODE_DEFAULT;
}
// Use GPU_USE_SYNC_OBJECTS to force syncobject on or off when we need it
m_dcfg.syncObjectMode.hasValue = true;
m_dcfg.syncObjectMode.value = (GPU_USE_SYNC_OBJECTS) ?
GSL_CONFIG_SYNCOBJECT_MODE_ON : GSL_CONFIG_SYNCOBJECT_MODE_OFF;
// Use GPU_IFH_MODE to test with IFH mode enabled
m_dcfg.DropFlush.hasValue = true;
m_dcfg.DropFlush.value = (GPU_IFH_MODE == 1);
// Enable TC compatible htile mode. It's HW feature for VI+ and controlled in HWL.
// Depth interop doesn't support TC compatible htile mode, but OCL needs correct tiling setup.
m_dcfg.bEnableTCCompatibleHtile.hasValue = true;
m_dcfg.bEnableTCCompatibleHtile.value = true;
int32 asic_id = 0;
if (!SetupAdapter(asic_id))
{
return false;
}
if (!SetupContext(asic_id))
{
return false;
}
if (m_PerformLazyDeviceInit)
{
// close the adaptor
gsAdaptor::closeAdaptor(m_adp);
m_adp = 0;
}
else
{
PerformFullInitialization();
}
return true;
}
void
CALGSLDevice::close()
{
if (m_cs != NULL)
{
m_cs->Flush();
}
if (m_dstDRMDMAMem)
{
resFree(m_dstDRMDMAMem);
m_dstDRMDMAMem = NULL ;
}
if (m_srcDRMDMAMem)
{
resFree(m_srcDRMDMAMem);
m_srcDRMDMAMem = NULL ;
}
if (m_cs != NULL)
{
m_cs->destroyTextureResource(m_textureResource);
m_cs->destroySampler(m_textureSampler);
m_cs->destroyQuery(m_mapQuery);
m_cs->destroyQuery(m_mapDMAQuery);
m_cs->setRenderState(0);
m_cs->destroyRenderState(m_rs);
m_cs->destroySubAllocDesc();
m_rs = 0;
m_adp->deleteContext(m_cs);
m_cs = 0;
}
if (m_adp != NULL)
{
gsAdaptor::closeAdaptor(m_adp);
m_adp = 0;
}
}
void
CALGSLDevice::PerformAdapterInitialization() const
{
CALGSLDevice* mutable_this = const_cast<CALGSLDevice*>(this);
mutable_this->PerformAdapterInitialization_int(false);
}
void
CALGSLDevice::PerformFullInitialization() const
{
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
CALGSLDevice* mutable_this = const_cast<CALGSLDevice*>(this);
mutable_this->PerformFullInitialization_int();
}
bool
CALGSLDevice::SetupAdapter(int32 &asic_id)
{
bool initLite = false;
#ifdef ATI_OS_WIN
if(osGetVersion() >= AMD_OS_VERSION_WINDOWS_10)
{
initLite = true;
}
#endif
PerformAdapterInitialization_int(initLite);
if (m_adp == 0)
{
return false;
}
asic_id = m_adp->getAsicID();
if ((asic_id < GSL_ATIASIC_ID_TAHITI_P) ||
(asic_id == GSL_ATIASIC_ID_DEVASTATOR) ||
(asic_id == GSL_ATIASIC_ID_SCRAPPER))
{
LogPrintfInfo("Unsupported legacy ASIC(%d) found!\n", asic_id);
// close the adaptor
gsAdaptor::closeAdaptor(m_adp);
m_adp = 0;
return false;
}
bool hasDmaEngine = m_adp->findDMAEngine();
bool hasComputeEngine = m_adp->findComputeEngine();
m_canDMA = hasDmaEngine;
m_adp->queryAvailableEngines(&m_nEngines, m_engines);
//Disable DRMDMA on CFX mode for linux on all GPUs.
#ifdef ATI_OS_LINUX
if ((m_adp->getNumLinkedVPUs() > 1) && !DRMDMA_FOR_LNX_CF)
{
m_canDMA = ATIGL_FALSE;
}
#endif
if (asic_id < GSL_ATIASIC_ID_TAHITI_P ||
asic_id == GSL_ATIASIC_ID_DEVASTATOR ||
asic_id == GSL_ATIASIC_ID_SCRAPPER)
{
m_computeRing = false;
}
else
{
m_computeRing = true;
}
if (!flagIsDefault(GPU_NUM_COMPUTE_RINGS))
{
m_computeRing = (GPU_NUM_COMPUTE_RINGS != 0);
}
if ((!flagIsDefault(GPU_SELECT_COMPUTE_RINGS_ID)) && (m_computeRing))
{
gslEngineID engineID;
engineID = static_cast<gslEngineID>(GPU_SELECT_COMPUTE_RINGS_ID + GSL_ENGINEID_COMPUTE0);
if ((engineID >= GSL_ENGINEID_COMPUTE0) && (engineID <= GSL_ENGINEID_COMPUTE7))
{
for (uint i = 0; i < m_nEngines; ++i) {
if (m_engines[i].id == engineID){
m_isComputeRingIDForced = true;
m_forcedComputeEngineID = engineID;
break;
}
}
}
}
if (m_computeRing && !hasComputeEngine)
{
return false;
}
return true;
}
bool
CALGSLDevice::SetupContext(int32 &asic_id)
{
bool initLite = false;
#ifdef ATI_OS_WIN
if(osGetVersion() >= AMD_OS_VERSION_WINDOWS_10)
{
initLite = true;
}
#endif
gsl::gsCtx* temp_cs = m_adp->createComputeContext(m_computeRing ? (m_isComputeRingIDForced ? m_forcedComputeEngineID :
getFirstAvailableComputeEngineID()) : GSL_ENGINEID_3DCOMPUTE0,
m_canDMA ? GSL_ENGINEID_DRMDMA0 : GSL_ENGINEID_INVALID, initLite);
temp_cs->getMainSubCtx()->setVPUMask(m_vpuMask);
m_maxtexturesize = temp_cs->getMaxTextureSize();
switch (asic_id)
{
case GSL_ATIASIC_ID_TAHITI_P:
m_target = CAL_TARGET_TAHITI;
m_elfmachine = ED_ATI_CAL_MACHINE_TAHITI_ISA;
break;
case GSL_ATIASIC_ID_PITCAIRN_PM:
m_target = CAL_TARGET_PITCAIRN;
m_elfmachine = ED_ATI_CAL_MACHINE_PITCAIRN_ISA;
break;
case GSL_ATIASIC_ID_CAPEVERDE_M:
m_target = CAL_TARGET_CAPEVERDE;
m_elfmachine = ED_ATI_CAL_MACHINE_CAPEVERDE_ISA;
break;
case GSL_ATIASIC_ID_OLAND_M:
m_target = CAL_TARGET_OLAND;
m_elfmachine = ED_ATI_CAL_MACHINE_OLAND_ISA;
break;
case GSL_ATIASIC_ID_HAINAN_M:
m_target = CAL_TARGET_HAINAN;
m_elfmachine = ED_ATI_CAL_MACHINE_HAINAN_ISA;
break;
case GSL_ATIASIC_ID_BONAIRE_M:
m_target = CAL_TARGET_BONAIRE;
m_elfmachine = ED_ATI_CAL_MACHINE_BONAIRE_ISA;
break;
case GSL_ATIASIC_ID_SPECTRE:
m_target = CAL_TARGET_SPECTRE;
m_elfmachine = ED_ATI_CAL_MACHINE_SPECTRE_ISA;
break;
case GSL_ATIASIC_ID_SPOOKY:
m_target = CAL_TARGET_SPOOKY;
m_elfmachine = ED_ATI_CAL_MACHINE_SPOOKY_ISA;
break;
case GSL_ATIASIC_ID_KALINDI:
m_target = CAL_TARGET_KALINDI;
m_elfmachine = ED_ATI_CAL_MACHINE_KALINDI_ISA;
break;
case GSL_ATIASIC_ID_HAWAII_P:
m_target = CAL_TARGET_HAWAII;
m_elfmachine = ED_ATI_CAL_MACHINE_HAWAII_ISA;
break;
case GSL_ATIASIC_ID_ICELAND_M:
m_target = CAL_TARGET_ICELAND;
m_elfmachine = ED_ATI_CAL_MACHINE_ICELAND_ISA;
break;
case GSL_ATIASIC_ID_TONGA_P:
m_target = CAL_TARGET_TONGA;
m_elfmachine = ED_ATI_CAL_MACHINE_TONGA_ISA;
break;
case GSL_ATIASIC_ID_GODAVARI:
m_target = CAL_TARGET_GODAVARI;
m_elfmachine = ED_ATI_CAL_MACHINE_GODAVARI_ISA;
break;
case GSL_ATIASIC_ID_FIJI_P:
m_target = CAL_TARGET_FIJI;
m_elfmachine = ED_ATI_CAL_MACHINE_FIJI_ISA;
break;
case GSL_ATIASIC_ID_CARRIZO:
m_target = CAL_TARGET_CARRIZO;
m_elfmachine = ED_ATI_CAL_MACHINE_CARRIZO_ISA;
break;
case GSL_ATIASIC_ID_ELLESMERE:
m_target = CAL_TARGET_ELLESMERE;
m_elfmachine = ED_ATI_CAL_MACHINE_ELLESMERE_ISA;
break;
case GSL_ATIASIC_ID_BAFFIN:
m_target = CAL_TARGET_BAFFIN;
m_elfmachine = ED_ATI_CAL_MACHINE_BAFFIN_ISA;
break;
case GSL_ATIASIC_ID_GREENLAND:
m_target = CAL_TARGET_GREENLAND;
m_elfmachine = ED_ATI_CAL_MACHINE_GREENLAND_ISA;
break;
case GSL_ATIASIC_ID_STONEY:
m_target = CAL_TARGET_STONEY;
m_elfmachine = ED_ATI_CAL_MACHINE_STONEY_ISA;
break;
default:
// 6XX is not supported
m_adp->deleteContext(temp_cs);
gsAdaptor::closeAdaptor(m_adp);
m_adp = 0;
assert(0);
return false;
}
//cache device details
getAttribs_int(temp_cs);
temp_cs->getMemInfo(&m_memInfo, GSL_MEMINFO_BASIC);
assert(temp_cs->getVMMode());
m_adp->deleteContext(temp_cs);
return true;
}
void
CALGSLDevice::PerformAdapterInitialization_int(bool initLite)
{
if (m_adp == 0)
{
if (m_usePerVPUAdapterModel)
{
m_adp = gsAdaptor::openAdaptorByIndex<gsl::gsAdaptor>(m_gpuIndex, &m_scfg, &m_dcfg, initLite);
}
else
{
m_adp = gsAdaptor::openAdaptor(m_nativeDisplayHandle, m_chainIndex, &m_scfg, &m_dcfg);
}
assert(m_adp != 0);
}
}
void
CALGSLDevice::PerformFullInitialization_int()
{
if (m_adp == 0)
{
PerformAdapterInitialization_int(false);
}
if (m_cs == 0)
{
m_cs = m_adp->createComputeContext(m_computeRing ? (m_isComputeRingIDForced ? m_forcedComputeEngineID :
getFirstAvailableComputeEngineID()) : GSL_ENGINEID_3DCOMPUTE0,
m_canDMA ? GSL_ENGINEID_DRMDMA0 : GSL_ENGINEID_INVALID, false);
m_cs->getMainSubCtx()->setVPUMask(m_vpuMask);
//
// Check if the command stream has a DMA connection and allow DMA if there
// is a connection and we can actually DMA
//
bool dmaConnection = m_cs->getDrmDma0Ctx() && m_cs->getDrmDma0Ctx()->ioInfo.iolConnection;
m_allowDMA = (dmaConnection && m_canDMA);
m_rs = m_cs->createRenderState();
m_cs->setRenderState(m_rs);
m_cs->Flush();
m_cs->createSubAllocDesc();
m_mapQuery = m_cs->createQuery(GSL_SYNC_ATI);
m_mapDMAQuery = m_cs->createQuery(GSL_DRMDMA_SYNC_ATI);
// Allocate 1x1 FART and Vid memory for DMA flush
CALresourceDesc desc;
memset(&desc, 0, sizeof(CALresourceDesc));
desc.type = GSL_MOA_MEMORY_AGP;
desc.size.width = 1;
desc.size.height = 1;
desc.format = CM_SURF_FMT_R32F;
desc.channelOrder = GSL_CHANNEL_ORDER_R;
desc.dimension = GSL_MOA_TEXTURE_2D;
m_srcDRMDMAMem = resAlloc(&desc);
desc.type = GSL_MOA_MEMORY_CARD_EXT_NONEXT;
m_dstDRMDMAMem = resAlloc(&desc);
m_cs->setDMAFlushBuf(m_srcDRMDMAMem, m_dstDRMDMAMem, 4 /*size of CM_SURF_FMT_R32F*/);
m_PerformLazyDeviceInit = false;
m_textureResource = m_cs->createTextureResource();
m_textureSampler = m_cs->createSampler();
}
}
void
Wait(gsl::gsCtx* cs, gslQueryTarget target, gslQueryObject object)
{
uint64 param;
uint32 mask = (target == GSL_DRMDMA_SYNC_ATI) ? GSL_ENGINE_MASK(GSL_ENGINEID_DRMDMA0) | GSL_ENGINE_MASK(GSL_ENGINEID_DRMDMA1) : GSL_ENGINEMASK_ALL_BUT_UVD_VCE;
object->BeginQuery(cs, target, 0, mask);
object->EndQuery(cs, 0);
object->GetResult(cs, &param);
assert(param == 1);
}
bool
CALGSLDevice::ResolveAperture(const gslMemObjectAttribTiling tiling) const
{
// Don't ask for aperture if the tiling is linear.
if ((GSL_MOA_TILING_LINEAR == tiling) ||
(GSL_MOA_TILING_LINEAR_GENERAL == tiling))
{
return false;
}
// Use aperture.
return true;
}
gslMemObject
CALGSLDevice::resAlloc(const CALresourceDesc* desc) const
{
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
assert(m_cs != 0);
gslMemObject mem = 0;
uint32 flags = desc->flags;
gslMemObjectAttribs attribs(
GSL_MOA_TEXTURE_1D, // type
GSL_MOA_MEMORY_CARD_EXT_NONEXT, // location XXX
(flags & CAL_RESALLOC_GLOBAL_BUFFER) ? GSL_MOA_TILING_LINEAR : g_CALBETiling_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
);
attribs.location = desc->type;
attribs.vaBase = desc->vaBase;
attribs.section = desc->section;
attribs.isAllocExecute = desc->isAllocExecute;
attribs.minAlignment = desc->minAlignment;
//!@note GSL asserts with tiled 1D images of any type.
if ((desc->dimension == GSL_MOA_BUFFER) ||
(desc->dimension == GSL_MOA_TEXTURE_1D) ||
(desc->dimension == GSL_MOA_TEXTURE_1D_ARRAY) ||
(desc->dimension == GSL_MOA_TEXTURE_BUFFER))
{
attribs.tiling = GSL_MOA_TILING_LINEAR;
}
if (desc->type == GSL_MOA_MEMORY_SYSTEM)
{
// CPU addres and size for pinning
attribs.cpu_address = desc->systemMemory;
attribs.size = desc->systemMemorySize;
if ((desc->size.width % 64) == 0)
{
attribs.tiling = GSL_MOA_TILING_LINEAR;
}
else
{
// Use linear general if width isn't aligned
attribs.tiling = GSL_MOA_TILING_LINEAR_GENERAL;
}
}
else if (desc->type == GSL_MOA_MEMORY_CARD_EXTERNAL_PHYSICAL)
{
attribs.cpu_address = (void*)desc->busAddress;
}
// Don't ask for aperture if the tiling is linear.
attribs.useAperture = ResolveAperture(attribs.tiling);
attribs.channelOrder = desc->channelOrder;
attribs.type = desc->dimension;
if (desc->mipLevels > 1) {
attribs.levels = desc->mipLevels;
attribs.mipmap = true;
}
switch (desc->dimension)
{
case GSL_MOA_BUFFER:
mem = m_cs->createMemObject1D(desc->format, desc->size.width, &attribs);
break;
case GSL_MOA_TEXTURE_1D:
mem = m_cs->createMemObject1D(desc->format, desc->size.width, &attribs);
break;
case GSL_MOA_TEXTURE_2D:
mem = m_cs->createMemObject2D(desc->format, desc->size.width, (uint32)desc->size.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;
}
#ifdef ATI_OS_WIN
if ((desc->section == GSL_SECTION_SVM || desc->section == GSL_SECTION_SVM_ATOMICS) && mem == NULL) {
//svm allocation failure, try one more time after wait.
Wait(m_cs, GSL_SYNC_ATI, m_mapQuery);
mem = m_cs->createMemObject1D(desc->format, desc->size.width, &attribs);
}
#endif
return mem;
}
gslMemObject
CALGSLDevice::resAllocView(gslMemObject res, gslResource3D size, size_t offset, cmSurfFmt format,
gslChannelOrder channelOrder, gslMemObjectAttribType resType, uint32 level, uint32 layer, uint32 flags,
uint64 bytePitch) const
{
assert(m_cs != 0);
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
gslMemObjectAttribs attribs(
GSL_MOA_TEXTURE_2D, // type. Filled in below based on the base type.
GSL_MOA_MEMORY_ALIAS, // location. Filled in below based on the base location.
GSL_MOA_TILING_LINEAR, // tiling. Filled in below based on the flags passed in.
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
);
attribs.bytePitch = bytePitch;
attribs.section = res->getAttribs().section;
attribs.isAllocExecute = res->getAttribs().isAllocExecute;
// Need to get the alignment info from hwl.
// Not sure hwl is correct though. Linear aligned 256b, tiled 8kb according to the address library.
uint32 alignment;
switch (flags & ~CAL_RESALLOCSLICEVIEW_LEVEL_AND_LAYER)
{
case CAL_RESALLOCSLICEVIEW_LINEAR_ALIGNED:
alignment = 256;
attribs.tiling = GSL_MOA_TILING_LINEAR;
break;
case CAL_RESALLOCSLICEVIEW_LINEAR_UNALIGNED:
alignment = 1;
attribs.tiling = GSL_MOA_TILING_LINEAR_GENERAL;
break;
default:
alignment = 8192;
// GSL asserts if this tiled mode is differnt from the original surface.
// (For example, original is GSL_MOA_TILING_MACRO and the new one is GSL_MOA_TILING_TILED)
// Use the original mode for view allocation.
attribs.tiling = res->getAttribs().tiling;
if (attribs.tiling == GSL_MOA_TILING_LINEAR || attribs.tiling == GSL_MOA_TILING_LINEAR_GENERAL)
{
alignment = 256;
}
break;
};
// Check any alignment restrictions.
uint64 resPitch = res->getPitch();
cmSurfFmt baseFormat = res->getFormat();
uint32 elementSize = cmGetSurfElementSize(static_cast<cmSurfFmt>(baseFormat));
uint64 offsetInBytes = static_cast<uint64>(offset) * elementSize;
if (offsetInBytes % alignment)
{
return 0; //offset doesn't match alignment requirements.
}
// alias has same location as the base resource.
attribs.type = res->getAttribs().type;
attribs.location = res->getAttribs().location;
attribs.displayable = res->getAttribs().displayable;
attribs.channelOrder = channelOrder;
gslMemObject mo = NULL, levelobject = res;
bool levelLayer = false;
if (flags & CAL_RESALLOCSLICEVIEW_LEVEL)
{
const gsSubImageParam levelParam(level);
levelobject = m_cs->createSubMemObject(res, GSL_LEVEL, levelParam);
attribs.bytePitch = static_cast<size_t>(levelobject->getPitch()) *
(levelobject->getBitsPerElement() / 8);
levelLayer = true;
}
if (flags & CAL_RESALLOCSLICEVIEW_LAYER)
{
const gsSubImageParam layerParam(layer);
mo = m_cs->createSubMemObject(levelobject, GSL_LAYER, layerParam);
if (levelobject != res)
{
m_cs->destroyMemObject(levelobject);
}
levelobject = mo;
levelLayer = true;
}
if (levelLayer) {
// If level/layer object was created, then don't need an extra view
return levelobject;
}
attribs.type = resType;
switch (resType)
{
case GSL_MOA_BUFFER:
mo = m_cs->createOffsetMemObject1D(levelobject, offsetInBytes, format,
size.width, &attribs);
break;
case GSL_MOA_TEXTURE_1D:
mo = m_cs->createOffsetMemObject1D(levelobject, offsetInBytes, format,
size.width, &attribs);
break;
case GSL_MOA_TEXTURE_2D:
mo = m_cs->createOffsetMemObject2D(levelobject, offsetInBytes, format,
size.width, (uint32)size.height, &attribs);
break;
case GSL_MOA_TEXTURE_3D:
mo = m_cs->createOffsetMemObject3D(levelobject, offsetInBytes, format,
size.width, (uint32)size.height, (uint32)size.depth, &attribs);
break;
case GSL_MOA_TEXTURE_BUFFER:
mo = m_cs->createOffsetMemObject1D(levelobject, offsetInBytes, format,
size.width, &attribs);
break;
case GSL_MOA_TEXTURE_1D_ARRAY:
mo = m_cs->createOffsetMemObject3D(levelobject, offsetInBytes, format,
size.width, 1, (uint32)size.height, &attribs);
break;
case GSL_MOA_TEXTURE_2D_ARRAY:
mo = m_cs->createOffsetMemObject3D(levelobject, offsetInBytes, format,
size.width, (uint32)size.height, (uint32)size.depth, &attribs);
break;
default:
break;
}
if (levelobject != res)
{
m_cs->destroyMemObject(levelobject);
}
return mo;
}
struct GSLDeviceMemMap
{
gslMemObject mem;
uint32 flags;
};
void*
CALGSLDevice::resMapLocal(size_t& pitch,
gslMemObject mem,
gslMapAccessType flags)
{
// No map really necessary if IOMMUv2 is being used, return the surface address directly
// as CPU can write to it for Linear tiled surfaces only
if (mem->getAttribs().isAllocSVM && mem->getAttribs().tiling <= GSL_MOA_TILING_LINEAR)
{
return (void*)mem->getImage(0)->surf.addr.getAddress();
}
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
void* pPtr = NULL;
gslMemObjectAttribLocation location = mem->getAttribs().location;
if ((location == GSL_MOA_MEMORY_CARD_LOCKABLE) || !m_allowDMA)
{
// direct lock
if (location == GSL_MOA_MEMORY_CARD_LOCKABLE) {
// Get tiling mode and resolve the aperture settings.
bool useAperture = ResolveAperture(mem->getAttribs().tiling);
pPtr = mem->map(m_cs, GSL_MAP_NOSYNC, GSL_GPU_0, false, useAperture);
}
else
{
pPtr = mem->map(m_cs, flags, GSL_GPU_0, true, false);
}
if (pPtr == NULL)
{
return NULL;
}
// obtain the pitch of the buffer
pitch = static_cast<size_t>(mem->getPitch());
}
else
{
// Allocate map structure for the unmap call
GSLDeviceMemMap* memMap = (GSLDeviceMemMap*)malloc(sizeof(GSLDeviceMemMap));
if (memMap == NULL)
{
return NULL;
}
uint64 width = mem->getRectWidth();
intp height = mem->getRectHeight();
cmSurfFmt format = mem->getFormat();
gslMemObjectAttribType dstType = mem->getAttribs().type;
gslMemObjectAttribs attribsDest(
dstType, // type
GSL_MOA_MEMORY_REMOTE_CACHEABLE, // 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_DERIVED, // numFormat
DRIVER_MODULE_GLL, // module
GSL_ALLOCATION_INSTANCED // alloc_type
);
attribsDest.channelOrder = mem->getAttribs().channelOrder;
// Create the target destination buffer
memMap->mem = m_cs->createMemObject2D(format, width, (uint32)height, &attribsDest);
if (memMap->mem == NULL)
{
attribsDest.location = GSL_MOA_MEMORY_AGP;
memMap->mem = m_cs->createMemObject2D(format, width, (uint32)height, &attribsDest);
if (memMap->mem == NULL)
{
free(memMap);
return NULL;
}
}
// set the pointer to it as the return buffer
pPtr = memMap->mem->map(m_cs, GSL_MAP_NOSYNC, GSL_GPU_0, false, false);
if (pPtr == 0)
{
m_cs->destroyMemObject(memMap->mem);
free(memMap);
return NULL;
}
// obtain the pitch of the temporary buffer
pitch = static_cast<size_t>(memMap->mem->getPitch());
// For write only cases, we don't care about the data
if (flags != GSL_MAP_WRITE_ONLY)
{
uint64 surfaceSize = memMap->mem->getSurfaceSize();
uint64 dstSize = mem->getSurfaceSize();
surfaceSize = (surfaceSize > dstSize) ? dstSize : surfaceSize;
//! @todo Workaround strange GSL/CMM-QS behavior. OCL doesn't require a sync,
//! because resource isn't busy on the CAL device. However without sync there are less CBs available
//! Conformanace multidevice test will create around 60 queues, instead of 70
uint32 mode = (IS_LINUX) ? GSL_SYNCUPLOAD_SYNC_WAIT | GSL_SYNCUPLOAD_SYNC_START : 0;
m_cs->DMACopy(mem, 0, memMap->mem, 0, surfaceSize, mode, NULL);
Wait(m_cs, GSL_DRMDMA_SYNC_ATI, m_mapDMAQuery);
}
m_hack.insert(std::pair<gslMemObject, intp>(mem, (intp) memMap));
memMap->flags = flags;
}
return pPtr;
}
void
CALGSLDevice::resUnmapLocal(gslMemObject mem)
{
// No unmap necessary with IOMMUv2 as map operation directly returned the base surface System VA
// which CPU can write to it for Linear tiled surfaces only
if (mem->getAttribs().isAllocSVM && mem->getAttribs().tiling <= GSL_MOA_TILING_LINEAR)
{
return;
}
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
// Find the pairing
Hack::iterator iter = m_hack.find(mem);
if (iter == m_hack.end())
{
// We didn't find a pair, then it's a direct map
mem->unmap(m_cs);
//! @todo: GSL doesn't wait for CB on unmap,
//! thus the data isn't really avaiable to all engines
if (mem->getAttribs().location != GSL_MOA_MEMORY_CARD_LOCKABLE)
{
Wait(m_cs, GSL_SYNC_ATI, m_mapQuery);
}
return;
}
GSLDeviceMemMap* memMap = (GSLDeviceMemMap*)iter->second;
m_hack.erase(iter);
memMap->mem->unmap(m_cs);
if (memMap->flags != GSL_MAP_READ_ONLY)
{
uint64 surfaceSize = memMap->mem->getSurfaceSize();
uint64 dstSize = mem->getSurfaceSize();
surfaceSize = (surfaceSize > dstSize) ? dstSize : surfaceSize;
//! @todo Workaround strange GSL/CMM-QS behavior. OCL doesn't require a sync,
//! because resource isn't busy on the CAL device. However without sync there are less CBs available
//! Conformanace multidevice test will create around 60 queues, instead of 70
uint32 mode = (IS_LINUX) ? GSL_SYNCUPLOAD_SYNC_WAIT | GSL_SYNCUPLOAD_SYNC_START : 0;
m_cs->DMACopy(memMap->mem, 0, mem, 0, surfaceSize, mode, NULL);
Wait(m_cs, GSL_DRMDMA_SYNC_ATI, m_mapDMAQuery);
}
m_cs->destroyMemObject(memMap->mem);
delete memMap;
}
gslMemObject
CALGSLDevice::resGetHeap(size_t size) const
{
assert(m_cs != 0);
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
gslMemObjectAttribs attribs(
GSL_MOA_VIRTUAL_HEAP, // type
GSL_MOA_MEMORY_SYSTEM, // 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_DERIVED, // numFormat
DRIVER_MODULE_GLL, // module
GSL_ALLOCATION_INSTANCED, // alloc_type
0, // channel_order
0 // size of cpu_address
);
gslMemObject rval = m_cs->createMemObject1D(CM_SURF_FMT_R32I, size, &attribs);
return rval;
}
void*
CALGSLDevice::resMapRemote(
size_t& pitch,
gslMemObject mem,
gslMapAccessType flags) const
{
// No map really necessary if IOMMUv2 is being used, return the surface address directly
// as CPU can write to it for Linear tiled surfaces only
if (mem->getAttribs().isAllocSVM && mem->getAttribs().tiling <= GSL_MOA_TILING_LINEAR)
{
return (void*)mem->getImage(0)->surf.addr.getAddress();
}
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
pitch = static_cast<size_t>(mem->getPitch());
return mem->map(m_cs, GSL_MAP_NOSYNC, GSL_GPU_0, false, false);
}
void
CALGSLDevice::resUnmapRemote(gslMemObject mem) const
{
// No unmap necessary with IOMMUv2 as map operation directly returned the base surface System VA
// which CPU can write to it for Linear tiled surfaces only
if (mem->getAttribs().isAllocSVM && mem->getAttribs().tiling <= GSL_MOA_TILING_LINEAR)
{
return;
}
//! @note: GSL device isn't thread safe
amd::ScopedLock k(gslDeviceOps());
mem->unmap(m_cs);
}
#define CPDMA_THRESHOLD 131072
CopyType
CALGSLDevice::GetCopyType(
gslMemObject srcMem,
gslMemObject destMem,
size_t* srcOffset,
size_t* destOffset,
bool allowDMA,
uint32 flags,
size_t size,
bool enableCopyRect) const
{
CopyType type = USE_NONE;
gslMemObjectAttribTiling srcTiling = srcMem->getAttribs().tiling;
gslMemObjectAttribTiling dstTiling = destMem->getAttribs().tiling;
gslMemObjectAttribType srcType = srcMem->getAttribs().type;
gslMemObjectAttribType dstType = destMem->getAttribs().type;
uint64 srcSize = srcMem->getSurfaceSize();
if (size != 0)
{
srcSize = (srcSize > size) ? size : srcSize;
}
// CPDMA isnt possible for anything other than a 1D_TEXURE or a BUFFER as it does a blind blob copy without regards to padding
bool isCPDMApossible = ((srcTiling == GSL_MOA_TILING_LINEAR) || srcTiling == GSL_MOA_TILING_LINEAR_GENERAL) &&
((dstTiling == GSL_MOA_TILING_LINEAR) || dstTiling == GSL_MOA_TILING_LINEAR_GENERAL) &&
(dstType == GSL_MOA_TEXTURE_1D || dstType == GSL_MOA_BUFFER) &&
(srcType == dstType);
if (!allowDMA && !isCPDMApossible)
{
return USE_NONE;
}
//
// Use CPDMA for transfers < 128KB
//
if (isCPDMApossible && (((flags != CAL_MEMCOPY_ASYNC) && (srcSize <= CPDMA_THRESHOLD) && !enableCopyRect) ||
(allowDMA == false)) )
{
type = USE_CPDMA;
}
// ### Check for Particular kind of DRMDMA here
else if (allowDMA &&
(((srcType == GSL_MOA_TEXTURE_2D) && (dstType == GSL_MOA_BUFFER)) ||
((dstType == GSL_MOA_TEXTURE_2D) && (srcType == GSL_MOA_BUFFER))))
{
if ((srcTiling != GSL_MOA_TILING_LINEAR) &&
(dstTiling == GSL_MOA_TILING_LINEAR))
{
intp bppSrc = srcMem->getBitsPerElement();
uint64 linearBytePitch = size * (bppSrc / 8);
// Make sure linear pitch in bytes is 4 bytes aligned
if (((linearBytePitch % 4) == 0) &&
// another DRM restriciton... SI has 4 pixels
(destOffset[0] % 4 == 0))
{
type = USE_DRMDMA_T2L;
}
else
{
type = USE_NONE;
}
}
else if ((srcTiling == GSL_MOA_TILING_LINEAR) &&
(dstTiling != GSL_MOA_TILING_LINEAR))
{
intp bppDst = destMem->getBitsPerElement();
uint64 linearBytePitch = size * (bppDst / 8);
// Make sure linear pitch in bytes is 4 bytes aligned
if (((linearBytePitch % 4) == 0) &&
// another DRM restriciton... SI has 4 pixels
(srcOffset[0] % 4 == 0))
{
type = USE_DRMDMA_L2T;
}
else
{
type = USE_NONE;
}
}
else
{
type = USE_NONE;
}
}
else if (dstType == srcType)
{
type = USE_DRMDMA;
}
return type;
}
uint32
CALGSLDevice::calcScratchBufferSize(uint32 regNum) const
{
gslProgramTargetEnum target = GSL_COMPUTE_PROGRAM;
// Determine the scratch size we need to allocate.
cmScratchSpaceNeededPerShaderStage scratchSpacePerShaderStage;
memset(&scratchSpacePerShaderStage, 0, sizeof(scratchSpacePerShaderStage));
uint32 scratchBufferSizes[gslProgramTarget_COUNT];
memset(scratchBufferSizes, 0, sizeof(scratchBufferSizes));
uint32 enabledShadersFlag = 0;
//!@todo should be CM_COMPUTE_SHADER
enabledShadersFlag |= CM_FRAGMENT_SHADER_BIT;
scratchSpacePerShaderStage.scratchSpace[CM_FRAGMENT_SHADER] = regNum;
target = GSL_FRAGMENT_PROGRAM;
m_cs->CalcAllScratchBufferSizes(enabledShadersFlag, scratchSpacePerShaderStage,
scratchBufferSizes);
return scratchBufferSizes[target];
}
void
CALGSLDevice::convertInputChannelOrder(intp*channelOrder) const
{
// set default to indicate that we don't want to override the channel order.
// set all order to zero to indicate default.
channelSwizzle chanSwiz = {SWIZZLE_ZERO,
SWIZZLE_ZERO,
SWIZZLE_ZERO,
SWIZZLE_ZERO};
switch (*channelOrder) {
case GSL_CHANNEL_ORDER_R:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_ZERO;
chanSwiz.b = SWIZZLE_ZERO;
chanSwiz.a = SWIZZLE_ONE;
break;
case GSL_CHANNEL_ORDER_A:
chanSwiz.r = SWIZZLE_ZERO;
chanSwiz.g = SWIZZLE_ZERO;
chanSwiz.b = SWIZZLE_ZERO;
chanSwiz.a = SWIZZLE_COMPONENT0;
break;
case GSL_CHANNEL_ORDER_RG:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_ZERO;
chanSwiz.a = SWIZZLE_ONE;
break;
case GSL_CHANNEL_ORDER_RA:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_ZERO;
chanSwiz.b = SWIZZLE_ZERO;
chanSwiz.a = SWIZZLE_COMPONENT1;
break;
case GSL_CHANNEL_ORDER_RGB:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT2;
chanSwiz.a = SWIZZLE_ONE;
break;
case GSL_CHANNEL_ORDER_RGBA:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT2;
chanSwiz.a = SWIZZLE_COMPONENT3;
break;
case GSL_CHANNEL_ORDER_ARGB:
chanSwiz.r = SWIZZLE_COMPONENT1;
chanSwiz.g = SWIZZLE_COMPONENT2;
chanSwiz.b = SWIZZLE_COMPONENT3;
chanSwiz.a = SWIZZLE_COMPONENT0;
break;
case GSL_CHANNEL_ORDER_BGRA:
chanSwiz.r = SWIZZLE_COMPONENT2;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT0;
chanSwiz.a = SWIZZLE_COMPONENT3;
break;
case GSL_CHANNEL_ORDER_SRGB:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT2;
chanSwiz.a = SWIZZLE_ONE;
break;
case GSL_CHANNEL_ORDER_SRGBX:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT2;
chanSwiz.a = SWIZZLE_ONE;
break;
case GSL_CHANNEL_ORDER_SRGBA:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT2;
chanSwiz.a = SWIZZLE_COMPONENT3;
break;
case GSL_CHANNEL_ORDER_SBGRA:
chanSwiz.r = SWIZZLE_COMPONENT2;
chanSwiz.g = SWIZZLE_COMPONENT1;
chanSwiz.b = SWIZZLE_COMPONENT0;
chanSwiz.a = SWIZZLE_COMPONENT3;
break;
case GSL_CHANNEL_ORDER_REPLICATE_R:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT0;
chanSwiz.b = SWIZZLE_COMPONENT0;
chanSwiz.a = SWIZZLE_COMPONENT0;
break;
case GSL_CHANNEL_ORDER_INTENSITY:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT0;
chanSwiz.b = SWIZZLE_COMPONENT0;
chanSwiz.a = SWIZZLE_COMPONENT0;
break;
case GSL_CHANNEL_ORDER_LUMINANCE:
chanSwiz.r = SWIZZLE_COMPONENT0;
chanSwiz.g = SWIZZLE_COMPONENT0;
chanSwiz.b = SWIZZLE_COMPONENT0;
chanSwiz.a = SWIZZLE_ONE;
break;
default: assert(0); break;
};
*channelOrder = *(uint32 *)&chanSwiz;
}
void
CALGSLDevice::fillImageHwState(gslMemObject mem, void* hwState, uint32 hwStateSize) const
{
amd::ScopedLock k(gslDeviceOps());
intp channelOrder = mem->getAttribs().channelOrder;
convertInputChannelOrder(&channelOrder);
m_textureResource->updateDepthTextureParam(mem);
m_textureResource->getTextureSrd(m_cs, mem, reinterpret_cast<const char*>(&channelOrder),
hwState, hwStateSize);
}
void
CALGSLDevice::fillSamplerHwState(bool unnorm, uint32 min, uint32 mag, uint32 addr,
float minLod, float maxLod, void* hwState, uint32 hwStateSize) const
{
amd::ScopedLock k(gslDeviceOps());
m_textureSampler->setUnnormalizedMode(m_cs, unnorm);
m_textureSampler->setMinFilter(m_cs, static_cast<gslTexParameterParamMinFilter>(min));
m_textureSampler->setMagFilter(m_cs, static_cast<gslTexParameterParamMagFilter>(mag));
m_textureSampler->setWrap(m_cs, GSL_TEXTURE_WRAP_S, static_cast<gslTexParameterParamWrap>(addr));
m_textureSampler->setWrap(m_cs, GSL_TEXTURE_WRAP_T, static_cast<gslTexParameterParamWrap>(addr));
m_textureSampler->setWrap(m_cs, GSL_TEXTURE_WRAP_R, static_cast<gslTexParameterParamWrap>(addr));
m_textureSampler->setMinLOD(m_cs, static_cast<float32>(minLod));
m_textureSampler->setMaxLOD(m_cs, static_cast<float32>(maxLod));
m_textureSampler->getSamplerSrd(m_cs, hwState, hwStateSize);
}