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/draw.c

262 lines
9.8 KiB
C

#include "common.h"
#include "kernel/vc4_packet.h"
/*
* https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#vkCmdDraw
*/
void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)
{
assert(commandBuffer);
_commandBuffer* cb = commandBuffer;
_renderpass* rp = cb->renderpass;
_framebuffer* fb = cb->fbo;
//TODO handle multiple attachments etc.
_image* i = fb->attachmentViews[rp->subpasses[cb->currentSubpass].pColorAttachments[0].attachment].image;
//stuff needed to submit a draw call:
//Tile Binning Mode Configuration
clFit(commandBuffer, &commandBuffer->binCl, V3D21_TILE_BINNING_MODE_CONFIGURATION_length);
clInsertTileBinningModeConfiguration(&commandBuffer->binCl,
0, 0, 0, 0,
getFormatBpp(i->format) == 64, //64 bit color mode
i->samples > 1, //msaa
i->width, i->height, 0, 0, 0);
//Start Tile Binning
clFit(commandBuffer, &commandBuffer->binCl, V3D21_START_TILE_BINNING_length);
clInsertStartTileBinning(&commandBuffer->binCl);
//Primitive List Format
clFit(commandBuffer, &commandBuffer->binCl, V3D21_PRIMITIVE_LIST_FORMAT_length);
clInsertPrimitiveListFormat(&commandBuffer->binCl,
1, //16 bit
getTopology(cb->graphicsPipeline->topology)); //tris
//Clip Window
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIP_WINDOW_length);
clInsertClipWindow(&commandBuffer->binCl, i->width, i->height, 0, 0);
//Configuration Bits
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CONFIGURATION_BITS_length);
clInsertConfigurationBits(&commandBuffer->binCl,
1, //TODO earlyz updates
0, //TODO earlyz enable
0, //TODO z updates
cb->graphicsPipeline->depthTestEnable ? getDepthCompareOp(cb->graphicsPipeline->depthCompareOp) : V3D_COMPARE_FUNC_ALWAYS, //depth compare func
0,
0,
0,
0,
0,
cb->graphicsPipeline->depthBiasEnable, //depth offset enable
cb->graphicsPipeline->frontFace == VK_FRONT_FACE_CLOCKWISE, //clockwise
!(cb->graphicsPipeline->cullMode & VK_CULL_MODE_BACK_BIT), //enable back facing primitives
!(cb->graphicsPipeline->cullMode & VK_CULL_MODE_FRONT_BIT)); //enable front facing primitives
//TODO Depth Offset
clFit(commandBuffer, &commandBuffer->binCl, V3D21_DEPTH_OFFSET_length);
clInsertDepthOffset(&commandBuffer->binCl, cb->graphicsPipeline->depthBiasConstantFactor, cb->graphicsPipeline->depthBiasSlopeFactor);
//Point size
clFit(commandBuffer, &commandBuffer->binCl, V3D21_POINT_SIZE_length);
clInsertPointSize(&commandBuffer->binCl, 1.0f);
//Line width
clFit(commandBuffer, &commandBuffer->binCl, V3D21_LINE_WIDTH_length);
clInsertLineWidth(&commandBuffer->binCl, cb->graphicsPipeline->lineWidth);
//TODO why flipped???
//Clipper XY Scaling
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIPPER_XY_SCALING_length);
clInsertClipperXYScaling(&commandBuffer->binCl, (float)(i->width) * 0.5f * 16.0f, -1.0f * (float)(i->height) * 0.5f * 16.0f);
//TODO how is this calculated?
//seems to go from -1.0 .. 1.0 to 0.0 .. 1.0
//eg. x * 0.5 + 0.5
//cb->graphicsPipeline->minDepthBounds;
//Clipper Z Scale and Offset
clFit(commandBuffer, &commandBuffer->binCl, V3D21_CLIPPER_Z_SCALE_AND_OFFSET_length);
clInsertClipperZScaleOffset(&commandBuffer->binCl, 0.5f, 0.5f);
//Viewport Offset
clFit(commandBuffer, &commandBuffer->binCl, V3D21_VIEWPORT_OFFSET_length);
clInsertViewPortOffset(&commandBuffer->binCl, i->width >> 1, i->height >> 1);
//TODO?
//Flat Shade Flags
clFit(commandBuffer, &commandBuffer->binCl, V3D21_FLAT_SHADE_FLAGS_length);
clInsertFlatShadeFlags(&commandBuffer->binCl, 0);
//TODO how to get address?
//GL Shader State
clFit(commandBuffer, &commandBuffer->binCl, V3D21_GL_SHADER_STATE_length);
clInsertShaderState(&commandBuffer->binCl, 0, 0, cb->graphicsPipeline->vertexAttributeDescriptionCount);
//Vertex Array Primitives (draw call)
clFit(commandBuffer, &commandBuffer->binCl, V3D21_VERTEX_ARRAY_PRIMITIVES_length);
clInsertVertexArrayPrimitives(&commandBuffer->binCl, firstVertex, vertexCount, getPrimitiveMode(cb->graphicsPipeline->topology));
//emit shader record
ControlListAddress fragCode = {
.handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)]))->bos[VK_RPI_ASSEMBLY_TYPE_FRAGMENT],
.offset = 0,
};
ControlListAddress vertCode = {
.handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]))->bos[VK_RPI_ASSEMBLY_TYPE_VERTEX],
.offset = 0,
};
ControlListAddress coordCode = {
.handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]))->bos[VK_RPI_ASSEMBLY_TYPE_COORDINATE],
.offset = 0,
};
//TODO
commandBuffer->shaderRecCount++;
clFit(commandBuffer, &commandBuffer->shaderRecCl, V3D21_SHADER_RECORD_length);
ControlList relocCl = commandBuffer->shaderRecCl;
//TODO number of attribs
//3 is the number of type of possible shaders
int numAttribs = 1;
for(int c = 0; c < (3 + numAttribs)*4; ++c)
{
clInsertNop(&commandBuffer->shaderRecCl);
}
clInsertShaderRecord(&commandBuffer->shaderRecCl,
&relocCl,
&commandBuffer->handlesCl,
1, //TODO single threaded?
0, //point size included in shaded vertex data?
1, //enable clipping?
0, //fragment number of unused uniforms?
0, //fragment number of varyings?
0, //fragment uniform address?
fragCode, //fragment code address
0, //vertex number of unused uniforms?
1, //TODO vertex attribute array select bits
8, //TODO vertex total attribute size
0, //vertex uniform address
vertCode, //vertex shader code address
0, //coordinate number of unused uniforms?
1, //TODO coordinate attribute array select bits
8, //TODO coordinate total attribute size
0, //coordinate uniform address
coordCode //coordinate shader code address
);
ControlListAddress vertexBuffer = {
.handle = cb->vertexBuffers[cb->graphicsPipeline->vertexAttributeDescriptions[0].location]->boundMem->bo,
.offset = 0,
};
clFit(commandBuffer, &commandBuffer->shaderRecCl, V3D21_ATTRIBUTE_RECORD_length);
clInsertAttributeRecord(&commandBuffer->shaderRecCl,
&relocCl,
&commandBuffer->handlesCl,
vertexBuffer, //address
getFormatByteSize(cb->graphicsPipeline->vertexAttributeDescriptions[0].format),
cb->graphicsPipeline->vertexBindingDescriptions[0].stride, //stride
0, //TODO vertex vpm offset
0 //TODO coordinte vpm offset
);
//insert vertex buffer handle
//clFit(commandBuffer, &commandBuffer->handlesCl, 4);
//uint32_t vboIdx = clGetHandleIndex(&commandBuffer->handlesCl, vertexBuffer.handle);
//insert shader code handles
//clFit(commandBuffer, &commandBuffer->handlesCl, 4);
//uint32_t vertIdx = clGetHandleIndex(&commandBuffer->handlesCl, vertCode.handle);
//clFit(commandBuffer, &commandBuffer->handlesCl, 4);
//uint32_t coordIdx = clGetHandleIndex(&commandBuffer->handlesCl, coordCode.handle);
//clFit(commandBuffer, &commandBuffer->handlesCl, 4);
//uint32_t fragIdx = clGetHandleIndex(&commandBuffer->handlesCl, fragCode.handle);
//Insert image handle index
clFit(commandBuffer, &commandBuffer->handlesCl, 4);
uint32_t imageIdx = clGetHandleIndex(&commandBuffer->handlesCl, i->boundMem->bo);
//fill out submit cl fields
commandBuffer->submitCl.color_write.hindex = imageIdx;
commandBuffer->submitCl.color_write.offset = 0;
commandBuffer->submitCl.color_write.flags = 0;
//TODO format
commandBuffer->submitCl.color_write.bits =
VC4_SET_FIELD(VC4_RENDER_CONFIG_FORMAT_RGBA8888, VC4_RENDER_CONFIG_FORMAT) |
VC4_SET_FIELD(i->tiling, VC4_RENDER_CONFIG_MEMORY_FORMAT);
commandBuffer->submitCl.clear_color[0] = i->clearColor[0];
commandBuffer->submitCl.clear_color[1] = i->clearColor[1];
commandBuffer->submitCl.min_x_tile = 0;
commandBuffer->submitCl.min_y_tile = 0;
uint32_t tileSizeW = 64;
uint32_t tileSizeH = 64;
if(i->samples > 1)
{
tileSizeW >>= 1;
tileSizeH >>= 1;
}
if(getFormatBpp(i->format) == 64)
{
tileSizeH >>= 1;
}
uint32_t widthInTiles = divRoundUp(i->width, tileSizeW);
uint32_t heightInTiles = divRoundUp(i->height, tileSizeH);
commandBuffer->submitCl.max_x_tile = widthInTiles - 1;
commandBuffer->submitCl.max_y_tile = heightInTiles - 1;
commandBuffer->submitCl.width = i->width;
commandBuffer->submitCl.height = i->height;
commandBuffer->submitCl.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR;
commandBuffer->submitCl.clear_z = 0; //TODO
commandBuffer->submitCl.clear_s = 0;
//write uniforms
//TODO
/**
//FS
uniform count : 1
tex sample count : 0
uniform constant : 4291579008
//VS
uniform count : 4
tex sample count : 0
uniform constant : 1065353216
uniform viewport xscale : 15360.000000
uniform viewport yscale : -8640.000000
uniform viewport zoffset : 0.500000
//CS (same as VS)
uniform count : 4
tex sample count : 0
uniform viewport yscale : -8640.000000
uniform constant : 1065353216
uniform viewport xscale : 15360.000000
uniform viewport zoffset : 0.500000
/**/
clFit(commandBuffer, &commandBuffer->uniformsCl, 4*(1+4+4));
//FS
clInsertUniformConstant(&commandBuffer->uniformsCl, 4291579008);
//VS
clInsertUniformConstant(&commandBuffer->uniformsCl, 1065353216);
clInsertUniformXYScale(&commandBuffer->uniformsCl, (float)(i->width) * 0.5f * 16.0f);
clInsertUniformXYScale(&commandBuffer->uniformsCl, -1.0f * (float)(i->height) * 0.5f * 16.0f);
clInsertUniformZOffset(&commandBuffer->uniformsCl, 0.5f);
//CS
clInsertUniformXYScale(&commandBuffer->uniformsCl, -1.0f * (float)(i->height) * 0.5f * 16.0f);
clInsertUniformConstant(&commandBuffer->uniformsCl, 1065353216);
clInsertUniformXYScale(&commandBuffer->uniformsCl, (float)(i->width) * 0.5f * 16.0f);
clInsertUniformZOffset(&commandBuffer->uniformsCl, 0.5f);
}