| /* |
| * Copyright © 2019 Red Hat. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| * IN THE SOFTWARE. |
| */ |
| |
| #include "lvp_private.h" |
| #include "pipe/p_context.h" |
| |
| static VkResult lvp_create_cmd_buffer( |
| struct lvp_device * device, |
| struct lvp_cmd_pool * pool, |
| VkCommandBufferLevel level, |
| VkCommandBuffer* pCommandBuffer) |
| { |
| struct lvp_cmd_buffer *cmd_buffer; |
| |
| cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8, |
| VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); |
| if (cmd_buffer == NULL) |
| return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); |
| |
| vk_object_base_init(&device->vk, &cmd_buffer->base, |
| VK_OBJECT_TYPE_COMMAND_BUFFER); |
| cmd_buffer->device = device; |
| cmd_buffer->pool = pool; |
| list_inithead(&cmd_buffer->cmds); |
| cmd_buffer->status = LVP_CMD_BUFFER_STATUS_INITIAL; |
| if (pool) { |
| list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers); |
| } else { |
| /* Init the pool_link so we can safefly call list_del when we destroy |
| * the command buffer |
| */ |
| list_inithead(&cmd_buffer->pool_link); |
| } |
| *pCommandBuffer = lvp_cmd_buffer_to_handle(cmd_buffer); |
| |
| return VK_SUCCESS; |
| } |
| |
| static void |
| lvp_cmd_buffer_free_all_cmds(struct lvp_cmd_buffer *cmd_buffer) |
| { |
| struct lvp_cmd_buffer_entry *tmp, *cmd; |
| LIST_FOR_EACH_ENTRY_SAFE(cmd, tmp, &cmd_buffer->cmds, cmd_link) { |
| list_del(&cmd->cmd_link); |
| vk_free(&cmd_buffer->pool->alloc, cmd); |
| } |
| } |
| |
| static VkResult lvp_reset_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer) |
| { |
| lvp_cmd_buffer_free_all_cmds(cmd_buffer); |
| list_inithead(&cmd_buffer->cmds); |
| cmd_buffer->status = LVP_CMD_BUFFER_STATUS_INITIAL; |
| return VK_SUCCESS; |
| } |
| |
| VkResult lvp_AllocateCommandBuffers( |
| VkDevice _device, |
| const VkCommandBufferAllocateInfo* pAllocateInfo, |
| VkCommandBuffer* pCommandBuffers) |
| { |
| LVP_FROM_HANDLE(lvp_device, device, _device); |
| LVP_FROM_HANDLE(lvp_cmd_pool, pool, pAllocateInfo->commandPool); |
| |
| VkResult result = VK_SUCCESS; |
| uint32_t i; |
| |
| for (i = 0; i < pAllocateInfo->commandBufferCount; i++) { |
| |
| if (!list_is_empty(&pool->free_cmd_buffers)) { |
| struct lvp_cmd_buffer *cmd_buffer = list_first_entry(&pool->free_cmd_buffers, struct lvp_cmd_buffer, pool_link); |
| |
| list_del(&cmd_buffer->pool_link); |
| list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers); |
| |
| result = lvp_reset_cmd_buffer(cmd_buffer); |
| cmd_buffer->level = pAllocateInfo->level; |
| |
| pCommandBuffers[i] = lvp_cmd_buffer_to_handle(cmd_buffer); |
| } else { |
| result = lvp_create_cmd_buffer(device, pool, pAllocateInfo->level, |
| &pCommandBuffers[i]); |
| if (result != VK_SUCCESS) |
| break; |
| } |
| } |
| |
| if (result != VK_SUCCESS) { |
| lvp_FreeCommandBuffers(_device, pAllocateInfo->commandPool, |
| i, pCommandBuffers); |
| memset(pCommandBuffers, 0, |
| sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount); |
| } |
| |
| return result; |
| } |
| |
| static void |
| lvp_cmd_buffer_destroy(struct lvp_cmd_buffer *cmd_buffer) |
| { |
| lvp_cmd_buffer_free_all_cmds(cmd_buffer); |
| list_del(&cmd_buffer->pool_link); |
| vk_object_base_finish(&cmd_buffer->base); |
| vk_free(&cmd_buffer->pool->alloc, cmd_buffer); |
| } |
| |
| void lvp_FreeCommandBuffers( |
| VkDevice device, |
| VkCommandPool commandPool, |
| uint32_t commandBufferCount, |
| const VkCommandBuffer* pCommandBuffers) |
| { |
| for (uint32_t i = 0; i < commandBufferCount; i++) { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, pCommandBuffers[i]); |
| |
| if (cmd_buffer) { |
| if (cmd_buffer->pool) { |
| list_del(&cmd_buffer->pool_link); |
| list_addtail(&cmd_buffer->pool_link, &cmd_buffer->pool->free_cmd_buffers); |
| } else |
| lvp_cmd_buffer_destroy(cmd_buffer); |
| } |
| } |
| } |
| |
| VkResult lvp_ResetCommandBuffer( |
| VkCommandBuffer commandBuffer, |
| VkCommandBufferResetFlags flags) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| |
| return lvp_reset_cmd_buffer(cmd_buffer); |
| } |
| |
| VkResult lvp_BeginCommandBuffer( |
| VkCommandBuffer commandBuffer, |
| const VkCommandBufferBeginInfo* pBeginInfo) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| VkResult result; |
| if (cmd_buffer->status != LVP_CMD_BUFFER_STATUS_INITIAL) { |
| result = lvp_reset_cmd_buffer(cmd_buffer); |
| if (result != VK_SUCCESS) |
| return result; |
| } |
| cmd_buffer->status = LVP_CMD_BUFFER_STATUS_RECORDING; |
| return VK_SUCCESS; |
| } |
| |
| VkResult lvp_EndCommandBuffer( |
| VkCommandBuffer commandBuffer) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| cmd_buffer->status = LVP_CMD_BUFFER_STATUS_EXECUTABLE; |
| return VK_SUCCESS; |
| } |
| |
| VkResult lvp_CreateCommandPool( |
| VkDevice _device, |
| const VkCommandPoolCreateInfo* pCreateInfo, |
| const VkAllocationCallbacks* pAllocator, |
| VkCommandPool* pCmdPool) |
| { |
| LVP_FROM_HANDLE(lvp_device, device, _device); |
| struct lvp_cmd_pool *pool; |
| |
| pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8, |
| VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); |
| if (pool == NULL) |
| return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); |
| |
| vk_object_base_init(&device->vk, &pool->base, |
| VK_OBJECT_TYPE_COMMAND_POOL); |
| if (pAllocator) |
| pool->alloc = *pAllocator; |
| else |
| pool->alloc = device->vk.alloc; |
| |
| list_inithead(&pool->cmd_buffers); |
| list_inithead(&pool->free_cmd_buffers); |
| |
| *pCmdPool = lvp_cmd_pool_to_handle(pool); |
| |
| return VK_SUCCESS; |
| } |
| |
| void lvp_DestroyCommandPool( |
| VkDevice _device, |
| VkCommandPool commandPool, |
| const VkAllocationCallbacks* pAllocator) |
| { |
| LVP_FROM_HANDLE(lvp_device, device, _device); |
| LVP_FROM_HANDLE(lvp_cmd_pool, pool, commandPool); |
| |
| if (!pool) |
| return; |
| |
| list_for_each_entry_safe(struct lvp_cmd_buffer, cmd_buffer, |
| &pool->cmd_buffers, pool_link) { |
| lvp_cmd_buffer_destroy(cmd_buffer); |
| } |
| |
| list_for_each_entry_safe(struct lvp_cmd_buffer, cmd_buffer, |
| &pool->free_cmd_buffers, pool_link) { |
| lvp_cmd_buffer_destroy(cmd_buffer); |
| } |
| |
| vk_object_base_finish(&pool->base); |
| vk_free2(&device->vk.alloc, pAllocator, pool); |
| } |
| |
| VkResult lvp_ResetCommandPool( |
| VkDevice device, |
| VkCommandPool commandPool, |
| VkCommandPoolResetFlags flags) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_pool, pool, commandPool); |
| VkResult result; |
| |
| list_for_each_entry(struct lvp_cmd_buffer, cmd_buffer, |
| &pool->cmd_buffers, pool_link) { |
| result = lvp_reset_cmd_buffer(cmd_buffer); |
| if (result != VK_SUCCESS) |
| return result; |
| } |
| return VK_SUCCESS; |
| } |
| |
| void lvp_TrimCommandPool( |
| VkDevice device, |
| VkCommandPool commandPool, |
| VkCommandPoolTrimFlags flags) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_pool, pool, commandPool); |
| |
| if (!pool) |
| return; |
| |
| list_for_each_entry_safe(struct lvp_cmd_buffer, cmd_buffer, |
| &pool->free_cmd_buffers, pool_link) { |
| lvp_cmd_buffer_destroy(cmd_buffer); |
| } |
| } |
| |
| static struct lvp_cmd_buffer_entry *cmd_buf_entry_alloc_size(struct lvp_cmd_buffer *cmd_buffer, |
| uint32_t extra_size, |
| enum lvp_cmds type) |
| { |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = sizeof(*cmd) + extra_size; |
| cmd = vk_alloc(&cmd_buffer->pool->alloc, |
| cmd_size, |
| 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); |
| if (!cmd) |
| return NULL; |
| |
| cmd->cmd_type = type; |
| return cmd; |
| } |
| |
| static struct lvp_cmd_buffer_entry *cmd_buf_entry_alloc(struct lvp_cmd_buffer *cmd_buffer, |
| enum lvp_cmds type) |
| { |
| return cmd_buf_entry_alloc_size(cmd_buffer, 0, type); |
| } |
| |
| static void cmd_buf_queue(struct lvp_cmd_buffer *cmd_buffer, |
| struct lvp_cmd_buffer_entry *cmd) |
| { |
| list_addtail(&cmd->cmd_link, &cmd_buffer->cmds); |
| } |
| |
| static void |
| state_setup_attachments(struct lvp_attachment_state *attachments, |
| struct lvp_render_pass *pass, |
| const VkClearValue *clear_values) |
| { |
| for (uint32_t i = 0; i < pass->attachment_count; ++i) { |
| struct lvp_render_pass_attachment *att = &pass->attachments[i]; |
| VkImageAspectFlags att_aspects = vk_format_aspects(att->format); |
| VkImageAspectFlags clear_aspects = 0; |
| if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) { |
| /* color attachment */ |
| if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { |
| clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; |
| } |
| } else { |
| /* depthstencil attachment */ |
| if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && |
| att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { |
| clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; |
| if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && |
| att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE) |
| clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; |
| } |
| if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && |
| att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { |
| clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; |
| } |
| } |
| attachments[i].pending_clear_aspects = clear_aspects; |
| if (clear_values) |
| attachments[i].clear_value = clear_values[i]; |
| } |
| } |
| |
| void lvp_CmdBeginRenderPass( |
| VkCommandBuffer commandBuffer, |
| const VkRenderPassBeginInfo* pRenderPassBegin, |
| VkSubpassContents contents) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_render_pass, pass, pRenderPassBegin->renderPass); |
| LVP_FROM_HANDLE(lvp_framebuffer, framebuffer, pRenderPassBegin->framebuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = pass->attachment_count * sizeof(struct lvp_attachment_state); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_BEGIN_RENDER_PASS); |
| if (!cmd) |
| return; |
| |
| cmd->u.begin_render_pass.render_pass = pass; |
| cmd->u.begin_render_pass.framebuffer = framebuffer; |
| cmd->u.begin_render_pass.render_area = pRenderPassBegin->renderArea; |
| |
| cmd->u.begin_render_pass.attachments = (struct lvp_attachment_state *)(cmd + 1); |
| state_setup_attachments(cmd->u.begin_render_pass.attachments, pass, pRenderPassBegin->pClearValues); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdNextSubpass( |
| VkCommandBuffer commandBuffer, |
| VkSubpassContents contents) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_NEXT_SUBPASS); |
| if (!cmd) |
| return; |
| |
| cmd->u.next_subpass.contents = contents; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBindVertexBuffers( |
| VkCommandBuffer commandBuffer, |
| uint32_t firstBinding, |
| uint32_t bindingCount, |
| const VkBuffer* pBuffers, |
| const VkDeviceSize* pOffsets) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| struct lvp_buffer **buffers; |
| VkDeviceSize *offsets; |
| int i; |
| uint32_t cmd_size = bindingCount * sizeof(struct lvp_buffer *) + bindingCount * sizeof(VkDeviceSize); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_BIND_VERTEX_BUFFERS); |
| if (!cmd) |
| return; |
| |
| cmd->u.vertex_buffers.first = firstBinding; |
| cmd->u.vertex_buffers.binding_count = bindingCount; |
| |
| buffers = (struct lvp_buffer **)(cmd + 1); |
| offsets = (VkDeviceSize *)(buffers + bindingCount); |
| for (i = 0; i < bindingCount; i++) { |
| buffers[i] = lvp_buffer_from_handle(pBuffers[i]); |
| offsets[i] = pOffsets[i]; |
| } |
| cmd->u.vertex_buffers.buffers = buffers; |
| cmd->u.vertex_buffers.offsets = offsets; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBindPipeline( |
| VkCommandBuffer commandBuffer, |
| VkPipelineBindPoint pipelineBindPoint, |
| VkPipeline _pipeline) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_pipeline, pipeline, _pipeline); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_BIND_PIPELINE); |
| if (!cmd) |
| return; |
| |
| cmd->u.pipeline.bind_point = pipelineBindPoint; |
| cmd->u.pipeline.pipeline = pipeline; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBindDescriptorSets( |
| VkCommandBuffer commandBuffer, |
| VkPipelineBindPoint pipelineBindPoint, |
| VkPipelineLayout _layout, |
| uint32_t firstSet, |
| uint32_t descriptorSetCount, |
| const VkDescriptorSet* pDescriptorSets, |
| uint32_t dynamicOffsetCount, |
| const uint32_t* pDynamicOffsets) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_pipeline_layout, layout, _layout); |
| struct lvp_cmd_buffer_entry *cmd; |
| struct lvp_descriptor_set **sets; |
| uint32_t *offsets; |
| int i; |
| uint32_t cmd_size = descriptorSetCount * sizeof(struct lvp_descriptor_set *) + dynamicOffsetCount * sizeof(uint32_t); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_BIND_DESCRIPTOR_SETS); |
| if (!cmd) |
| return; |
| |
| cmd->u.descriptor_sets.bind_point = pipelineBindPoint; |
| cmd->u.descriptor_sets.layout = layout; |
| cmd->u.descriptor_sets.first = firstSet; |
| cmd->u.descriptor_sets.count = descriptorSetCount; |
| |
| sets = (struct lvp_descriptor_set **)(cmd + 1); |
| for (i = 0; i < descriptorSetCount; i++) { |
| sets[i] = lvp_descriptor_set_from_handle(pDescriptorSets[i]); |
| } |
| cmd->u.descriptor_sets.sets = sets; |
| |
| cmd->u.descriptor_sets.dynamic_offset_count = dynamicOffsetCount; |
| offsets = (uint32_t *)(sets + descriptorSetCount); |
| for (i = 0; i < dynamicOffsetCount; i++) |
| offsets[i] = pDynamicOffsets[i]; |
| cmd->u.descriptor_sets.dynamic_offsets = offsets; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdDraw( |
| VkCommandBuffer commandBuffer, |
| uint32_t vertexCount, |
| uint32_t instanceCount, |
| uint32_t firstVertex, |
| uint32_t firstInstance) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW); |
| if (!cmd) |
| return; |
| |
| cmd->u.draw.vertex_count = vertexCount; |
| cmd->u.draw.instance_count = instanceCount; |
| cmd->u.draw.first_vertex = firstVertex; |
| cmd->u.draw.first_instance = firstInstance; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdEndRenderPass( |
| VkCommandBuffer commandBuffer) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_END_RENDER_PASS); |
| if (!cmd) |
| return; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetViewport( |
| VkCommandBuffer commandBuffer, |
| uint32_t firstViewport, |
| uint32_t viewportCount, |
| const VkViewport* pViewports) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| int i; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_VIEWPORT); |
| if (!cmd) |
| return; |
| |
| cmd->u.set_viewport.first_viewport = firstViewport; |
| cmd->u.set_viewport.viewport_count = viewportCount; |
| for (i = 0; i < viewportCount; i++) |
| cmd->u.set_viewport.viewports[i] = pViewports[i]; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetScissor( |
| VkCommandBuffer commandBuffer, |
| uint32_t firstScissor, |
| uint32_t scissorCount, |
| const VkRect2D* pScissors) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| int i; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_SCISSOR); |
| if (!cmd) |
| return; |
| |
| cmd->u.set_scissor.first_scissor = firstScissor; |
| cmd->u.set_scissor.scissor_count = scissorCount; |
| for (i = 0; i < scissorCount; i++) |
| cmd->u.set_scissor.scissors[i] = pScissors[i]; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetLineWidth( |
| VkCommandBuffer commandBuffer, |
| float lineWidth) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_LINE_WIDTH); |
| if (!cmd) |
| return; |
| |
| cmd->u.set_line_width.line_width = lineWidth; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetDepthBias( |
| VkCommandBuffer commandBuffer, |
| float depthBiasConstantFactor, |
| float depthBiasClamp, |
| float depthBiasSlopeFactor) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_DEPTH_BIAS); |
| if (!cmd) |
| return; |
| |
| cmd->u.set_depth_bias.constant_factor = depthBiasConstantFactor; |
| cmd->u.set_depth_bias.clamp = depthBiasClamp; |
| cmd->u.set_depth_bias.slope_factor = depthBiasSlopeFactor; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetBlendConstants( |
| VkCommandBuffer commandBuffer, |
| const float blendConstants[4]) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_BLEND_CONSTANTS); |
| if (!cmd) |
| return; |
| |
| memcpy(cmd->u.set_blend_constants.blend_constants, blendConstants, 4 * sizeof(float)); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetDepthBounds( |
| VkCommandBuffer commandBuffer, |
| float minDepthBounds, |
| float maxDepthBounds) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_DEPTH_BOUNDS); |
| if (!cmd) |
| return; |
| |
| cmd->u.set_depth_bounds.min_depth = minDepthBounds; |
| cmd->u.set_depth_bounds.max_depth = maxDepthBounds; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetStencilCompareMask( |
| VkCommandBuffer commandBuffer, |
| VkStencilFaceFlags faceMask, |
| uint32_t compareMask) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_STENCIL_COMPARE_MASK); |
| if (!cmd) |
| return; |
| |
| cmd->u.stencil_vals.face_mask = faceMask; |
| cmd->u.stencil_vals.value = compareMask; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetStencilWriteMask( |
| VkCommandBuffer commandBuffer, |
| VkStencilFaceFlags faceMask, |
| uint32_t writeMask) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_STENCIL_WRITE_MASK); |
| if (!cmd) |
| return; |
| |
| cmd->u.stencil_vals.face_mask = faceMask; |
| cmd->u.stencil_vals.value = writeMask; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| |
| void lvp_CmdSetStencilReference( |
| VkCommandBuffer commandBuffer, |
| VkStencilFaceFlags faceMask, |
| uint32_t reference) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_STENCIL_REFERENCE); |
| if (!cmd) |
| return; |
| |
| cmd->u.stencil_vals.face_mask = faceMask; |
| cmd->u.stencil_vals.value = reference; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdPushConstants( |
| VkCommandBuffer commandBuffer, |
| VkPipelineLayout layout, |
| VkShaderStageFlags stageFlags, |
| uint32_t offset, |
| uint32_t size, |
| const void* pValues) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, (size - 4), LVP_CMD_PUSH_CONSTANTS); |
| if (!cmd) |
| return; |
| |
| cmd->u.push_constants.stage = stageFlags; |
| cmd->u.push_constants.offset = offset; |
| cmd->u.push_constants.size = size; |
| memcpy(cmd->u.push_constants.val, pValues, size); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBindIndexBuffer( |
| VkCommandBuffer commandBuffer, |
| VkBuffer _buffer, |
| VkDeviceSize offset, |
| VkIndexType indexType) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, buffer, _buffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_BIND_INDEX_BUFFER); |
| if (!cmd) |
| return; |
| |
| cmd->u.index_buffer.buffer = buffer; |
| cmd->u.index_buffer.offset = offset; |
| cmd->u.index_buffer.index_type = indexType; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdDrawIndexed( |
| VkCommandBuffer commandBuffer, |
| uint32_t indexCount, |
| uint32_t instanceCount, |
| uint32_t firstIndex, |
| int32_t vertexOffset, |
| uint32_t firstInstance) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW_INDEXED); |
| if (!cmd) |
| return; |
| |
| cmd->u.draw_indexed.index_count = indexCount; |
| cmd->u.draw_indexed.instance_count = instanceCount; |
| cmd->u.draw_indexed.first_index = firstIndex; |
| cmd->u.draw_indexed.vertex_offset = vertexOffset; |
| cmd->u.draw_indexed.first_instance = firstInstance; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdDrawIndirect( |
| VkCommandBuffer commandBuffer, |
| VkBuffer _buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, buf, _buffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW_INDIRECT); |
| if (!cmd) |
| return; |
| |
| cmd->u.draw_indirect.offset = offset; |
| cmd->u.draw_indirect.buffer = buf; |
| cmd->u.draw_indirect.draw_count = drawCount; |
| cmd->u.draw_indirect.stride = stride; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdDrawIndexedIndirect( |
| VkCommandBuffer commandBuffer, |
| VkBuffer _buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, buf, _buffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DRAW_INDEXED_INDIRECT); |
| if (!cmd) |
| return; |
| |
| cmd->u.draw_indirect.offset = offset; |
| cmd->u.draw_indirect.buffer = buf; |
| cmd->u.draw_indirect.draw_count = drawCount; |
| cmd->u.draw_indirect.stride = stride; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdDispatch( |
| VkCommandBuffer commandBuffer, |
| uint32_t x, |
| uint32_t y, |
| uint32_t z) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DISPATCH); |
| if (!cmd) |
| return; |
| |
| cmd->u.dispatch.x = x; |
| cmd->u.dispatch.y = y; |
| cmd->u.dispatch.z = z; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdDispatchIndirect( |
| VkCommandBuffer commandBuffer, |
| VkBuffer _buffer, |
| VkDeviceSize offset) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_DISPATCH_INDIRECT); |
| if (!cmd) |
| return; |
| |
| cmd->u.dispatch_indirect.buffer = lvp_buffer_from_handle(_buffer); |
| cmd->u.dispatch_indirect.offset = offset; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdExecuteCommands( |
| VkCommandBuffer commandBuffer, |
| uint32_t commandBufferCount, |
| const VkCommandBuffer* pCmdBuffers) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = commandBufferCount * sizeof(struct lvp_cmd_buffer *); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_EXECUTE_COMMANDS); |
| if (!cmd) |
| return; |
| |
| cmd->u.execute_commands.command_buffer_count = commandBufferCount; |
| for (unsigned i = 0; i < commandBufferCount; i++) |
| cmd->u.execute_commands.cmd_buffers[i] = lvp_cmd_buffer_from_handle(pCmdBuffers[i]); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdSetEvent(VkCommandBuffer commandBuffer, |
| VkEvent _event, |
| VkPipelineStageFlags stageMask) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_event, event, _event); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_EVENT); |
| if (!cmd) |
| return; |
| |
| cmd->u.event_set.event = event; |
| cmd->u.event_set.value = true; |
| cmd->u.event_set.flush = !!(stageMask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdResetEvent(VkCommandBuffer commandBuffer, |
| VkEvent _event, |
| VkPipelineStageFlags stageMask) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_event, event, _event); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_SET_EVENT); |
| if (!cmd) |
| return; |
| |
| cmd->u.event_set.event = event; |
| cmd->u.event_set.value = false; |
| cmd->u.event_set.flush = !!(stageMask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| |
| } |
| |
| void lvp_CmdWaitEvents(VkCommandBuffer commandBuffer, |
| uint32_t eventCount, |
| const VkEvent* pEvents, |
| VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| uint32_t memoryBarrierCount, |
| const VkMemoryBarrier* pMemoryBarriers, |
| uint32_t bufferMemoryBarrierCount, |
| const VkBufferMemoryBarrier* pBufferMemoryBarriers, |
| uint32_t imageMemoryBarrierCount, |
| const VkImageMemoryBarrier* pImageMemoryBarriers) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = 0; |
| |
| cmd_size += eventCount * sizeof(struct lvp_event *); |
| cmd_size += memoryBarrierCount * sizeof(VkMemoryBarrier); |
| cmd_size += bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier); |
| cmd_size += imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_WAIT_EVENTS); |
| if (!cmd) |
| return; |
| |
| cmd->u.wait_events.src_stage_mask = srcStageMask; |
| cmd->u.wait_events.dst_stage_mask = dstStageMask; |
| cmd->u.wait_events.event_count = eventCount; |
| cmd->u.wait_events.events = (struct lvp_event **)(cmd + 1); |
| for (unsigned i = 0; i < eventCount; i++) |
| cmd->u.wait_events.events[i] = lvp_event_from_handle(pEvents[i]); |
| cmd->u.wait_events.memory_barrier_count = memoryBarrierCount; |
| cmd->u.wait_events.buffer_memory_barrier_count = bufferMemoryBarrierCount; |
| cmd->u.wait_events.image_memory_barrier_count = imageMemoryBarrierCount; |
| |
| /* TODO finish off this */ |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| |
| void lvp_CmdCopyBufferToImage( |
| VkCommandBuffer commandBuffer, |
| VkBuffer srcBuffer, |
| VkImage destImage, |
| VkImageLayout destImageLayout, |
| uint32_t regionCount, |
| const VkBufferImageCopy* pRegions) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, src_buffer, srcBuffer); |
| LVP_FROM_HANDLE(lvp_image, dst_image, destImage); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = regionCount * sizeof(VkBufferImageCopy); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_COPY_BUFFER_TO_IMAGE); |
| if (!cmd) |
| return; |
| |
| cmd->u.buffer_to_img.src = src_buffer; |
| cmd->u.buffer_to_img.dst = dst_image; |
| cmd->u.buffer_to_img.dst_layout = destImageLayout; |
| cmd->u.buffer_to_img.region_count = regionCount; |
| |
| { |
| VkBufferImageCopy *regions; |
| |
| regions = (VkBufferImageCopy *)(cmd + 1); |
| memcpy(regions, pRegions, regionCount * sizeof(VkBufferImageCopy)); |
| cmd->u.buffer_to_img.regions = regions; |
| } |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdCopyImageToBuffer( |
| VkCommandBuffer commandBuffer, |
| VkImage srcImage, |
| VkImageLayout srcImageLayout, |
| VkBuffer destBuffer, |
| uint32_t regionCount, |
| const VkBufferImageCopy* pRegions) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_image, src_image, srcImage); |
| LVP_FROM_HANDLE(lvp_buffer, dst_buffer, destBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = regionCount * sizeof(VkBufferImageCopy); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_COPY_IMAGE_TO_BUFFER); |
| if (!cmd) |
| return; |
| |
| cmd->u.img_to_buffer.src = src_image; |
| cmd->u.img_to_buffer.dst = dst_buffer; |
| cmd->u.img_to_buffer.src_layout = srcImageLayout; |
| cmd->u.img_to_buffer.region_count = regionCount; |
| |
| { |
| VkBufferImageCopy *regions; |
| |
| regions = (VkBufferImageCopy *)(cmd + 1); |
| memcpy(regions, pRegions, regionCount * sizeof(VkBufferImageCopy)); |
| cmd->u.img_to_buffer.regions = regions; |
| } |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdCopyImage( |
| VkCommandBuffer commandBuffer, |
| VkImage srcImage, |
| VkImageLayout srcImageLayout, |
| VkImage destImage, |
| VkImageLayout destImageLayout, |
| uint32_t regionCount, |
| const VkImageCopy* pRegions) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_image, src_image, srcImage); |
| LVP_FROM_HANDLE(lvp_image, dest_image, destImage); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = regionCount * sizeof(VkImageCopy); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_COPY_IMAGE); |
| if (!cmd) |
| return; |
| |
| cmd->u.copy_image.src = src_image; |
| cmd->u.copy_image.dst = dest_image; |
| cmd->u.copy_image.src_layout = srcImageLayout; |
| cmd->u.copy_image.dst_layout = destImageLayout; |
| cmd->u.copy_image.region_count = regionCount; |
| |
| { |
| VkImageCopy *regions; |
| |
| regions = (VkImageCopy *)(cmd + 1); |
| memcpy(regions, pRegions, regionCount * sizeof(VkImageCopy)); |
| cmd->u.copy_image.regions = regions; |
| } |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| |
| void lvp_CmdCopyBuffer( |
| VkCommandBuffer commandBuffer, |
| VkBuffer srcBuffer, |
| VkBuffer destBuffer, |
| uint32_t regionCount, |
| const VkBufferCopy* pRegions) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, src_buffer, srcBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, dest_buffer, destBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = regionCount * sizeof(VkBufferCopy); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_COPY_BUFFER); |
| if (!cmd) |
| return; |
| |
| cmd->u.copy_buffer.src = src_buffer; |
| cmd->u.copy_buffer.dst = dest_buffer; |
| cmd->u.copy_buffer.region_count = regionCount; |
| |
| { |
| VkBufferCopy *regions; |
| |
| regions = (VkBufferCopy *)(cmd + 1); |
| memcpy(regions, pRegions, regionCount * sizeof(VkBufferCopy)); |
| cmd->u.copy_buffer.regions = regions; |
| } |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBlitImage( |
| VkCommandBuffer commandBuffer, |
| VkImage srcImage, |
| VkImageLayout srcImageLayout, |
| VkImage destImage, |
| VkImageLayout destImageLayout, |
| uint32_t regionCount, |
| const VkImageBlit* pRegions, |
| VkFilter filter) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_image, src_image, srcImage); |
| LVP_FROM_HANDLE(lvp_image, dest_image, destImage); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = regionCount * sizeof(VkImageBlit); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_BLIT_IMAGE); |
| if (!cmd) |
| return; |
| |
| cmd->u.blit_image.src = src_image; |
| cmd->u.blit_image.dst = dest_image; |
| cmd->u.blit_image.src_layout = srcImageLayout; |
| cmd->u.blit_image.dst_layout = destImageLayout; |
| cmd->u.blit_image.filter = filter; |
| cmd->u.blit_image.region_count = regionCount; |
| |
| { |
| VkImageBlit *regions; |
| |
| regions = (VkImageBlit *)(cmd + 1); |
| memcpy(regions, pRegions, regionCount * sizeof(VkImageBlit)); |
| cmd->u.blit_image.regions = regions; |
| } |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdClearAttachments( |
| VkCommandBuffer commandBuffer, |
| uint32_t attachmentCount, |
| const VkClearAttachment* pAttachments, |
| uint32_t rectCount, |
| const VkClearRect* pRects) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = attachmentCount * sizeof(VkClearAttachment) + rectCount * sizeof(VkClearRect); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_CLEAR_ATTACHMENTS); |
| if (!cmd) |
| return; |
| |
| cmd->u.clear_attachments.attachment_count = attachmentCount; |
| cmd->u.clear_attachments.attachments = (VkClearAttachment *)(cmd + 1); |
| for (unsigned i = 0; i < attachmentCount; i++) |
| cmd->u.clear_attachments.attachments[i] = pAttachments[i]; |
| cmd->u.clear_attachments.rect_count = rectCount; |
| cmd->u.clear_attachments.rects = (VkClearRect *)(cmd->u.clear_attachments.attachments + attachmentCount); |
| for (unsigned i = 0; i < rectCount; i++) |
| cmd->u.clear_attachments.rects[i] = pRects[i]; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdFillBuffer( |
| VkCommandBuffer commandBuffer, |
| VkBuffer dstBuffer, |
| VkDeviceSize dstOffset, |
| VkDeviceSize fillSize, |
| uint32_t data) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, dst_buffer, dstBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_FILL_BUFFER); |
| if (!cmd) |
| return; |
| |
| cmd->u.fill_buffer.buffer = dst_buffer; |
| cmd->u.fill_buffer.offset = dstOffset; |
| cmd->u.fill_buffer.fill_size = fillSize; |
| cmd->u.fill_buffer.data = data; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdUpdateBuffer( |
| VkCommandBuffer commandBuffer, |
| VkBuffer dstBuffer, |
| VkDeviceSize dstOffset, |
| VkDeviceSize dataSize, |
| const void* pData) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_buffer, dst_buffer, dstBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, dataSize, LVP_CMD_UPDATE_BUFFER); |
| if (!cmd) |
| return; |
| |
| cmd->u.update_buffer.buffer = dst_buffer; |
| cmd->u.update_buffer.offset = dstOffset; |
| cmd->u.update_buffer.data_size = dataSize; |
| memcpy(cmd->u.update_buffer.data, pData, dataSize); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdClearColorImage( |
| VkCommandBuffer commandBuffer, |
| VkImage image_h, |
| VkImageLayout imageLayout, |
| const VkClearColorValue* pColor, |
| uint32_t rangeCount, |
| const VkImageSubresourceRange* pRanges) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_image, image, image_h); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = rangeCount * sizeof(VkImageSubresourceRange); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_CLEAR_COLOR_IMAGE); |
| if (!cmd) |
| return; |
| |
| cmd->u.clear_color_image.image = image; |
| cmd->u.clear_color_image.layout = imageLayout; |
| cmd->u.clear_color_image.clear_val = *pColor; |
| cmd->u.clear_color_image.range_count = rangeCount; |
| cmd->u.clear_color_image.ranges = (VkImageSubresourceRange *)(cmd + 1); |
| for (unsigned i = 0; i < rangeCount; i++) |
| cmd->u.clear_color_image.ranges[i] = pRanges[i]; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdClearDepthStencilImage( |
| VkCommandBuffer commandBuffer, |
| VkImage image_h, |
| VkImageLayout imageLayout, |
| const VkClearDepthStencilValue* pDepthStencil, |
| uint32_t rangeCount, |
| const VkImageSubresourceRange* pRanges) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_image, image, image_h); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = rangeCount * sizeof(VkImageSubresourceRange); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_CLEAR_DEPTH_STENCIL_IMAGE); |
| if (!cmd) |
| return; |
| |
| cmd->u.clear_ds_image.image = image; |
| cmd->u.clear_ds_image.layout = imageLayout; |
| cmd->u.clear_ds_image.clear_val = *pDepthStencil; |
| cmd->u.clear_ds_image.range_count = rangeCount; |
| cmd->u.clear_ds_image.ranges = (VkImageSubresourceRange *)(cmd + 1); |
| for (unsigned i = 0; i < rangeCount; i++) |
| cmd->u.clear_ds_image.ranges[i] = pRanges[i]; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| |
| void lvp_CmdResolveImage( |
| VkCommandBuffer commandBuffer, |
| VkImage srcImage, |
| VkImageLayout srcImageLayout, |
| VkImage destImage, |
| VkImageLayout destImageLayout, |
| uint32_t regionCount, |
| const VkImageResolve* regions) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_image, src_image, srcImage); |
| LVP_FROM_HANDLE(lvp_image, dst_image, destImage); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = regionCount * sizeof(VkImageResolve); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_RESOLVE_IMAGE); |
| if (!cmd) |
| return; |
| |
| cmd->u.resolve_image.src = src_image; |
| cmd->u.resolve_image.dst = dst_image; |
| cmd->u.resolve_image.src_layout = srcImageLayout; |
| cmd->u.resolve_image.dst_layout = destImageLayout; |
| cmd->u.resolve_image.region_count = regionCount; |
| cmd->u.resolve_image.regions = (VkImageResolve *)(cmd + 1); |
| for (unsigned i = 0; i < regionCount; i++) |
| cmd->u.resolve_image.regions[i] = regions[i]; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdResetQueryPool( |
| VkCommandBuffer commandBuffer, |
| VkQueryPool queryPool, |
| uint32_t firstQuery, |
| uint32_t queryCount) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_query_pool, query_pool, queryPool); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_RESET_QUERY_POOL); |
| if (!cmd) |
| return; |
| |
| cmd->u.query.pool = query_pool; |
| cmd->u.query.query = firstQuery; |
| cmd->u.query.index = queryCount; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBeginQueryIndexedEXT( |
| VkCommandBuffer commandBuffer, |
| VkQueryPool queryPool, |
| uint32_t query, |
| VkQueryControlFlags flags, |
| uint32_t index) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_query_pool, query_pool, queryPool); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_BEGIN_QUERY); |
| if (!cmd) |
| return; |
| |
| cmd->u.query.pool = query_pool; |
| cmd->u.query.query = query; |
| cmd->u.query.index = index; |
| cmd->u.query.precise = true; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdBeginQuery( |
| VkCommandBuffer commandBuffer, |
| VkQueryPool queryPool, |
| uint32_t query, |
| VkQueryControlFlags flags) |
| { |
| lvp_CmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, 0); |
| } |
| |
| void lvp_CmdEndQueryIndexedEXT( |
| VkCommandBuffer commandBuffer, |
| VkQueryPool queryPool, |
| uint32_t query, |
| uint32_t index) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_query_pool, query_pool, queryPool); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_END_QUERY); |
| if (!cmd) |
| return; |
| |
| cmd->u.query.pool = query_pool; |
| cmd->u.query.query = query; |
| cmd->u.query.index = index; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdEndQuery( |
| VkCommandBuffer commandBuffer, |
| VkQueryPool queryPool, |
| uint32_t query) |
| { |
| lvp_CmdEndQueryIndexedEXT(commandBuffer, queryPool, query, 0); |
| } |
| |
| void lvp_CmdWriteTimestamp( |
| VkCommandBuffer commandBuffer, |
| VkPipelineStageFlagBits pipelineStage, |
| VkQueryPool queryPool, |
| uint32_t query) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_query_pool, query_pool, queryPool); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_WRITE_TIMESTAMP); |
| if (!cmd) |
| return; |
| |
| cmd->u.query.pool = query_pool; |
| cmd->u.query.query = query; |
| cmd->u.query.flush = !(pipelineStage == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdCopyQueryPoolResults( |
| VkCommandBuffer commandBuffer, |
| VkQueryPool queryPool, |
| uint32_t firstQuery, |
| uint32_t queryCount, |
| VkBuffer dstBuffer, |
| VkDeviceSize dstOffset, |
| VkDeviceSize stride, |
| VkQueryResultFlags flags) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| LVP_FROM_HANDLE(lvp_query_pool, query_pool, queryPool); |
| LVP_FROM_HANDLE(lvp_buffer, buffer, dstBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| |
| cmd = cmd_buf_entry_alloc(cmd_buffer, LVP_CMD_COPY_QUERY_POOL_RESULTS); |
| if (!cmd) |
| return; |
| |
| cmd->u.copy_query_pool_results.pool = query_pool; |
| cmd->u.copy_query_pool_results.first_query = firstQuery; |
| cmd->u.copy_query_pool_results.query_count = queryCount; |
| cmd->u.copy_query_pool_results.dst = buffer; |
| cmd->u.copy_query_pool_results.dst_offset = dstOffset; |
| cmd->u.copy_query_pool_results.stride = stride; |
| cmd->u.copy_query_pool_results.flags = flags; |
| |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |
| |
| void lvp_CmdPipelineBarrier( |
| VkCommandBuffer commandBuffer, |
| VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags destStageMask, |
| VkBool32 byRegion, |
| uint32_t memoryBarrierCount, |
| const VkMemoryBarrier* pMemoryBarriers, |
| uint32_t bufferMemoryBarrierCount, |
| const VkBufferMemoryBarrier* pBufferMemoryBarriers, |
| uint32_t imageMemoryBarrierCount, |
| const VkImageMemoryBarrier* pImageMemoryBarriers) |
| { |
| LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer); |
| struct lvp_cmd_buffer_entry *cmd; |
| uint32_t cmd_size = 0; |
| |
| cmd_size += memoryBarrierCount * sizeof(VkMemoryBarrier); |
| cmd_size += bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier); |
| cmd_size += imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier); |
| |
| cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, LVP_CMD_PIPELINE_BARRIER); |
| if (!cmd) |
| return; |
| |
| cmd->u.pipeline_barrier.src_stage_mask = srcStageMask; |
| cmd->u.pipeline_barrier.dst_stage_mask = destStageMask; |
| cmd->u.pipeline_barrier.by_region = byRegion; |
| cmd->u.pipeline_barrier.memory_barrier_count = memoryBarrierCount; |
| cmd->u.pipeline_barrier.buffer_memory_barrier_count = bufferMemoryBarrierCount; |
| cmd->u.pipeline_barrier.image_memory_barrier_count = imageMemoryBarrierCount; |
| |
| /* TODO finish off this */ |
| cmd_buf_queue(cmd_buffer, cmd); |
| } |