4599bd0d4a
ECR #304775 - Device enqueuing - Add L2 cache flush after the scheduler execution. Although CP has to work with L2 cache, it seems some functionality relies on direct memory access and without explicit L2 flush CP can pick old values in the template. Affected files ... ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#324 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gslbe/src/rt/GSLContext.cpp#61 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gslbe/src/rt/GSLContext.h#35 edit
1299 líneas
40 KiB
C++
1299 líneas
40 KiB
C++
#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
|
|
{
|
|
m_cs->FlushCUCaches(flushL2);
|
|
}
|
|
|
|
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)
|
|
{
|
|
eventBegin(MainEngine);
|
|
m_cs->VirtualQueueHandshake(mem, parentState, newStateValue, parentChildCounter, signal);
|
|
eventEnd(MainEngine, event);
|
|
}
|