Files
rocm-systems/rocclr/runtime/device/gpu/gslbe/src/rt/GSLContext.cpp
T

1299 строки
40 KiB
C++
Исходник Обычный вид История

2014-07-04 16:17:05 -04:00
#include "gsl_ctx.h"
#include "gsl_adaptor.h"
#include "GSLContext.h"
#include "GSLDevice.h"
#include "cm_if.h"
#include "amuABI.h"
#include "shader/ProgramObject.h"
#include "query/QueryObject.h"
#include "query/PerformanceQueryObject.h"
#include "constbuffer/ConstantBufferObject.h"
#include "sampler/SamplerObject.h"
#include "texture/TextureResourceObject.h"
#include "uav/UAVObject.h"
#include "RenderStateObject.h"
#include "shadertracebuffer/ShaderTraceBufferObject.h"
#include "scratchbuffer/ScratchBufferObject.h"
#include "memory/MemObject.h"
#include "framebuffer/FrameBufferObject.h"
#include <algorithm>
CALGSLContext::CALGSLContext()
{
m_cs = 0;
m_rs = 0;
m_fb = 0;
m_allowDMA = false;
COMPILE_TIME_ASSERT((int)MAX_OUTPUTS <= (int)GSL_MAX_OUTPUT);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_VIDEO == (int)CAL_CONTEXT_VIDEO);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_3DCOMPUTE == (int)CAL_CONTEXT_3DCOMPUTE);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_COMPUTE0 == (int)CAL_CONTEXT_COMPUTE0);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_COMPUTE1 == (int)CAL_CONTEXT_COMPUTE1);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_DRMDMA0 == (int)CAL_CONTEXT_DRMDMA0);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_DRMDMA1 == (int)CAL_CONTEXT_DRMDMA1);
COMPILE_TIME_ASSERT((int)GSL_VID_CONTEXT_VIDEO_VCE == (int)CAL_CONTEXT_VIDEO_VCE);
memset(m_textureSamplers, 0, sizeof(m_textureSamplers));
memset(m_textureResources, 0, sizeof(m_textureResources));
memset(m_uavResources, 0, sizeof(m_uavResources));
memset(m_constantBuffers, 0, sizeof(m_constantBuffers));
m_scratchBuffers = 0;
m_videoSession = 0;
m_waitType = CAL_WAIT_LOW_CPU_UTILIZATION;
}
CALGSLContext::~CALGSLContext()
{
assert(m_cs == 0);
}
bool
CALGSLContext::open(
const CALGSLDevice* pDeviceObject,
uint32 nEngines,
gslEngineDescriptor* engines)
{
m_Dev = pDeviceObject;
//! @note: GSL device isn't thread safe
amd::ScopedLock k(dev()->gslDeviceOps());
gsl::gsAdaptor* native = dev()->getNative();
assert(native != 0);
EQManagerConfig EQConfig = EQManager_HIGH;
gslEngineID mainEngineOrdinal = GSL_ENGINEID_INVALID;
gslEngineID sdmaOrdinal = GSL_ENGINEID_INVALID;
gslEngineID decoderOrdinal = GSL_ENGINEID_INVALID;
gslEngineID encoderOrdinal = GSL_ENGINEID_INVALID;
for (uint i = 0; i < nEngines; i++)
{
if (engines[i].id >= GSL_ENGINEID_3DCOMPUTE0 &&
engines[i].id <= GSL_ENGINEID_COMPUTE7)
{
mainEngineOrdinal = engines[i].id;
}
if (engines[i].id == GSL_ENGINEID_DRMDMA0||
engines[i].id == GSL_ENGINEID_DRMDMA1)
{
sdmaOrdinal = engines[i].id;
m_allowDMA = dev()->canDMA();
}
if (engines[i].id == GSL_ENGINEID_UVD)
{
decoderOrdinal = engines[i].id;
}
if (engines[i].id == GSL_ENGINEID_VCE)
{
encoderOrdinal = engines[i].id;
}
}
if (decoderOrdinal != GSL_ENGINEID_INVALID)
{
m_cs = native->createDecoderContext(decoderOrdinal);
}
else if (encoderOrdinal != GSL_ENGINEID_INVALID)
{
m_cs = native->createEncoderContext(encoderOrdinal);
}
else
{
m_cs = native->createComputeContext(mainEngineOrdinal, sdmaOrdinal);
}
if (m_cs == 0)
{
return false;
}
m_cs->getMainSubCtx()->setVPUMask(dev()->getVPUMask());
m_cs->makeCurrent(0);
m_rs = m_cs->createRenderState();
if (m_rs == 0)
{
native->deleteContext(m_cs);
m_cs = 0;
return false;
}
m_fb = m_cs->createFrameBuffer();
if (m_fb == 0)
{
m_cs->destroyRenderState(m_rs);
m_rs = 0;
native->deleteContext(m_cs);
m_cs = 0;
return false;
}
m_cs->setRenderState(m_rs);
m_rs->setCurrentFrameBufferObject(m_cs, m_fb);
//
//
// configure the default compute mode
//
m_rs->setComputeShader(m_cs, true);
if (decoderOrdinal != GSL_ENGINEID_INVALID)
{
m_eventQueue[MainEngine].open(m_cs, GSL_UVD_SYNC_ATI, EQConfig, GSL_ENGINEMASK_ALL_BUT_UVD_VCE | GSL_ENGINE_MASK(GSL_ENGINEID_UVD));
}
else if (encoderOrdinal != GSL_ENGINEID_INVALID)
{
m_eventQueue[MainEngine].open(m_cs, GSL_VCE_SYNC_ATI, EQConfig, GSL_ENGINEMASK_ALL_BUT_UVD_VCE | GSL_ENGINE_MASK(GSL_ENGINEID_VCE));
}
else
{
m_eventQueue[MainEngine].open(m_cs, GSL_SYNC_ATI, EQConfig);
if (dev()->uavInCB())
{
// Evergreen uses physical mode for DRM engine, so flush 3D pipe wih DRM,
// thus GSL can get VA ranges back from KMD asap
m_eventQueue[SdmaEngine].open(m_cs, GSL_DRMDMA_SYNC_ATI, EQConfig);
}
else
{
m_eventQueue[SdmaEngine].open(m_cs, GSL_DRMDMA_SYNC_ATI, EQConfig, GSL_ENGINE_MASK(GSL_ENGINEID_DRMDMA0) | GSL_ENGINE_MASK(GSL_ENGINEID_DRMDMA1));
}
}
m_cs->setGPU((gslGPUMask)dev()->getVPUMask());
m_cs->setDMAFlushBuf(dev()->m_srcDRMDMAMem, dev()->m_dstDRMDMAMem, 4 /* size of CM_SURF_FMT_R32F*/);
// Create the GSL scratch buffer object
m_scratchBuffers = m_cs->createScratchBuffer();
if (m_scratchBuffers == NULL)
{
return false;
}
if (m_textureSamplers[0] == 0)
{
// Special case. GSL validation requires a sampler with any texture setup.
// In OCL kernel may have an image argument, but doesn't use it. So a sampler
// can be undefined.
//! @note HSAIL will need a sampler as well
m_textureSamplers[0] = m_cs->createSampler();
m_rs->setSamplerObject(GSL_COMPUTE_PROGRAM, m_textureSamplers[0], 0);
}
return true;
}
void
CALGSLContext::close(gsl::gsAdaptor* native)
{
if (m_cs == 0)
{
return;
}
//! @note: GSL device isn't thread safe
amd::ScopedLock k(dev()->gslDeviceOps());
m_cs->Flush();
assert(m_rs != 0);
assert(m_fb != 0);
m_cs->setRenderState(m_rs);
m_rs->setCurrentProgramObject(GSL_COMPUTE_PROGRAM, 0);
for (int i = 0; i < MAX_SAMPLERS; i++)
{
m_rs->setSamplerObject(GSL_COMPUTE_PROGRAM, 0, i);
if (m_textureSamplers[i] != 0)
{
m_cs->destroySampler(m_textureSamplers[i]);
}
}
for (int i = 0; i < MAX_RESOURCES; i++)
{
m_rs->setTextureResourceObject(m_cs, GSL_COMPUTE_PROGRAM, 0, i);
if (m_textureResources[i] != 0)
{
m_cs->destroyTextureResource(m_textureResources[i]);
}
}
for (int i = 0; i < MAX_UAVS; i++)
{
m_rs->setUavObject(m_cs, GSL_COMPUTE_PROGRAM, 0, static_cast<uint32>(GSL_UAV0 + i));
if (m_uavResources[i] != 0)
{
m_cs->destroyUAVObject(m_uavResources[i]);
}
}
for (int i = 0; i < MAX_CONSTANTBUFFERS; i++)
{
m_rs->setConstantBufferObject(GSL_COMPUTE_PROGRAM, 0, i);
if (m_constantBuffers[i])
{
m_cs->destroyConstantBuffer(m_constantBuffers[i]);
}
}
if (m_scratchBuffers != NULL)
{
if (!dev()->uavInCB())
{
m_rs->setScratchBufferObject(GSL_FRAGMENT_PROGRAM, 0);
m_scratchBuffers->setMemObject(m_cs, 0, 0);
}
else
{
m_rs->setScratchBufferObject(GSL_COMPUTE_PROGRAM, 0);
for (int i = 0; i < MAX_SHADERENGINES; i++)
{
m_scratchBuffers->setMemObject(m_cs, 0, i);
}
}
m_cs->destroyScratchBuffer(m_scratchBuffers);
m_scratchBuffers = 0;
}
m_rs->setCurrentFrameBufferObject(m_cs, 0);
m_cs->setRenderState(0);
m_cs->destroyFrameBuffer(m_fb);
m_cs->destroyRenderState(m_rs);
m_rs = 0;
m_fb = 0;
for (uint32 i = 0; i < AllEngines; ++i)
{
m_eventQueue[i].close();
}
native->deleteContext(m_cs);
m_cs = 0;
}
bool
CALGSLContext::setInput(uint32 physUnit, gslMemObject mem)
{
assert(physUnit < MAX_RESOURCES);
//if there is no texture resource object associated with this unit, then allocate one.
if (m_textureResources[physUnit] == 0)
{
m_textureResources[physUnit] = m_cs->createTextureResource();
m_rs->setTextureResourceObject(m_cs, GSL_COMPUTE_PROGRAM,
m_textureResources[physUnit], physUnit);
}
m_textureResources[physUnit]->setMemObject(m_cs, GSL_COMPUTE_PROGRAM, mem);
if (mem != NULL)
{
intp channelOrder = mem->getAttribs().channelOrder;
dev()->convertInputChannelOrder(&channelOrder);
m_rs->setTextureResourceSwizzle(GSL_COMPUTE_PROGRAM, physUnit,
reinterpret_cast<const int32 *>(&channelOrder));
}
return true;
}
bool
CALGSLContext::setConstantBuffer(uint32 physUnit, gslMemObject mem, uint32 offset, size_t size)
{
assert(physUnit < MAX_CONSTANTBUFFERS);
assert((physUnit < MAX_APICONSTANTBUFFERS) || (physUnit == SC_INFO_CONSTANTBUFFER));
//if there is no constant buffer object associated with this unit, then allocate one.
if (m_constantBuffers[physUnit] == 0)
{
m_constantBuffers[physUnit] = m_cs->createConstantBuffer();
m_rs->setConstantBufferObject(GSL_COMPUTE_PROGRAM, m_constantBuffers[physUnit], physUnit);
}
return m_constantBuffers[physUnit]->SetMemory(m_cs, mem, static_cast<mcoffset>(offset), (uint32)size);
}
bool
CALGSLContext::setUAVBuffer(uint32 physUnit, gslMemObject mem, gslUAVType uavType)
{
if (!dev()->uavInCB()) // SI
{
assert(physUnit < MAX_UAVS);
if (m_uavResources[physUnit] == 0)
{
m_uavResources[physUnit] = m_cs->createUAVObject();
m_rs->setUavObject(m_cs, GSL_COMPUTE_PROGRAM, m_uavResources[physUnit], GSL_UAV0 + physUnit);
}
m_uavResources[physUnit]->setMemObject(m_cs, mem, uavType);
m_uavResources[physUnit]->setRSOBindings(m_cs, GSL_COMPUTE_PROGRAM);
}
else
{
assert(physUnit < MAX_OUTPUTS);
m_fb->setColorBufferMemory(m_cs, mem, physUnit, true);
}
return true;
}
void
CALGSLContext::setUavMask(const CALUavMask& uavMask)
{
// Only do this if UAV in the Color Buffer block
if (dev()->uavInCB())
{
int count = 0;
for (int i = 0; i < MAX_OUTPUTS; i++)
{
m_drawBuffers.buffer[i] = GSL_COLOR_NONE;
if (uavMask.mask[0] & (1 << i))
{
m_drawBuffers.buffer[count] = static_cast<gslColorBuffer>(GSL_COLOR_BUFFER0 + i);
++count;
}
}
m_fb->setDrawBuffers(m_cs, m_drawBuffers);
}
}
void
CALGSLContext::setUAVChannelOrder(uint32 physUnit, gslMemObject mem)
{
if (!dev()->uavInCB()) // SI
{
assert(physUnit < MAX_UAVS);
intp channelOrder = mem->getAttribs().channelOrder;
dev()->convertInputChannelOrder(&channelOrder);
m_uavResources[physUnit]->setParameter(GSL_UAV_RESOURCE_SWIZZLE, &channelOrder);
}
else
{
assert(physUnit < MAX_OUTPUTS);
int32 channelOrder[2];
channelOrder[0] = mem->getAttribs().channelOrder;
channelOrder[1] = physUnit;
m_fb->setChannelOrder(m_cs, (const int32*) channelOrder);
}
}
void
CALGSLContext::setProgram(gslProgramObject func)
{
m_rs->setCurrentProgramObject(GSL_COMPUTE_PROGRAM, func);
}
bool
CALGSLContext::runProgramGrid(GpuEvent& event, const ProgramGrid* pProgramGrid, const gslMemObject* mems, uint32 numMems)
{
eventBegin(MainEngine);
m_rs->Dispatch(m_cs, &pProgramGrid->gridBlock, &pProgramGrid->partialGridBlock,
&pProgramGrid->gridSize, pProgramGrid->localSize, mems, numMems);
eventEnd(MainEngine, event);
return true;
}
bool
CALGSLContext::runProgramVideoDecode(GpuEvent& event, gslMemObject mo, const CALprogramVideoDecode& decode)
{
gslVidDecodeData data;
data.decode_output = mo;
data.picture_parameter_1 = decode.picture_parameter_1;
data.picture_parameter_2 = decode.picture_parameter_2;
data.picture_parameter_2_size = decode.picture_parameter_2_size;
data.bitstream_data = decode.bitstream_data;
data.bitstream_data_size = decode.bitstream_data_size;
data.slice_data_control = decode.slice_data_control;
data.slice_data_size = decode.slice_data_size;
eventBegin(MainEngine);
eventEnd(MainEngine, event);
gslVidDecode(&m_videocontext, m_videoSession, data);
return true;
}
bool
CALGSLContext::isDone(GpuEvent* event)
{
if (event->isValid())
{
assert(event->engineId_ < AllEngines);
if (m_eventQueue[event->engineId_].isDone(event->id))
{
event->invalidate();
return true;
}
return false;
}
return true;
}
void
CALGSLContext::waitForEvent(GpuEvent* event)
{
if (event->isValid())
{
assert(event->engineId_ < AllEngines);
m_eventQueue[event->engineId_].waitForEvent(event->id, m_waitType);
event->invalidate();
}
}
void
CALGSLContext::flushIOCaches() const
{
m_cs->FlushIOCaches();
}
void
CALGSLContext::flushCUCaches(bool flushL2) const
2014-07-04 16:17:05 -04:00
{
m_cs->FlushCUCaches(flushL2);
2014-07-04 16:17:05 -04:00
}
gslProgramObject
CALGSLContext::createProgramObject(CALuint type)
{
return m_cs->createProgramObject(GSL_COMPUTE_PROGRAM);
}
void
CALGSLContext::setScratchBuffer(gslMemObject mem, int32 engineId)
{
// This card has global scratch buffer, so we only manage one resource,
// independent of program type and number of shader engineers.
// For consistency with GSL, We will store the buffer under the
// fragment program type for shader engine 0.
gslProgramTargetEnum target =
(!dev()->uavInCB()) ? GSL_FRAGMENT_PROGRAM : GSL_COMPUTE_PROGRAM;
gslScratchBufferObject scratchBuff = (mem != NULL) ? m_scratchBuffers : NULL;
m_rs->setScratchBufferObject(target, m_scratchBuffers);
m_scratchBuffers->setMemObject(m_cs, mem, engineId);
}
void
CALGSLContext::destroyProgramObject(gslProgramObject func)
{
m_cs->destroyProgramObject(func);
}
void
CALGSLContext::writeSurfRaw(GpuEvent& event, gslMemObject mem, size_t size, const void* data)
{
eventBegin(MainEngine);
mem->writeDataRaw(m_cs, size, data, true);
eventEnd(MainEngine, event);
}
bool
CALGSLContext::copyPartial(GpuEvent& event,
gslMemObject srcMem,
size_t* srcOffset,
gslMemObject destMem,
size_t* destOffset,
size_t* size,
CALmemcopyflags flags,
bool enableRectCopy)
{
uint64 surfaceSize;
uint32 mode = GSL_SYNCUPLOAD_IGNORE_ELEMENTSIZE;
EngineType engineId = MainEngine;
assert(m_cs != 0);
CopyType type = USE_NONE;
uint64 linearBytePitch = 0;
intp bpp = 0;
type = dev()->GetCopyType(srcMem, destMem, srcOffset, destOffset, m_allowDMA, flags, surfaceSize, size[0], enableRectCopy);
if(type == USE_NONE)
{
return false;
}
switch (flags)
{
case CAL_MEMCOPY_DEFAULT:
case CAL_MEMCOPY_SYNC:
mode |= GSL_SYNCUPLOAD_SYNC_START | GSL_SYNCUPLOAD_SYNC_WAIT;
break;
case CAL_MEMCOPY_ASYNC:
if ((type == USE_DRMDMA) || (type == USE_DRMDMA_T2L) || (type == USE_DRMDMA_L2T))
{
engineId = SdmaEngine;
}
break;
default:
break;
}
gslErrorCode gslErr = GSL_NO_ERROR;
switch (type)
{
case USE_DRMDMA:
mode |= GSL_SYNCUPLOAD_DMA;
eventBegin(engineId);
if(enableRectCopy)
{
if ((*srcOffset%4 != 0) || (*destOffset%4 != 0) || (size[0]%4 !=0))
{
return false;
}
m_cs->syncUploadRawRect(srcMem, srcOffset[0], (uint32)srcOffset[1], (uint32)srcOffset[2],
destMem, destOffset[0], (uint32)destOffset[1], (uint32)destOffset[2],
size[0], (uint32)size[1], (uint32)size[2], mode);
}
else
{
m_cs->syncUploadRaw(srcMem, srcOffset[0], destMem, destOffset[0], size[0], mode);
}
eventEnd(engineId, event);
break;
case USE_DRMDMA_T2L:
mode |= GSL_SYNCUPLOAD_DMA;
eventBegin(engineId);
bpp = srcMem->getBitsPerElement();
linearBytePitch = size[0] * (bpp / 8);
gslErr = m_cs->DMACopySubSurface(srcOffset[0], (uint32)srcOffset[1], size[0], (uint32)size[1],
destMem, destOffset[0], linearBytePitch, srcMem, 0, 0, ATIGL_FALSE, mode);
eventEnd(engineId, event);
break;
case USE_DRMDMA_L2T:
mode |= GSL_SYNCUPLOAD_DMA;
eventBegin(engineId);
bpp = destMem->getBitsPerElement();
linearBytePitch = size[0] * (bpp / 8);
gslErr = m_cs->DMACopySubSurface(destOffset[0], (uint32)destOffset[1], size[0], (uint32)size[1],
srcMem, srcOffset[0], linearBytePitch, destMem, 0, 0, ATIGL_TRUE, mode);
eventEnd(engineId, event);
break;
case USE_CPDMA:
eventBegin(MainEngine);
m_cs->syncUploadRaw(srcMem, srcOffset[0], destMem, destOffset[0], size[0], mode);
eventEnd(MainEngine, event);
break;
default:
assert(0);
//
// XXX - should never be here
//
return false;
}
if (gslErr != GSL_NO_ERROR)
{
return false;
}
return true;
}
void
CALGSLContext::setSamplerParameter(uint32 sampler, gslTexParameterPname param, void* vals)
{
if (m_textureSamplers[sampler] == 0)
{
m_textureSamplers[sampler] = m_cs->createSampler();
m_rs->setSamplerObject(GSL_COMPUTE_PROGRAM, m_textureSamplers[sampler], sampler);
}
float* params = reinterpret_cast<float*>(vals);
switch (param)
{
case GSL_TEXTURE_MIN_FILTER:
m_textureSamplers[sampler]->setMinFilter(m_cs,
static_cast<gslTexParameterParamMinFilter>((uint32)params[0]));
break;
case GSL_TEXTURE_MAG_FILTER:
m_textureSamplers[sampler]->setMagFilter(m_cs,
static_cast<gslTexParameterParamMagFilter>((uint32)params[0]));
break;
case GSL_TEXTURE_WRAP_S:
case GSL_TEXTURE_WRAP_T:
case GSL_TEXTURE_WRAP_R:
m_textureSamplers[sampler]->setWrap(m_cs, param,
static_cast<gslTexParameterParamWrap>((uint32)params[0]));
break;
case GSL_TEXTURE_BORDER_COLOR:
m_textureSamplers[sampler]->setBorderColor(m_cs, params);
break;
default:
assert(!"Unknown sampler state");
break;
}
}
gslQueryObject CALGSLContext::createCounter(gslQueryTarget target) const
{
return m_cs->createQuery(target);
}
void CALGSLContext::destroyCounter(gslQueryObject counter) const
{
m_cs->destroyQuery(counter);
}
void CALGSLContext::beginCounter(gslQueryObject counter, gslQueryTarget target) const
{
// This should never be called for UVD/VCE Sync queries in case it is
// Please correctly pass on EngineMask else queries may be messed up
assert(target != GSL_UVD_SYNC_ATI || target != GSL_VCE_SYNC_ATI);
counter->BeginQuery(m_cs, target, 0);
}
void CALGSLContext::endCounter(gslQueryObject counter, GpuEvent& event)
{
eventBegin(MainEngine);
counter->EndQuery(m_cs, 0);
eventEnd(MainEngine, event);
}
void CALGSLContext::getCounter(uint64* result, gslQueryObject counter) const
{
counter->GetResult(m_cs, result);
}
void CALGSLContext::configPerformanceCounter(gslQueryObject counter, CALuint block, CALuint index, CALuint event) const
{
counter->getAsPerformanceQueryObject()->setCounterState(block, index, event);
}
gslMemObject
CALGSLContext::createConstants(uint32 count) const
{
assert(m_cs != 0);
const gslMemObjectAttribs attribs(
GSL_MOA_CONSTANT_STORE, // type
GSL_MOA_MEMORY_CARD, // location
GSL_MOA_TILING_LINEAR, // tiling
GSL_MOA_DISPLAYABLE_NO, // displayable
ATIGL_FALSE, // mipmap
1, // samples
0, // cpu_address
GSL_MOA_SIGNED_NO, // signed_format
GSL_MOA_FORMAT_NORM, // numFormat
DRIVER_MODULE_GLL, // module
GSL_ALLOCATION_INSTANCED // alloc_type
);
return m_cs->createMemObject1D(CM_SURF_FMT_RGBX8, count, &attribs);
}
void
CALGSLContext::setConstants(gslMemObject constants) const
{
m_cs->setIntConstants(GSL_COMPUTE_PROGRAM, constants);
}
void
CALGSLContext::destroyConstants(gslMemObject constants) const
{
assert(m_cs != 0);
assert(constants != 0);
m_cs->setIntConstants(GSL_COMPUTE_PROGRAM, 0);
m_cs->destroyMemObject(constants);
}
void
CALGSLContext::getFuncInfo(gslProgramObject func, gslProgramTarget target, CALfuncInfo *pInfo)
{
assert(m_cs!= 0);
assert(func!= 0);
gsl::gsProgramInfo* pProgramResource = func->getProgramResourceInfo();
pInfo->maxScratchRegsNeeded = pProgramResource->elfInfo._maxScratchRegsNeeded;
pInfo->numSharedGPRUser = pProgramResource->elfInfo._numSharedGPRUser;
pInfo->numSharedGPRTotal = pProgramResource->elfInfo._numSharedGPRTotal;
pInfo->eCsSetupMode = (CALboolean)pProgramResource->elfInfo._eCsSetupMode;
pInfo->numThreadPerGroup = pProgramResource->elfInfo._numThreadPerGroup;
pInfo->numThreadPerGroupX = pProgramResource->elfInfo._numThreadPerGroupX;
pInfo->numThreadPerGroupY = pProgramResource->elfInfo._numThreadPerGroupY;
pInfo->numThreadPerGroupZ = pProgramResource->elfInfo._numThreadPerGroupZ;
pInfo->totalNumThreadGroup = pProgramResource->elfInfo._totalNumThreadGroup;
pInfo->numWavefrontPerSIMD = pProgramResource->elfInfo._NumWavefrontPerSIMD;
pInfo->isMaxNumWavePerSIMD = (CALboolean)pProgramResource->elfInfo._IsMaxNumWavePerSIMD;
pInfo->setBufferForNumGroup = (CALboolean)pProgramResource->elfInfo._SetBufferForNumGroup;
pInfo->wavefrontSize = pProgramResource->wavefrontSize;
pInfo->numGPRsAvailable = pProgramResource->numGPRsAvailable;
pInfo->numGPRsUsed = pProgramResource->numGPRsUsed;
pInfo->numSGPRsAvailable = pProgramResource->numSGPRsAvailable;
pInfo->numSGPRsUsed = pProgramResource->numSGPRsUsed;
pInfo->numVGPRsAvailable = pProgramResource->numVGPRsAvailable;
pInfo->numVGPRsUsed = pProgramResource->numVGPRsUsed;
pInfo->LDSSizeAvailable = pProgramResource->LDSSizeAvailable;
pInfo->LDSSizeUsed = pProgramResource->LDSSizeUsed;
pInfo->stackSizeAvailable = pProgramResource->stackSizeAvailable;
pInfo->stackSizeUsed = pProgramResource->stackSizeUsed;
}
bool
CALGSLContext::WaitSignal(gslMemObject mem, CALuint value)
{
uint64 surfAddr = mem->getPhysicalAddress(m_cs);
uint64 markerAddr = mem->getMarkerAddress(m_cs);
uint64 markerOffset = markerAddr - surfAddr;
if((markerAddr + markerOffset) == 0)
return false;
m_cs->p2pMarkerOp(mem, value, markerOffset, false);
return true;
}
bool
CALGSLContext::WriteSignal(gslMemObject mem, CALuint value, CALuint64 offset)
{
m_cs->p2pMarkerOp(mem, value,offset, true);
m_cs->Flush();
return true;
}
bool
CALGSLContext::MakeBuffersResident(CALuint numObjects, gslMemObject* pMemObjects,
CALuint64* surfBusAddress, CALuint64* markerBusAddress)
{
bool res = true;
res = (m_cs->makeBuffersResident(numObjects, pMemObjects, surfBusAddress,
markerBusAddress) == GSL_NO_ERROR) ? true:false;
return res;
}
bool
CALGSLContext::openVideoSession(CALvideoProperties& properties)
{
gslVidSessionCreateData data;
assert(properties.size == sizeof(CALvideoProperties));
data.size = sizeof(gslVidSessionCreateData);
data.type = (gslDecodeProfile) properties.profile;
data.format = (gslDecodeFormat) properties.format;
data.width = properties.width;
data.height = properties.height;
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = static_cast<gslVidContextEnum>(properties.VideoEngine_name);
m_videoSession = gslVidSessionCreate(&m_videocontext, data);
if (m_videoSession == NULL)
{
return false;
}
return true;
}
void
CALGSLContext::closeVideoSession(void)
{
if (m_videoSession)
{
//! @note: GSL device isn't thread safe
amd::ScopedLock k(dev()->gslDeviceOps());
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO;
gslVidSessionDestroy(&m_videocontext, m_videoSession);
}
}
void
CALGSLContext::bindAtomicCounter(uint32 index, gslMemObject obj)
{
m_cs->bindAtomicCounter(index, obj);
}
void
CALGSLContext::setGWSResource(uint32 index, uint32 value)
{
m_cs->setGWSResource(index, value);
}
void
CALGSLContext::syncAtomicCounter(GpuEvent& event, uint32 index, bool read)
{
eventBegin(MainEngine);
m_cs->syncAtomicCounter(index, read);
eventEnd(MainEngine, event);
}
void
CALGSLContext::createVCE(CALEncodeCreateVCE* pEncodeVCE, CALuint flags)
{
gslVidEncodeCreateVCEData data;
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeCreateVCE(&m_videocontext, &data);
pEncodeVCE->VCEsession = reinterpret_cast<CALvoid *>(data.session);
}
void
CALGSLContext::destroyVCE(CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeDestroyVCE(&m_videocontext);
}
void
CALGSLContext::getDeviceInfoVCE(CALuint *num_device, CALEncodeGetDeviceInfo* pEncodeDeviceInfo, CALuint flags)
{
gslVidEncodeGetDeviceInfo(num_device, (gslVidEncodeGetDeviceInfoData *) pEncodeDeviceInfo);
}
void
CALGSLContext::getNumberOfModesVCE(CALEncodeGetNumberOfModes* pEncodeNumberOfModes, CALuint flags)
{
uint32 device_id =0;
gslVidEncodeQueryNumberOfModesData data;
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeGetNumberOfModes(&m_videocontext, device_id, &data);
pEncodeNumberOfModes->num_of_encode_Mode = data.num_of_encode_Mode;
}
void
CALGSLContext::getModesVCE(CALuint device_id, CALuint NumEncodeModesToRetrieve, CALEncodeGetModes* pEncodeMode, CALuint flags)
{
gslVidEncodeGetModesData data;
data.NumEncodeModesToRetrieve = NumEncodeModesToRetrieve ;
data.pEncodeModes = (GSL_VID_ENCODE_MODE *)malloc(sizeof(GSL_VID_ENCODE_MODE)*NumEncodeModesToRetrieve);
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeGetModes(&m_videocontext, device_id, &data);
// pEncodeMode = ( CALEncodeGetModes *) data.pEncodeModes;
pEncodeMode->NumEncodeModesToRetrieve = data.NumEncodeModesToRetrieve;
CALencodeMode *pEncodeModes = pEncodeMode->pEncodeModes;
for (CALuint mode_id = 0; mode_id < NumEncodeModesToRetrieve; mode_id++)
{
switch(data.pEncodeModes[mode_id])
{
case GSL_VID_encode_AVC_FULL:
pEncodeModes[mode_id] = CAL_VID_encode_AVC_FULL;
break;
case GSL_VID_encode_AVC_ENTROPY:
pEncodeModes[mode_id] = CAL_VID_encode_AVC_ENTROPY;
break;
default:
pEncodeModes[mode_id] = CAL_VID_encode_MODE_NONE;
break;
}
}
free(data.pEncodeModes);
}
void
CALGSLContext::getDeviceCAPVCE(CALuint device_id,
CALuint encode_cap_total_size,
CALEncodeGetDeviceCAP *pEncodeCAP,
CALuint flags)
{
gslVidEncodeGetDeviceCAPData *data = (gslVidEncodeGetDeviceCAPData *) pEncodeCAP;
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
data->num_of_encode_cap = encode_cap_total_size;
gslVidEncodeGetDeviceCAP(device_id, encode_cap_total_size, data);
}
void
CALGSLContext::createEncodeSession(CALuint device_id,
CALencodeMode encode_mode,
CAL_VID_PROFILE_LEVEL encode_profile_level,
CAL_VID_PICTURE_FORMAT encode_formatm,
CALuint encode_width,
CALuint encode_height,
CALuint frameRateNum,
CALuint frameRateDenom,
CAL_VID_ENCODE_JOB_PRIORITY encode_priority_level)
{
gslVidEncodeSessionCreateData data;
data.encode_mode = (GSL_VID_ENCODE_MODE)encode_mode;
data.encode_profile_level.profile = encode_profile_level.profile;
data.encode_profile_level.level = encode_profile_level.level;
data.encode_formatm = (GSL_VID_PICTURE_FORMAT)encode_formatm;
data.encode_width = encode_width;
data.encode_height = encode_height;
data.frameRateNumerator = frameRateNum;
data.frameRateDenominator = frameRateDenom;
data.encode_priority_level = (GSL_VID_ENCODE_JOB_PRIORITY)encode_priority_level;
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
m_EncodevideoSession = gslVidEncodeCreateSession(&m_videocontext, device_id, &data);
}
void
CALGSLContext::closeVideoEncodeSession(CALuint device_id)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
if (m_EncodevideoSession)
{
gslVidEncodeSessionDestroy(&m_videocontext, device_id, m_EncodevideoSession);
}
}
void
CALGSLContext::setState(CALEncodeSetState EncodeState, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeSetState(&m_videocontext, m_EncodevideoSession, (GSL_VID_ENCODE_STATE) EncodeState.encode_states);
}
void
CALGSLContext::getPictureConfig(CALEncodeGetPictureControlConfig *pPictureControlConfig, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeGetPictureControlConfig(&m_videocontext, m_EncodevideoSession, (GSL_VID_CONFIG_PICTURE_CONTROL *) pPictureControlConfig);
}
void
CALGSLContext::getRateControlConfig(CALEncodeGetRateControlConfig *pRateControConfig, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeGetRateControlConfig(&m_videocontext, m_EncodevideoSession, (GSL_VID_CONFIG_RATE_CONTROL *) pRateControConfig);
}
void
CALGSLContext::getMotionEstimationConfig(CALEncodeGetMotionEstimationConfig *pMotionEstimationConfig, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeGetMotionEstimationConfig(&m_videocontext, m_EncodevideoSession, (GSL_VID_CONFIG_MOTION_ESTIMATION *) pMotionEstimationConfig);
}
void
CALGSLContext::getRDOConfig(CALEncodeGetRDOControlConfig *pRODConfig, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeGetRDOControlConfig(&m_videocontext, m_EncodevideoSession, (GSL_VID_CONFIG_RDO *) pRODConfig);
}
void
CALGSLContext::SendConfig(CALuint num_of_config_buffers, CAL_VID_CONFIG *pConfigBuffers, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeSendConfig(&m_videocontext, m_EncodevideoSession, num_of_config_buffers, (GSL_VID_CONFIG *)pConfigBuffers);
}
void
CALGSLContext::EncodeePicture(GpuEvent& event,
CALuint num_of_encode_task_input_buffer,
CAL_VID_BUFFER_DESCRIPTION *encode_task_input_buffer_list,
void* picture_parameter,
CALuint *pTaskID,
gslMemObject input_NV12_surface,
CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
eventBegin(MainEngine);
eventEnd(MainEngine, event);
gslVidEncodeePicture(
&m_videocontext,
m_EncodevideoSession,
num_of_encode_task_input_buffer,
(GSL_VID_BUFFER_DESCRIPTION *)encode_task_input_buffer_list,
picture_parameter,
pTaskID,
input_NV12_surface);
}
void
CALGSLContext::QueryTaskDescription(CALuint num_of_task_description_request,
CALuint *num_of_task_description_return,
CAL_VID_OUTPUT_DESCRIPTION *task_description_list,
CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeeQueryTaskDescription(
&m_videocontext,
m_EncodevideoSession,
num_of_task_description_request,
num_of_task_description_return,
(GSL_VID_OUTPUT_DESCRIPTION *)task_description_list);
}
void
CALGSLContext::ReleaseOutputResource(CALuint taskID, CALuint flags)
{
m_videocontext.m_gsCtx = m_cs;
m_videocontext.VideoEngine_name = GSL_VID_CONTEXT_VIDEO_VCE;
gslVidEncodeeReleaseOutputResource(&m_videocontext, m_EncodevideoSession, taskID);
}
bool
CALGSLContext::moduleLoad(CALimage image,
gslProgramObject* func, gslMemObject* constants, CALUavMask* uavMask)
{
AMUabiMultiBinary binary;
AMUabiEncoding encoding;
amuABIMultiBinaryCreate(&binary);
amuABIMultiBinaryUnpack(binary, image);
CALuint machine, type, count = 0;
amuABIMultiBinaryGetEncodingCount(&count, binary);
bool binaryFound = false;
for (CALuint i = 0; i < count; ++i)
{
if (amuABIMultiBinaryGetEncoding(&encoding, binary, i) &&
amuABIEncodingGetSignature(&machine, &type, encoding) &&
(machine == dev()->getElfMachine()) && (type == (CALuint)ED_ATI_CAL_TYPE_COMPUTE))
{
binaryFound = true;
break;
}
}
if (!binaryFound)
{
amuABIMultiBinaryDestroy(binary);
return false;
}
*func = createProgramObject((CALuint)ED_ATI_CAL_TYPE_COMPUTE);
if (*func == 0)
{
amuABIMultiBinaryDestroy(binary);
return false;
}
(*func)->programStringARB(m_cs, GSL_COMPUTE_PROGRAM, GSL_PROGRAM_FORMAT_ELF_BINARY, 0, image);
amuABIEncodingGetUAVMask(uavMask, encoding);
// Setup the loop constants from the ELF binary int const area.
CALuint numConstants = 0;
CALuint maxPhysical = 0;
AMUabiLiteralConst* litConsts;
CALuint litConstsCount = 0;
amuABIEncodingGetLitConsts(&litConstsCount, &litConsts, encoding);
for (CALuint i = 0; i < litConstsCount; ++i)
{
if (litConsts[i].type == AMU_ABI_INT32)
{
maxPhysical = std::max(maxPhysical, litConsts[i].addr);
++numConstants;
}
}
if (numConstants > 0)
{
*constants = createConstants(++maxPhysical);
CALuint* ptr = static_cast<CALuint*>((*constants)->map(m_cs, GSL_MAP_READ_WRITE));
assert(ptr != 0 && "gslMapMemImage failed!");
for (CALuint i = 0; i < litConstsCount; ++i)
{
if (litConsts[i].type == AMU_ABI_INT32)
{
ptr[litConsts[i].addr] = litConsts[i].value.int32[0];
}
}
(*constants)->unmap(m_cs);
}
amuABIMultiBinaryDestroy(binary);
// FIXME Until we get everything right, return an error or we'll hang the HW
return true;
}
gslQueryObject CALGSLContext::createThreadTrace(void) const
{
return m_cs->createQuery(GSL_SHADER_TRACE_BYTES_WRITTEN);
}
void CALGSLContext::destroyThreadTrace(gslQueryObject threadTrace) const
{
m_cs->destroyQuery(threadTrace);
}
gslShaderTraceBufferObject
CALGSLContext::CreateThreadTraceBuffer(void) const
{
return m_cs->createShaderTraceBuffer();
}
void
CALGSLContext::DestroyThreadTraceBuffer(gslShaderTraceBufferObject shaderTraceBuffer,uint32 index) const
{
shaderTraceBuffer->attachMemObject(m_cs, NULL, 0, 0, 0, index);
m_cs->destroyShaderTraceBuffer(shaderTraceBuffer);
}
void
CALGSLContext::configMemThreadTrace(gslShaderTraceBufferObject shaderTraceBuffer,gslMemObject memObject,uint32 index,uint32 size) const
{
shaderTraceBuffer->attachMemObject(m_cs, memObject, 0, 0, size,index);
}
void
CALGSLContext::beginThreadTrace(gslQueryObject threadTrace,gslQueryObject threadTrace2, gslQueryTarget target,uint32 seNum,CALthreadTraceConfig& threadTraceConfig) const
{
// This should never be called for UVD/VCE Sync queries in case it is
// Please correctly pass on EngineMask else queries may be messed up
assert(target != GSL_UVD_SYNC_ATI || target != GSL_VCE_SYNC_ATI);
const gslErrorCode ec = threadTrace->BeginQuery(m_cs, target, 0);
assert(ec == GSL_NO_ERROR);
for (uint32 index = 0;index < seNum;++index) {
m_rs->enableShaderTrace(m_cs,index,true);
m_rs->setShaderTraceComputeUnit(index,threadTraceConfig.cu);
m_rs->setShaderTraceShaderArray(index,threadTraceConfig.sh);
m_rs->setShaderTraceSIMDMask(index,threadTraceConfig.simd_mask);
m_rs->setShaderTraceVmIdMask(index,threadTraceConfig.vm_id_mask);
m_rs->setShaderTraceTokenMask(index,threadTraceConfig.token_mask);
m_rs->setShaderTraceRegisterMask(index,threadTraceConfig.reg_mask);
m_rs->setShaderTraceIssueMask(index,threadTraceConfig.inst_mask);
m_rs->setShaderTraceRandomSeed(index,threadTraceConfig.random_seed);
if (threadTraceConfig.is_user_data) {
m_rs->setShaderTraceUserData(index,threadTraceConfig.user_data);
}
m_rs->setShaderTraceCaptureMode(index,threadTraceConfig.capture_mode);
if (threadTraceConfig.is_wrapped) {
m_rs->setShaderTraceWrap(index,true);
}
}
}
void
CALGSLContext::endThreadTrace(gslQueryObject threadTrace,uint32 seNum) const
{
for (uint32 index = 0;index < seNum;++index) {
m_rs->enableShaderTrace(m_cs,index,false);
}
threadTrace->EndQuery(m_cs, 0);
}
void
CALGSLContext::pauseThreadTrace(uint32 seNum) const
{
for (uint32 index = 0;index < seNum;++index) {
m_rs->setShaderTraceIsPaused(m_cs,index,(bool32)true);
}
}
void
CALGSLContext::resumeThreadTrace(uint32 seNum) const
{
for (uint32 index = 0;index < seNum;++index) {
m_rs->setShaderTraceIsPaused(m_cs,index,(bool32)false);
}
}
uint32
CALGSLContext::getThreadTraceQueryRes(gslQueryObject threadTrace) const
{
CALuint64 tempResult;
threadTrace->GetResult(m_cs, &tempResult);
// Make sure that we aren't losing any data from the cast
assert(tempResult < UINT_MAX);
return (uint32)tempResult;
}
void
CALGSLContext::writeTimer(bool sdma, const gslMemObject mem, uint32 offset) const
{
m_rs->writeTimer(m_cs, sdma, mem, offset);
}
void
CALGSLContext::runAqlDispatch(GpuEvent& event, const void* aqlPacket,
const gslMemObject* mems, uint32 numMems, gslMemObject scratch, const void* cpuKernelCode, uint64 hsaQueueVA)
{
eventBegin(MainEngine);
m_cs->AqlDispatch(aqlPacket, mems, numMems, scratch, cpuKernelCode, hsaQueueVA);
eventEnd(MainEngine, event);
}
mcaddr
CALGSLContext::virtualQueueDispatcherStart()
{
return m_cs->VirtualQueueDispatcherStart();
}
void
CALGSLContext::virtualQueueDispatcherEnd(GpuEvent& event, const gslMemObject* mems,
uint32 numMems, mcaddr signal, mcaddr loopStart)
{
eventBegin(MainEngine);
m_cs->VirtualQueueDispatcherEnd(mems, numMems, signal, loopStart);
eventEnd(MainEngine, event);
}
void
CALGSLContext::virtualQueueHandshake(GpuEvent& event, const gslMemObject mem, mcaddr parentState,
uint32 newStateValue, mcaddr parentChildCounter, mcaddr signal, bool dedicatedQueue)
2014-07-04 16:17:05 -04:00
{
eventBegin(MainEngine);
m_cs->VirtualQueueHandshake(mem, parentState, newStateValue, parentChildCounter, signal, dedicatedQueue);
2014-07-04 16:17:05 -04:00
eventEnd(MainEngine, event);
}