1
0
mirror of https://github.com/Yours3lf/rpi-vk-driver.git synced 2024-11-29 11:24:14 +01:00
rpi-vk-driver/driver/common.c
2019-09-30 01:13:55 +01:00

943 lines
22 KiB
C

#include "common.h"
#include "kernel/vc4_packet.h"
#include "brcm/cle/v3d_decoder.h"
#include "brcm/clif/clif_dump.h"
uint32_t getFormatBpp(VkFormat f)
{
switch(f)
{
case VK_FORMAT_R64G64B64_UINT: //padded to 256
case VK_FORMAT_R64G64B64_SINT:
case VK_FORMAT_R64G64B64_SFLOAT:
case VK_FORMAT_R64G64B64A64_UINT:
case VK_FORMAT_R64G64B64A64_SINT:
case VK_FORMAT_R64G64B64A64_SFLOAT:
return 256;
case VK_FORMAT_R32G32B32_UINT: //padded to 128
case VK_FORMAT_R32G32B32_SINT:
case VK_FORMAT_R32G32B32_SFLOAT:
case VK_FORMAT_R32G32B32A32_UINT:
case VK_FORMAT_R32G32B32A32_SINT:
case VK_FORMAT_R32G32B32A32_SFLOAT:
case VK_FORMAT_R64G64_UINT:
case VK_FORMAT_R64G64_SINT:
case VK_FORMAT_R64G64_SFLOAT:
return 128;
case VK_FORMAT_R16G16B16A16_SFLOAT:
case VK_FORMAT_R16G16B16_UNORM: //padded to 64
case VK_FORMAT_R16G16B16_SNORM: //padded to 64
case VK_FORMAT_R16G16B16_USCALED: //padded to 64
case VK_FORMAT_R16G16B16_SSCALED: //padded to 64
case VK_FORMAT_R16G16B16_UINT: //padded to 64
case VK_FORMAT_R16G16B16_SINT: //padded to 64
case VK_FORMAT_R16G16B16_SFLOAT: //padded to 64
case VK_FORMAT_R16G16B16A16_UNORM:
case VK_FORMAT_R16G16B16A16_SNORM:
case VK_FORMAT_R16G16B16A16_USCALED:
case VK_FORMAT_R16G16B16A16_SSCALED:
case VK_FORMAT_R16G16B16A16_UINT:
case VK_FORMAT_R16G16B16A16_SINT:
case VK_FORMAT_R32G32_UINT:
case VK_FORMAT_R32G32_SINT:
case VK_FORMAT_R32G32_SFLOAT:
case VK_FORMAT_R64_UINT:
case VK_FORMAT_R64_SINT:
case VK_FORMAT_R64_SFLOAT:
case VK_FORMAT_D32_SFLOAT_S8_UINT: //padded to 64
return 64;
case VK_FORMAT_R8G8B8_UNORM: //padded to 32
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R32_UINT:
case VK_FORMAT_R8G8B8A8_UINT:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_R8G8B8_SNORM: //padded to 32
case VK_FORMAT_R8G8B8_USCALED: //padded to 32
case VK_FORMAT_R8G8B8_SSCALED: //padded to 32
case VK_FORMAT_R8G8B8_UINT: //padded to 32
case VK_FORMAT_R8G8B8_SINT: //padded to 32
case VK_FORMAT_R8G8B8_SRGB: //padded to 32
case VK_FORMAT_B8G8R8_UNORM: //padded to 32
case VK_FORMAT_B8G8R8_SNORM: //padded to 32
case VK_FORMAT_B8G8R8_USCALED: //padded to 32
case VK_FORMAT_B8G8R8_SSCALED: //padded to 32
case VK_FORMAT_B8G8R8_UINT: //padded to 32
case VK_FORMAT_B8G8R8_SINT: //padded to 32
case VK_FORMAT_B8G8R8_SRGB: //padded to 32
case VK_FORMAT_R8G8B8A8_SNORM:
case VK_FORMAT_R8G8B8A8_USCALED:
case VK_FORMAT_R8G8B8A8_SSCALED:
case VK_FORMAT_R8G8B8A8_SINT:
case VK_FORMAT_R8G8B8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_B8G8R8A8_SNORM:
case VK_FORMAT_B8G8R8A8_USCALED:
case VK_FORMAT_B8G8R8A8_SSCALED:
case VK_FORMAT_B8G8R8A8_UINT:
case VK_FORMAT_B8G8R8A8_SINT:
case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
case VK_FORMAT_A2R10G10B10_UINT_PACK32:
case VK_FORMAT_A2R10G10B10_SINT_PACK32:
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
case VK_FORMAT_A2B10G10R10_UINT_PACK32:
case VK_FORMAT_A2B10G10R10_SINT_PACK32:
case VK_FORMAT_R16G16_UNORM:
case VK_FORMAT_R16G16_SNORM:
case VK_FORMAT_R16G16_USCALED:
case VK_FORMAT_R16G16_SSCALED:
case VK_FORMAT_R16G16_UINT:
case VK_FORMAT_R16G16_SINT:
case VK_FORMAT_R16G16_SFLOAT:
case VK_FORMAT_R32_SINT:
case VK_FORMAT_R32_SFLOAT:
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D16_UNORM_S8_UINT: //padded to 32
case VK_FORMAT_D24_UNORM_S8_UINT:
return 32;
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
case VK_FORMAT_R5G6B5_UNORM_PACK16:
case VK_FORMAT_R8G8_UNORM:
case VK_FORMAT_R16_SFLOAT:
case VK_FORMAT_R16_SINT:
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
case VK_FORMAT_B5G6R5_UNORM_PACK16:
case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
case VK_FORMAT_R8G8_SNORM:
case VK_FORMAT_R8G8_USCALED:
case VK_FORMAT_R8G8_SSCALED:
case VK_FORMAT_R8G8_UINT:
case VK_FORMAT_R8G8_SINT:
case VK_FORMAT_R8G8_SRGB:
case VK_FORMAT_R16_UNORM:
case VK_FORMAT_R16_SNORM:
case VK_FORMAT_R16_USCALED:
case VK_FORMAT_R16_SSCALED:
case VK_FORMAT_R16_UINT:
return 16;
case VK_FORMAT_R8_UNORM:
case VK_FORMAT_R8_SINT:
case VK_FORMAT_S8_UINT:
case VK_FORMAT_R4G4_UNORM_PACK8:
case VK_FORMAT_R8_SNORM:
case VK_FORMAT_R8_USCALED:
case VK_FORMAT_R8_SSCALED:
case VK_FORMAT_R8_UINT:
case VK_FORMAT_R8_SRGB:
case VK_FORMAT_UNDEFINED: //TODO
return 8;
default://
fprintf(stderr, "format %i\n", f);
assert(!"Unknown format.");
return 0;
}
}
uint32_t packVec4IntoABGR8(const float rgba[4])
{
uint8_t r, g, b, a;
r = rgba[0] * 255.0;
g = rgba[1] * 255.0;
b = rgba[2] * 255.0;
a = rgba[3] * 255.0;
uint32_t res = 0 |
(a << 24) |
(b << 16) |
(g << 8) |
(r << 0);
return res;
}
int findInstanceExtension(char* name)
{
for(int c = 0; c < numInstanceExtensions; ++c)
{
if(strcmp(instanceExtensions[c].extensionName, name) == 0)
{
return c;
}
}
return -1;
}
int findDeviceExtension(char* name)
{
for(int c = 0; c < numDeviceExtensions; ++c)
{
if(strcmp(deviceExtensions[c].extensionName, name) == 0)
{
return c;
}
}
return -1;
}
//Textures in T format:
//formed out of 4KB tiles, which have 1KB subtiles (see page 105 in VC4 arch guide)
//1KB subtiles have 512b microtiles.
//Width/height of the 512b microtiles is the following:
// 64bpp: 2x4
// 32bpp: 4x4
// 16bpp: 8x4
// 8bpp: 8x8
// 4bpp: 16x8
// 1bpp: 32x16
//Therefore width/height of 1KB subtiles is the following:
// 64bpp: 8x16
// 32bpp: 16x16
// 16bpp: 32x16
// 8bpp: 32x32
// 4bpp: 64x32
// 1bpp: 128x64
//Finally width/height of the 4KB tiles:
// 64bpp: 16x32
// 32bpp: 32x32
// 16bpp: 64x32
// 8bpp: 64x64
// 4bpp: 128x64
// 1bpp: 256x128
void getPaddedTextureDimensionsT(uint32_t width, uint32_t height, uint32_t bpp, uint32_t* paddedWidth, uint32_t* paddedHeight)
{
assert(paddedWidth);
assert(paddedHeight);
uint32_t tileW = 0;
uint32_t tileH = 0;
switch(bpp)
{
case 256:
{
tileW = 8;
tileH = 16;
break;
}
case 128:
{
tileW = 16;
tileH = 16;
break;
}
case 64:
{
tileW = 16;
tileH = 32;
break;
}
case 32:
{
tileW = 32;
tileH = 32;
break;
}
case 16:
{
tileW = 64;
tileH = 32;
break;
}
case 8:
{
tileW = 64;
tileH = 64;
break;
}
case 4:
{
tileW = 128;
tileH = 64;
break;
}
case 1:
{
tileW = 256;
tileH = 128;
break;
}
default:
{
fprintf(stderr, "bpp: %i\n", bpp);
assert(!"Unsupported texture bpp.");
}
}
*paddedWidth = ((tileW - (width % tileW)) % tileW) + width;
*paddedHeight = ((tileH - (height % tileH)) % tileH) + height;
}
/*static inline void util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
{
ubyte r = 0;
ubyte g = 0;
ubyte b = 0;
ubyte a = 0;
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) <= 8) {
r = float_to_ubyte(rgba[0]);
g = float_to_ubyte(rgba[1]);
b = float_to_ubyte(rgba[2]);
a = float_to_ubyte(rgba[3]);
}
switch (format) {
case PIPE_FORMAT_ABGR8888_UNORM:
{
uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | a;
}
return;
case PIPE_FORMAT_XBGR8888_UNORM:
{
uc->ui[0] = (r << 24) | (g << 16) | (b << 8) | 0xff;
}
return;
case PIPE_FORMAT_BGRA8888_UNORM:
{
uc->ui[0] = (a << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_BGRX8888_UNORM:
{
uc->ui[0] = (0xffu << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_ARGB8888_UNORM:
{
uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | a;
}
return;
case PIPE_FORMAT_XRGB8888_UNORM:
{
uc->ui[0] = (b << 24) | (g << 16) | (r << 8) | 0xff;
}
return;
case PIPE_FORMAT_B5G6R5_UNORM:
{
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
case PIPE_FORMAT_B5G5R5X1_UNORM:
{
uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
}
return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
}
return;
case PIPE_FORMAT_B4G4R4A4_UNORM:
{
uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
}
return;
case PIPE_FORMAT_A8_UNORM:
{
uc->ub = a;
}
return;
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_I8_UNORM:
{
uc->ub = r;
}
return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
uc->f[0] = rgba[0];
uc->f[1] = rgba[1];
uc->f[2] = rgba[2];
uc->f[3] = rgba[3];
}
return;
case PIPE_FORMAT_R32G32B32_FLOAT:
{
uc->f[0] = rgba[0];
uc->f[1] = rgba[1];
uc->f[2] = rgba[2];
}
return;
default:
util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1);
}
}*/
int isDepthStencilFormat(VkFormat format)
{
switch(format)
{
case VK_FORMAT_D16_UNORM:
case VK_FORMAT_X8_D24_UNORM_PACK32:
case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_S8_UINT:
case VK_FORMAT_D16_UNORM_S8_UINT:
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return 1;
default:
return 0;
}
}
uint32_t getCompareOp(VkCompareOp op)
{
switch(op)
{
case VK_COMPARE_OP_NEVER:
return V3D_COMPARE_FUNC_NEVER;
case VK_COMPARE_OP_LESS:
return V3D_COMPARE_FUNC_LESS;
case VK_COMPARE_OP_EQUAL:
return V3D_COMPARE_FUNC_EQUAL;
case VK_COMPARE_OP_LESS_OR_EQUAL:
return V3D_COMPARE_FUNC_LEQUAL;
case VK_COMPARE_OP_GREATER:
return V3D_COMPARE_FUNC_GREATER;
case VK_COMPARE_OP_NOT_EQUAL:
return V3D_COMPARE_FUNC_NOTEQUAL;
case VK_COMPARE_OP_GREATER_OR_EQUAL:
return V3D_COMPARE_FUNC_GEQUAL;
case VK_COMPARE_OP_ALWAYS:
return V3D_COMPARE_FUNC_ALWAYS;
default:
return -1;
}
}
uint32_t getStencilOp(VkStencilOp op)
{
switch(op)
{
case VK_STENCIL_OP_ZERO:
return 0;
case VK_STENCIL_OP_KEEP:
return 1;
case VK_STENCIL_OP_REPLACE:
return 2;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
return 3;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
return 4;
case VK_STENCIL_OP_INVERT:
return 5;
case VK_STENCIL_OP_INCREMENT_AND_WRAP:
return 6;
case VK_STENCIL_OP_DECREMENT_AND_WRAP:
return 7;
default:
return -1;
};
}
uint32_t getTopology(VkPrimitiveTopology topology)
{
switch(topology)
{
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return 0;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return 1;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
return 2;
default:
return -1;
}
}
uint32_t getPrimitiveMode(VkPrimitiveTopology topology)
{
switch(topology)
{
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return V3D_PRIM_POINTS;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
return V3D_PRIM_LINES;
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return V3D_PRIM_LINE_STRIP;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
return V3D_PRIM_TRIANGLES;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
return V3D_PRIM_TRIANGLE_STRIP;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
return V3D_PRIM_TRIANGLE_FAN;
default:
return -1;
}
}
uint32_t getFormatByteSize(VkFormat format)
{
switch(format)
{
case VK_FORMAT_R16_SFLOAT:
return 2;
case VK_FORMAT_R16G16_SFLOAT:
return 4;
case VK_FORMAT_R16G16B16_SFLOAT:
return 6;
case VK_FORMAT_R16G16B16A16_SFLOAT:
return 8;
case VK_FORMAT_R32_SFLOAT:
return 4;
case VK_FORMAT_R32G32_SFLOAT:
return 8;
case VK_FORMAT_R32G32B32_SFLOAT:
return 12;
case VK_FORMAT_R32G32B32A32_SFLOAT:
return 16;
default:
return -1;
}
}
uint32_t ulog2(uint32_t v)
{
uint32_t ret = 0;
while(v >>= 1) ret++;
return ret;
}
void clFit(VkCommandBuffer cb, ControlList* cl, uint32_t commandSize)
{
if(!clHasEnoughSpace(cl, commandSize))
{
uint32_t currSize = cl->nextFreeByte - cl->buffer;
cl->buffer = consecutivePoolReAllocate(&cb->cp->cpa, cl->buffer, cl->numBlocks); assert(cl->buffer);
cl->nextFreeByte = cl->buffer + currSize;
}
}
void clDump(void* cl, uint32_t size)
{
struct v3d_device_info devinfo = {
/* While the driver supports V3D 2.1 and 2.6, we haven't split
* off a 2.6 XML yet (there are a couple of fields different
* in render target formatting)
*/
.ver = 21,
};
struct v3d_spec* spec = v3d_spec_load(&devinfo);
struct clif_dump *clif = clif_dump_init(&devinfo, stderr, true);
uint32_t offset = 0, hw_offset = 0;
uint8_t *p = cl;
while (offset < size) {
struct v3d_group *inst = v3d_spec_find_instruction(spec, p);
uint8_t header = *p;
uint32_t length;
if (inst == NULL) {
fprintf(stderr, "0x%08x 0x%08x: Unknown packet 0x%02x (%d)!\n",
offset, hw_offset, header, header);
return;
}
length = v3d_group_get_length(inst);
printf("0x%08x 0x%08x: 0x%02x %s\n",
offset, hw_offset, header, v3d_group_get_name(inst));
v3d_print_group(clif, inst, offset, p);
switch (header) {
case VC4_PACKET_HALT:
case VC4_PACKET_STORE_MS_TILE_BUFFER_AND_EOF:
return;
default:
break;
}
offset += length;
if (header != VC4_PACKET_GEM_HANDLES)
hw_offset += length;
p += length;
}
clif_dump_destroy(clif);
}
void encodeTextureUniform(uint32_t* params, //array of 4 uint32_t
//num mip levels - 1
uint8_t numMipLevels,
///0: rgba8
///1: rgbx8 (a=1)
///2: rgba4
///3: rgb5a1
///4: r5g6b5 (a=1)
///5: luminance (8 bit, a=1)
//6: alpha (8 bit, rga=0)
///7: lumalpha
///8: etc1
///9: s16f (blending supported)
///10: s8 (blending supported)
///11: s16 (point sampling only)
//12: bw1 (1 bit black and white)
//13: a4
//14: a1
///15: rgba16f
//16: rgba8r (raster format = not in T format)
///17: yuyv422r (raster format = not in T format, yuyv)
uint8_t textureDataType,
uint8_t isCubeMap,
uint32_t cubemapStride, //in multiples of 4k bytes
uint32_t textureBasePtr, //in multiples of 4k bytes
//0 = 2048
uint16_t height,
uint16_t width,
//0: linear
//1: nearest
//2: near_mip_near
//3: near_mip_lin
//4: lin_mip_near
//5: lin_mip_lin
uint8_t minFilter,
//0: linear
//1: nearest
uint8_t magFilter,
//0: repeat
//1: clamp
//2: mirror
//3: border
uint8_t wrapT,
uint8_t wrapS,
uint8_t noAutoLod //disable automatic LOD, use bias only
)
{
assert(params);
params[0] = 0
| numMipLevels & 0xf
| (uint32_t)(textureDataType & 0xf) << 4
| (uint32_t)(isCubeMap ? 1 : 0) << 9
| (uint32_t)(textureBasePtr & 0xfffff) << 12;
params[1] = 0
| wrapS & 0x3
| (uint32_t)(wrapT & 0x3) << 2
| (uint32_t)(minFilter & 0x7) << 4
| (uint32_t)(magFilter & 0x1) << 7
| (uint32_t)(width & 0x7ff) << 8
| (uint32_t)(height & 0x7ff) << 20
| (uint32_t)((textureDataType & 0x10) >> 4) << 31;
params[2] = 0
| noAutoLod & 0x1
| (uint32_t)(cubemapStride & 0x3ffff) << 12
| (uint32_t)(isCubeMap ? 1 : 0) << 30;
//TODO
//child images
params[3] = 0;
}
void encodeStencilValue(uint32_t *values, uint32_t* numValues, VkStencilOpState front, VkStencilOpState back, uint8_t stencilTestEnable)
{
assert(values);
assert(numValues);
if(!stencilTestEnable)
{
front.compareOp = back.compareOp = VK_COMPARE_OP_ALWAYS;
}
if(front.compareMask == back.compareMask &&
front.compareOp == back.compareOp &&
front.depthFailOp == back.depthFailOp &&
front.failOp == back.failOp &&
front.passOp == back.passOp &&
front.reference == back.reference &&
front.writeMask == back.writeMask
)
{
*numValues = 1;
values[0] = 0
| (front.compareMask & 0xff)
| (front.reference & 0xff) << 0x8
| (getCompareOp(front.compareOp) & 0x7) << 16
| (getStencilOp(front.failOp) & 0x7) << 19
| (getStencilOp(front.passOp) & 0x7) << 22
| (getStencilOp(front.depthFailOp) & 0x7) << 25
| 3 << 30; //front and back
switch(front.writeMask)
{
case 0x1:
values[0] |= 0 << 28;
break;
case 0x3:
values[0] |= 1 << 28;
break;
case 0xf:
values[0] |= 2 << 28;
break;
case 0xff:
values[0] |= 3 << 28;
break;
default:
values[1] = 0
| front.writeMask & 0xff
| (front.writeMask & 0xff) << 8;
*numValues = 2;
break;
};
}
else
{
*numValues = 2;
values[0] = 0
| (front.compareMask & 0xff)
| (front.reference & 0xff) << 0x8
| (getCompareOp(front.compareOp) & 0x7) << 16
| (getStencilOp(front.failOp) & 0x7) << 19
| (getStencilOp(front.passOp) & 0x7) << 22
| (getStencilOp(front.depthFailOp) & 0x7) << 25
| 1 << 30; //front
values[1] = 0
| (back.compareMask & 0xff)
| (back.reference & 0xff) << 0x8
| (getCompareOp(back.compareOp) & 0x7) << 16
| (getStencilOp(back.failOp) & 0x7) << 19
| (getStencilOp(back.passOp) & 0x7) << 22
| (getStencilOp(back.depthFailOp) & 0x7) << 25
| 2 << 30; //front
if((front.writeMask == 0x1 ||
front.writeMask == 0x3 ||
front.writeMask == 0xf ||
front.writeMask == 0xff) &&
(back.writeMask == 0x1 ||
back.writeMask == 0x3 ||
back.writeMask == 0xf ||
back.writeMask == 0xff))
{
switch(front.writeMask)
{
case 0x1:
values[0] |= 0 << 28;
break;
case 0x3:
values[0] |= 1 << 28;
break;
case 0xf:
values[0] |= 2 << 28;
break;
case 0xff:
values[0] |= 3 << 28;
break;
};
switch(back.writeMask)
{
case 0x1:
values[1] |= 0 << 28;
break;
case 0x3:
values[1] |= 1 << 28;
break;
case 0xf:
values[1] |= 2 << 28;
break;
case 0xff:
values[1] |= 3 << 28;
break;
};
}
else
{
values[2] = 0
| front.writeMask & 0xff
| (back.writeMask & 0xff) << 8;
*numValues = 3;
}
}
}
uint8_t getTextureDataType(VkFormat format)
{
switch(format)
{
case VK_FORMAT_R16G16B16A16_SFLOAT:
return 15; //rgba16f
case VK_FORMAT_R8G8B8_UNORM:
return 1; //rgbx8 (a=1)
case VK_FORMAT_R8G8B8A8_UNORM:
return 0; //rgba8
case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
return 3; //rgb5a1
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
return 2; //rgba4
case VK_FORMAT_R5G6B5_UNORM_PACK16:
return 4; //r5g6b5 (a=1)
case VK_FORMAT_R8G8_UNORM:
return 7; //lumalpha
case VK_FORMAT_R16_SFLOAT:
return 9; //s16f (blending supported)
case VK_FORMAT_R16_SINT:
return 11; //s16 (point sampling only)
case VK_FORMAT_R8_UNORM:
return 5; //luminance (8 bit, a=1)
case VK_FORMAT_R8_SINT:
return 10; //s8 (blending supported)
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
return 8; //etc1
case VK_FORMAT_G8B8G8R8_422_UNORM:
return 17; //yuyv422r (raster format = not in T format, yuyv)
case VK_FORMAT_UNDEFINED: //TODO
return -1;
default://
fprintf(stderr, "format %i\n", format);
assert(!"Unsupported format.");
return -1;
}
}
uint8_t getMinFilterType(VkFilter minFilter, VkSamplerMipmapMode mipFilter, float maxLod)
{
if(minFilter == VK_FILTER_NEAREST)
{
if(maxLod < 0.0001f)
{
return 1; //no mip filtering
}
if(mipFilter == VK_SAMPLER_MIPMAP_MODE_NEAREST)
{
return 2;
}
else if(mipFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
{
return 3;
}
}
else if(minFilter == VK_FILTER_LINEAR)
{
if(maxLod < 0.0001f)
{
return 0; //no mip filtering
}
if(mipFilter == VK_SAMPLER_MIPMAP_MODE_NEAREST)
{
return 4;
}
else if(mipFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
{
return 5;
}
}
}
uint8_t getWrapMode(VkSamplerAddressMode mode)
{
if(mode == VK_SAMPLER_ADDRESS_MODE_REPEAT)
{
return 0;
}
else if(mode == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
{
return 1;
}
else if(mode == VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT)
{
return 2;
}
else if(mode == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)
{
return 3;
}
else
{
fprintf(stderr, "wrap mode: %i\n", mode);
assert(!"Unsupported wrap mode.");
return -1;
}
}
uint32_t getRenderTargetFormatVC4(VkFormat format)
{
//TODO dithered BGR565
switch(format)
{
case VK_FORMAT_R16G16B16A16_SFLOAT: //HDR mode set in tile binning config mode, so just return a valid format
case VK_FORMAT_R8G8B8A8_UNORM:
return VC4_RENDER_CONFIG_FORMAT_RGBA8888;
case VK_FORMAT_B5G6R5_UNORM_PACK16:
return VC4_RENDER_CONFIG_FORMAT_BGR565;
default:
fprintf(stderr, "rendertarget format: %i\n", format);
assert(!"Unsupported render target format");
return -1;
}
}
////////////////////////////////////////////////////
////////////////////////////////////////////////////
/// just so we can return a function pointer
////////////////////////////////////////////////////
////////////////////////////////////////////////////
VKAPI_ATTR void VKAPI_CALL rpi_vkGetPhysicalDeviceExternalBufferProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
VkExternalBufferProperties* pExternalBufferProperties)
{
UNSUPPORTED(rpi_vkGetPhysicalDeviceExternalBufferProperties);
}
VKAPI_ATTR void VKAPI_CALL rpi_vkGetPhysicalDeviceExternalFenceProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
VkExternalFenceProperties* pExternalFenceProperties)
{
UNSUPPORTED(rpi_vkGetPhysicalDeviceExternalFenceProperties);
}
VKAPI_ATTR void VKAPI_CALL rpi_vkGetPhysicalDeviceExternalSemaphoreProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
VkExternalSemaphoreProperties* pExternalSemaphoreProperties)
{
UNSUPPORTED(rpi_vkGetPhysicalDeviceExternalSemaphoreProperties);
}
VKAPI_ATTR void VKAPI_CALL rpi_vkGetDeviceGroupPeerMemoryFeatures(
VkDevice device,
uint32_t heapIndex,
uint32_t localDeviceIndex,
uint32_t remoteDeviceIndex,
VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
{
UNSUPPORTED(rpi_vkGetDeviceGroupPeerMemoryFeatures);
}