1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2024-12-10 22:24:14 +01:00
rpi-vk-driver/driver/ControlListUtil.c

639 lines
25 KiB
C

#include "ControlListUtil.h"
#include "ConsecutivePoolAllocator.h"
#include <stdint.h>
uint32_t divRoundUp(uint32_t n, uint32_t d)
{
return (((n) + (d) - 1) / (d));
}
//move bits to offset, mask rest to 0
uint32_t moveBits(uint32_t d, uint32_t bits, uint32_t offset)
{
return (d << offset) & (~(~0u << bits) << offset);
}
uint32_t clHasEnoughSpace(ControlList* cl, uint32_t size)
{
assert(cl);
assert(cl->CPA);
uint32_t currSize = cl->nextFreeByteOffset - cl->offset;
if((currSize + size) <= (cl->numBlocks * cl->blockSize))
{
return 1; //fits!
}
else
{
return 0; //need to reallocate
}
}
void clInit(ControlList* cl, void* CPA, uint32_t offset, uint32_t blockSize)
{
assert(cl);
assert(CPA);
cl->offset = offset;
cl->numBlocks = 1;
cl->blockSize = blockSize;
cl->nextFreeByteOffset = offset;
cl->currMarkerOffset = -1;
cl->CPA = CPA;
}
void clInsertNewCLMarker(ControlList* cl,
ControlList* handlesCL,
ControlList* shaderRecCL,
uint32_t shaderRecCount,
ControlList* uniformsCL)
{
//to be inserted when you'd insert tile binning mode config
assert(cl);
assert(cl->CPA);
assert(handlesCL);
assert(shaderRecCL);
assert(uniformsCL);
CLMarker marker = {0};
marker.memGuard = 0xDDDDDDDD;
marker.nextMarkerOffset = -1;
//close current marker
if(cl->currMarkerOffset != ~0u && !((CLMarker*)getCPAptrFromOffset(cl->CPA, cl->currMarkerOffset))->size)
{
clCloseCurrentMarker(cl, handlesCL, shaderRecCL, shaderRecCount, uniformsCL);
}
//if this is not the first marker
if(cl->currMarkerOffset != ~0u)
{
CLMarker* currMarker = getCPAptrFromOffset(cl->CPA, cl->currMarkerOffset);
marker.handlesBufOffset = currMarker->handlesBufOffset + currMarker->handlesSize;
marker.shaderRecBufOffset = currMarker->shaderRecBufOffset + currMarker->shaderRecSize;
marker.uniformsBufOffset = currMarker->uniformsBufOffset + currMarker->uniformsSize;
marker.shaderRecCount = currMarker->shaderRecCount; //initialize with previous marker's data
}
*(CLMarker*)getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset) = marker;
if(cl->currMarkerOffset != ~0u)
{
((CLMarker*)getCPAptrFromOffset(cl->CPA, cl->currMarkerOffset))->nextMarkerOffset = (cl->nextFreeByteOffset - cl->offset);
}
cl->currMarkerOffset = cl->nextFreeByteOffset;
cl->nextFreeByteOffset += sizeof(CLMarker);
}
void clCloseCurrentMarker(ControlList* cl, ControlList* handlesCL, ControlList* shaderRecCL, uint32_t shaderRecCount, ControlList* uniformsCL)
{
assert(cl);
assert(cl->CPA);
assert(handlesCL);
assert(shaderRecCL);
assert(uniformsCL);
CLMarker* currMarker = getCPAptrFromOffset(cl->CPA, cl->currMarkerOffset);
currMarker->size = cl->nextFreeByteOffset - (cl->currMarkerOffset + sizeof(CLMarker));
currMarker->handlesSize = handlesCL->nextFreeByteOffset - (currMarker->handlesBufOffset + handlesCL->offset);
currMarker->shaderRecSize = shaderRecCL->nextFreeByteOffset - (currMarker->shaderRecBufOffset + shaderRecCL->offset);
currMarker->uniformsSize = uniformsCL->nextFreeByteOffset - (currMarker->uniformsBufOffset + uniformsCL->offset);
currMarker->shaderRecCount = shaderRecCount - currMarker->shaderRecCount; //update shader rec count to reflect added shader recs
}
void clInsertData(ControlList* cl, uint32_t size, void* data)
{
assert(cl);
assert(cl->CPA);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), data, size);
cl->nextFreeByteOffset += size;
}
void clInsertUniformConstant(ControlList* cl, uint32_t data)
{
assert(cl);
assert(cl->CPA);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &data, sizeof(uint32_t));
cl->nextFreeByteOffset += 4;
}
void clInsertUniformXYScale(ControlList* cl, float data)
{
assert(cl);
assert(cl->CPA);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &data, sizeof(float));
cl->nextFreeByteOffset += 4;
}
void clInsertUniformZOffset(ControlList* cl, float data)
{
assert(cl);
assert(cl->CPA);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &data, sizeof(float));
cl->nextFreeByteOffset += 4;
}
void clInsertHalt(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_HALT_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertNop(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_NOP_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertFlush(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_FLUSH_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertFlushAllState(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_FLUSH_ALL_STATE_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertStartTileBinning(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_START_TILE_BINNING_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertIncrementSemaphore(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_INCREMENT_SEMAPHORE_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertWaitOnSemaphore(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_WAIT_ON_SEMAPHORE_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
//input: 2 cls (cl, handles cl)
void clInsertBranch(ControlList* cls, ControlListAddress address)
{
assert(cls);
assert(cls->CPA);
uint8_t opCode = V3D21_BRANCH_opcode;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cls->nextFreeByteOffset++;
//TODO is this correct?
//clEmitShaderRelocation(cls, &address);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &address.offset, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
}
//input: 2 cls (cl, handles cl)
void clInsertBranchToSubList(ControlList* cls, ControlListAddress address)
{
assert(cls);
assert(cls->CPA);
uint8_t opCode = V3D21_BRANCH_TO_SUB_LIST_opcode;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cls->nextFreeByteOffset++;
//TODO is this correct?
//clEmitShaderRelocation(cls, &address);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &address.offset, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
}
void clInsertReturnFromSubList(ControlList* cl)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_RETURN_FROM_SUB_LIST_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertIndexedPrimitiveList(ControlList* cl,
uint32_t maxIndex,
uint32_t indicesAddress,
uint32_t length,
uint32_t indexType, //0/1: 8 or 16 bit
enum V3D21_Primitive primitiveMode)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_INDEXED_PRIMITIVE_LIST_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint8_t tmp = moveBits(indexType, 4, 4) | moveBits(primitiveMode, 4, 0);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &length, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &indicesAddress, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &maxIndex, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
}
void clInsertVertexArrayPrimitives(ControlList* cl,
uint32_t firstVertexIndex,
uint32_t length,
enum V3D21_Primitive primitiveMode)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_VERTEX_ARRAY_PRIMITIVES_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint8_t tmp = moveBits(primitiveMode, 8, 0);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &length, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &firstVertexIndex, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
}
void clInsertShaderState(ControlList* cl,
uint32_t address,
uint32_t extendedShaderRecord, //0/1: true/false
uint32_t numberOfAttributeArrays)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_GL_SHADER_STATE_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint32_t tmp = moveBits(address, 28, 4) |
moveBits(extendedShaderRecord, 1, 3) |
moveBits(numberOfAttributeArrays, 3, 0);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint32_t));
cl->nextFreeByteOffset += 4;
}
void clInsertConfigurationBits(ControlList* cl,
uint32_t earlyZUpdatesEnable, //0/1
uint32_t earlyZEnable, //0/1
uint32_t zUpdatesEnable, //0/1
enum V3D21_Compare_Function depthTestFunction,
uint32_t coverageReadMode, //0/1 clear/leave as is
uint32_t coveragePipeSelect, //0/1
uint32_t coverageUpdateMode, //0/1/2/3 nonzero, odd, or, zero
uint32_t coverageReadType, //0/1 4*8bit, 16 bit mask
uint32_t rasterizerOversampleMode, //0/1/2 none, 4x, 16x
uint32_t enableDepthOffset, //0/1
uint32_t clockwisePrimitives, //0/1
uint32_t enableReverseFacingPrimitive, //0/1
uint32_t enableForwardFacingPrimitive) //0/1
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_CONFIGURATION_BITS_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint32_t tmp = moveBits(enableForwardFacingPrimitive, 1, 0) |
moveBits(enableReverseFacingPrimitive, 1, 1) |
moveBits(clockwisePrimitives, 1, 2) |
moveBits(enableDepthOffset, 1, 3) |
moveBits(coverageReadType, 1, 5) |
moveBits(rasterizerOversampleMode, 2, 6) |
moveBits(coveragePipeSelect, 1, 8) |
moveBits(coverageUpdateMode, 2, 9) |
moveBits(coverageReadMode, 1, 11) |
moveBits(depthTestFunction, 3, 12) |
moveBits(zUpdatesEnable, 1, 15) |
moveBits(earlyZEnable, 1, 16) |
moveBits(earlyZUpdatesEnable, 1, 17);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint32_t));
cl->nextFreeByteOffset += 3;
}
void clInsertFlatShadeFlags(ControlList* cl,
uint32_t flags)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_FLAT_SHADE_FLAGS_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &flags, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
}
void clInsertPointSize(ControlList* cl,
float size)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_POINT_SIZE_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &size, sizeof(float)); cl->nextFreeByteOffset += 4;
}
void clInsertLineWidth(ControlList* cl,
float width)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_LINE_WIDTH_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &width, sizeof(float)); cl->nextFreeByteOffset += 4;
}
void clInsertRHTXBoundary(ControlList* cl,
uint32_t boundary) //sint16
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_RHT_X_BOUNDARY_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint16_t tmp = moveBits(boundary, 16, 0);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint16_t)); cl->nextFreeByteOffset += 2;
}
uint32_t f32_to_f187(float f32)
{
uint32_t bits = *(uint32_t*)&f32;
return bits >> 16;
}
void clInsertDepthOffset(ControlList* cl,
float units,
float factor)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_DEPTH_OFFSET_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint32_t tmp = moveBits(f32_to_f187(factor), 16, 0) | moveBits(f32_to_f187(units), 16, 16);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
}
void clInsertClipWindow(ControlList* cl,
uint32_t width, //uint16
uint32_t height, //uint16
uint32_t bottomPixelCoord, //uint16
uint32_t leftPixelCoord) //uint16
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_CLIP_WINDOW_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint32_t tmp = moveBits(leftPixelCoord, 16, 0) | moveBits(bottomPixelCoord, 16, 16);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
tmp = moveBits(width, 16, 0) | moveBits(height, 16, 16);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
}
uint16_t get16bitSignedFixedNumber(float x)
{
int32_t integerPart = roundf(x * 16.0f);
return integerPart & 0xffff;
}
//viewport centre x/y coordinate
void clInsertViewPortOffset(ControlList* cl,
float x,
float y
)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_VIEWPORT_OFFSET_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
//expects 16 bit signed fixed point number with 4 fractional bits
uint16_t tmp = get16bitSignedFixedNumber(x);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint16_t)); cl->nextFreeByteOffset += 2;
tmp = get16bitSignedFixedNumber(y);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint16_t)); cl->nextFreeByteOffset += 2;
}
void clInsertZMinMaxClippingPlanes(ControlList* cl,
float minZw,
float maxZw
)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_Z_MIN_AND_MAX_CLIPPING_PLANES_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &minZw, sizeof(float)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &maxZw, sizeof(float)); cl->nextFreeByteOffset += 4;
}
void clInsertClipperXYScaling(ControlList* cl,
float width, //half width in 1/16 of pixel
float height //half height in 1/16 of pixel
)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_CLIPPER_XY_SCALING_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &width, sizeof(float)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &height, sizeof(float)); cl->nextFreeByteOffset += 4;
}
void clInsertClipperZScaleOffset(ControlList* cl,
float zOffset, //zc to zs
float zScale //zc to zs
)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_CLIPPER_Z_SCALE_AND_OFFSET_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &zScale, sizeof(float)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &zOffset, sizeof(float)); cl->nextFreeByteOffset += 4;
}
void clInsertTileBinningModeConfiguration(ControlList* cl,
uint32_t doubleBufferInNonMsMode, //0/1
uint32_t tileAllocationBlockSize, //0/1/2/3 32/64/128/256 bytes
uint32_t tileAllocationInitialBlockSize, //0/1/2/3 32/64/128/256 bytes
uint32_t autoInitializeTileStateDataArray, //0/1
uint32_t tileBuffer64BitColorDepth, //0/1
uint32_t multisampleMode4x, //0/1
uint32_t widthInPixels,
uint32_t heightInPixels,
uint32_t tileStateDataArrayAddress, //16 byte aligned, size of 48 bytes * num tiles
uint32_t tileAllocationMemorySize,
uint32_t tileAllocationMemoryAddress
)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_TILE_BINNING_MODE_CONFIGURATION_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tileAllocationMemoryAddress, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tileAllocationMemorySize, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tileStateDataArrayAddress, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
uint32_t tileSizeW = 64;
uint32_t tileSizeH = 64;
if(multisampleMode4x)
{
tileSizeW >>= 1;
tileSizeH >>= 1;
}
if(tileBuffer64BitColorDepth)
{
tileSizeH >>= 1;
}
uint8_t widthInTiles = divRoundUp(widthInPixels, tileSizeW);
uint8_t heightInTiles = divRoundUp(heightInPixels, tileSizeH);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &widthInTiles, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &heightInTiles, sizeof(uint8_t)); cl->nextFreeByteOffset++;
uint8_t tmp = moveBits(multisampleMode4x, 1, 0) |
moveBits(tileBuffer64BitColorDepth, 1, 1) |
moveBits(autoInitializeTileStateDataArray, 1, 2) |
moveBits(tileAllocationInitialBlockSize, 2, 3) |
moveBits(tileAllocationBlockSize, 2, 5) |
moveBits(doubleBufferInNonMsMode, 1, 7);
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &tmp, sizeof(uint8_t));
cl->nextFreeByteOffset++;
}
void clInsertGEMRelocations(ControlList* cl,
uint32_t buffer0,
uint32_t buffer1)
{
assert(cl);
assert(cl->CPA);
uint8_t opCode = V3D21_GEM_RELOCATIONS_opcode;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &opCode, sizeof(uint8_t)); cl->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &buffer0, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cl->CPA, cl->nextFreeByteOffset), &buffer1, sizeof(uint32_t)); cl->nextFreeByteOffset += 4;
}
//input: 2 cls (cl, handles cl)
void clInsertShaderRecord(ControlList* cls,
ControlList* relocCl,
ControlList* handlesCl,
uint32_t handlesOffset,
uint32_t handlesSize,
uint32_t fragmentShaderIsSingleThreaded, //0/1
uint32_t pointSizeIncludedInShadedVertexData, //0/1
uint32_t enableClipping, //0/1
uint32_t fragmentNumberOfUsedUniforms,
uint32_t fragmentNumberOfVaryings,
uint32_t fragmentUniformsAddress,
ControlListAddress fragmentCodeAddress,
uint32_t vertexNumberOfUsedUniforms,
uint32_t vertexAttributeArraySelectBits,
uint32_t vertexTotalAttributesSize,
uint32_t vertexUniformsAddress,
ControlListAddress vertexCodeAddress,
uint32_t coordinateNumberOfUsedUniforms,
uint32_t coordinateAttributeArraySelectBits,
uint32_t coordinateTotalAttributesSize,
uint32_t coordinateUniformsAddress,
ControlListAddress coordinateCodeAddress)
{
assert(cls);
assert(cls->CPA);
uint8_t tmp = moveBits(fragmentShaderIsSingleThreaded, 1, 0) |
moveBits(pointSizeIncludedInShadedVertexData, 1, 1) |
moveBits(enableClipping, 1, 2);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &tmp, sizeof(uint8_t));
cls->nextFreeByteOffset++;
tmp = 0;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &tmp, sizeof(uint8_t)); cls->nextFreeByteOffset++;
uint16_t tmp2 = moveBits(fragmentNumberOfUsedUniforms, 16, 0);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &tmp2, sizeof(uint16_t)); cls->nextFreeByteOffset++;
memcpy(&tmp, getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), sizeof(uint8_t));
tmp |= fragmentNumberOfVaryings;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &tmp, sizeof(uint8_t)); cls->nextFreeByteOffset++;
clEmitShaderRelocation(relocCl, handlesCl, handlesOffset, handlesSize, &fragmentCodeAddress);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &fragmentCodeAddress.offset, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &fragmentUniformsAddress, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
tmp2 = moveBits(vertexNumberOfUsedUniforms, 16, 0);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &tmp2, sizeof(uint16_t)); cls->nextFreeByteOffset += 2;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &vertexAttributeArraySelectBits, sizeof(uint8_t)); cls->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &vertexTotalAttributesSize, sizeof(uint8_t)); cls->nextFreeByteOffset++;
clEmitShaderRelocation(relocCl, handlesCl, handlesOffset, handlesSize, &vertexCodeAddress);
//wtf??? --> shader code will always have an offset of 0 so this is fine
uint32_t offset = moveBits(vertexCodeAddress.offset, 32, 0) | moveBits(vertexUniformsAddress, 32, 0);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &offset, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
cls->nextFreeByteOffset += 4;
tmp2 = moveBits(coordinateNumberOfUsedUniforms, 16, 0);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &tmp2, sizeof(uint16_t)); cls->nextFreeByteOffset += 2;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &coordinateAttributeArraySelectBits, sizeof(uint8_t)); cls->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &coordinateTotalAttributesSize, sizeof(uint8_t)); cls->nextFreeByteOffset++;
clEmitShaderRelocation(relocCl, handlesCl, handlesOffset, handlesSize, &coordinateCodeAddress);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &coordinateCodeAddress.offset, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &coordinateUniformsAddress, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
}
//input: 2 cls (cl, handles cl)
void clInsertAttributeRecord(ControlList* cls,
ControlList* relocCl,
ControlList* handlesCl,
uint32_t handlesOffset, uint32_t handlesSize,
ControlListAddress address,
uint32_t sizeBytes,
uint32_t stride,
uint32_t vertexVPMOffset,
uint32_t coordinateVPMOffset)
{
assert(cls);
assert(cls->CPA);
uint32_t sizeBytesMinusOne = sizeBytes - 1;
clEmitShaderRelocation(relocCl, handlesCl, handlesOffset, handlesSize, &address);
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &address.offset, sizeof(uint32_t)); cls->nextFreeByteOffset += 4;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &sizeBytesMinusOne, sizeof(uint8_t)); cls->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &stride, sizeof(uint8_t)); cls->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &vertexVPMOffset, sizeof(uint8_t)); cls->nextFreeByteOffset++;
memcpy(getCPAptrFromOffset(cls->CPA, cls->nextFreeByteOffset), &coordinateVPMOffset, sizeof(uint8_t)); cls->nextFreeByteOffset++;
}
uint32_t clGetHandleIndex(ControlList* handlesCl, uint32_t handlesOffset, uint32_t handlesSize, uint32_t handle)
{
uint32_t c = 0;
//if curr marker is closed already we need to work with the stored size
uint32_t numHandles = (handlesSize ? handlesSize : (handlesCl->nextFreeByteOffset - handlesOffset)) / 4;
for(; c < numHandles; ++c)
{
if(((uint32_t*)getCPAptrFromOffset(handlesCl->CPA, handlesOffset))[c] == handle)
{
//found
return c;
}
}
//write handle to handles cl
memcpy(getCPAptrFromOffset(handlesCl->CPA, handlesCl->nextFreeByteOffset), &handle, sizeof(uint32_t));
handlesCl->nextFreeByteOffset += 4;
assert(handlesCl->nextFreeByteOffset < handlesCl->offset + handlesCl->blockSize * handlesCl->numBlocks);
return c;
}
//input: 2 cls (cl + handles cl)
inline void clEmitShaderRelocation(ControlList* relocCl, ControlList* handlesCl, uint32_t handlesOffset, uint32_t handlesSize, const ControlListAddress* address)
{
assert(relocCl);
assert(relocCl->CPA);
assert(handlesCl);
assert(handlesCl->CPA);
assert(address);
assert(address->handle);
//store offset within handles in cl
uint32_t idx = clGetHandleIndex(handlesCl, handlesOffset, handlesSize, address->handle);
memcpy(getCPAptrFromOffset(relocCl->CPA, relocCl->nextFreeByteOffset), &idx, sizeof(uint32_t));
relocCl->nextFreeByteOffset += 4;
}
inline void clDummyRelocation(ControlList* relocCl, const ControlListAddress* address)
{}