diff --git a/driver/stateChange.c b/driver/stateChange.c index a1a3b7d..054a35f 100644 --- a/driver/stateChange.c +++ b/driver/stateChange.c @@ -503,10 +503,6 @@ VKAPI_ATTR void VKAPI_CALL RPIFUNC(vkCmdClearColorImage)( //TODO ranges support - assert(imageLayout == VK_IMAGE_LAYOUT_GENERAL || - imageLayout == VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR || - imageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - assert(commandBuffer->state == CMDBUF_STATE_RECORDING); assert(_queueFamilyProperties[commandBuffer->cp->queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT || _queueFamilyProperties[commandBuffer->cp->queueFamilyIndex].queueFlags & VK_QUEUE_COMPUTE_BIT); @@ -581,7 +577,70 @@ VKAPI_ATTR void VKAPI_CALL RPIFUNC(vkCmdClearDepthStencilImage)( assert(image); assert(pDepthStencil); - //TODO + //TODO this should only flag an image for clearing. This can only be called outside a renderpass + //actual clearing would only happen: + // -if image is rendered to (insert clear before first draw call) + // -if the image is bound for sampling (submit a CL with a clear) + // -if a command buffer is submitted without any rendering (insert clear) + // -etc. + //we shouldn't clear an image if noone uses it + + //TODO ranges support + + assert(commandBuffer->state == CMDBUF_STATE_RECORDING); + assert(_queueFamilyProperties[commandBuffer->cp->queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT || _queueFamilyProperties[commandBuffer->cp->queueFamilyIndex].queueFlags & VK_QUEUE_COMPUTE_BIT); + + _image* i = image; + + assert(i->usageBits & VK_IMAGE_USAGE_TRANSFER_DST_BIT); + + { //Simplest case: just submit a job to clear the image + clFit(commandBuffer, &commandBuffer->binCl, sizeof(CLMarker)); + clInsertNewCLMarker(&commandBuffer->binCl, &commandBuffer->handlesCl, &commandBuffer->shaderRecCl, commandBuffer->shaderRecCount, &commandBuffer->uniformsCl); + + ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->writeDepthStencilImage = i; + + //insert reloc for render target + clFit(commandBuffer, &commandBuffer->handlesCl, 4); + clGetHandleIndex(&commandBuffer->handlesCl, ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->handlesBufOffset + commandBuffer->handlesCl.offset, ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->handlesSize, i->boundMem->bo); + + clFit(commandBuffer, &commandBuffer->binCl, V3D21_TILE_BINNING_MODE_CONFIGURATION_length); + clInsertTileBinningModeConfiguration(&commandBuffer->binCl, + 0, //double buffer in non ms mode + 0, //tile allocation block size + 0, //tile allocation initial block size + 0, //auto initialize tile state data array + 0, //64 bit color mode + i->samples > 1, //msaa + i->width, i->height, + 0, //tile state data array address + 0, //tile allocation memory size + 0); //tile allocation memory address + + //START_TILE_BINNING resets the statechange counters in the hardware, + //which are what is used when a primitive is binned to a tile to + //figure out what new state packets need to be written to that tile's + //command list. + clFit(commandBuffer, &commandBuffer->binCl, V3D21_START_TILE_BINNING_length); + clInsertStartTileBinning(&commandBuffer->binCl); + + //Increment the semaphore indicating that binning is done and + //unblocking the render thread. Note that this doesn't act + //until the FLUSH completes. + //The FLUSH caps all of our bin lists with a + //VC4_PACKET_RETURN. + clFit(commandBuffer, &commandBuffer->binCl, V3D21_INCREMENT_SEMAPHORE_length); + clInsertIncrementSemaphore(&commandBuffer->binCl); + clFit(commandBuffer, &commandBuffer->binCl, V3D21_FLUSH_length); + clInsertFlush(&commandBuffer->binCl); + + ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->clearDepth = (uint32_t)(pDepthStencil->depth * 0xffffff) & 0xffffff; + ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->clearStencil = pDepthStencil->stencil & 0xff; + ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR; + + ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->width = i->width; + ((CLMarker*)getCPAptrFromOffset(commandBuffer->binCl.CPA, commandBuffer->binCl.currMarkerOffset))->height = i->height; + } PROFILEEND(RPIFUNC(vkCmdClearDepthStencilImage)); } diff --git a/test/clearTest/clearTest.cpp b/test/clearTest/clearTest.cpp index a95826a..514320f 100644 --- a/test/clearTest/clearTest.cpp +++ b/test/clearTest/clearTest.cpp @@ -589,7 +589,7 @@ void createDepthBuffer() imageCreateInfo.arrayLayers = 1; imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + imageCreateInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageCreateInfo.extent = { swapChainExtent.width, swapChainExtent.height, 1 }; @@ -801,6 +801,17 @@ void recordCommandBuffers() renderPassInfo.framebuffer = fbs[i]; + VkClearDepthStencilValue dsv; + dsv.depth = 1.0f; + dsv.stencil = 0xff; + VkImageSubresourceRange srr; + srr.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + srr.baseArrayLayer = 0; + srr.baseMipLevel = 0; + srr.layerCount = 1; + srr.levelCount = 1; + vkCmdClearDepthStencilImage(presentCommandBuffers[i], depthImage, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, &dsv, 1, &srr); + vkCmdBeginRenderPass(presentCommandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(presentCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); @@ -839,7 +850,7 @@ void recordCommandBuffers() clearRect.rect.offset.y = 972; clearRect.rect.extent.width = 144; clearRect.rect.extent.height = 108; - vkCmdClearAttachments(presentCommandBuffers[i], 2, clearAttachment, 1, &clearRect); + //vkCmdClearAttachments(presentCommandBuffers[i], 2, clearAttachment, 1, &clearRect); vkCmdSetDepthBias(presentCommandBuffers[i], 0.0, 0.0, 0.0); @@ -939,7 +950,7 @@ void CreateRenderPass() VkAttachmentDescription attachDesc[2]; attachDesc[0] = {}; attachDesc[0].format = swapchainFormat.format; // - attachDesc[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachDesc[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachDesc[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachDesc[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachDesc[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -949,7 +960,7 @@ void CreateRenderPass() attachDesc[1] = {}; attachDesc[1].format = depthFormat; - attachDesc[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachDesc[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachDesc[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachDesc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachDesc[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;