diff --git a/src/nouveau/vulkan/meson.build b/src/nouveau/vulkan/meson.build index 16f5d018c90..cdcaf4cd2c3 100644 --- a/src/nouveau/vulkan/meson.build +++ b/src/nouveau/vulkan/meson.build @@ -12,6 +12,7 @@ nvk_files = files( 'nvk_cmd_copy.c', 'nvk_cmd_dispatch.c', 'nvk_cmd_draw.c', + 'nvk_cmd_meta.c', 'nvk_compute_pipeline.c', 'nvk_descriptor_set.h', 'nvk_descriptor_set.c', diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.h b/src/nouveau/vulkan/nvk_cmd_buffer.h index 0ec1b1150b0..cfdbc7ffbcd 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.h +++ b/src/nouveau/vulkan/nvk_cmd_buffer.h @@ -82,6 +82,9 @@ struct nvk_graphics_state { struct nvk_graphics_pipeline *pipeline; struct nvk_descriptor_state descriptors; + /* Used for meta save/restore */ + struct nvk_addr_range vb0; + /* Needed by vk_command_buffer::dynamic_graphics_state */ struct vk_vertex_input_state _dynamic_vi; struct vk_sample_locations_state _dynamic_ms_sl; diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c b/src/nouveau/vulkan/nvk_cmd_draw.c index 5d560cf298c..4ba9519e8a3 100644 --- a/src/nouveau/vulkan/nvk_cmd_draw.c +++ b/src/nouveau/vulkan/nvk_cmd_draw.c @@ -326,46 +326,6 @@ nvk_cmd_buffer_begin_graphics(struct nvk_cmd_buffer *cmd, } } -VKAPI_ATTR void VKAPI_CALL -nvk_CmdClearAttachments(VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment *pAttachments, - uint32_t rectCount, - const VkClearRect *pRects) -{ - VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer); - struct nvk_rendering_state *render = &cmd->state.gfx.render; - - for (unsigned i = 0; i < attachmentCount; i++) { - assert(pAttachments[i].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT); - if (pAttachments[i].colorAttachment == VK_ATTACHMENT_UNUSED) - return; - - struct nvk_image_view *iview = - render->color_att[pAttachments[i].colorAttachment].iview; - for (unsigned r = 0; r < rectCount; r++) { - assert(pRects[r].rect.offset.x == 0); - assert(pRects[r].rect.offset.y == 0); - assert(pRects[r].rect.extent.width == iview->vk.extent.width); - assert(pRects[r].rect.extent.height == iview->vk.extent.height); - - const VkImageSubresourceRange subres = { - .aspectMask = pAttachments[i].aspectMask, - .baseMipLevel = iview->vk.base_mip_level, - .levelCount = 1, - .baseArrayLayer = iview->vk.base_array_layer + - pRects[r].baseArrayLayer, - .layerCount = pRects[r].layerCount, - }; - nvk_CmdClearColorImage(commandBuffer, - vk_image_to_handle(iview->vk.image), - VK_IMAGE_LAYOUT_GENERAL, - &pAttachments[i].clearValue.color, - 1, &subres); - } - } -} - static void nvk_attachment_init(struct nvk_attachment *att, const VkRenderingAttachmentInfo *info) @@ -1286,6 +1246,10 @@ nvk_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer, addr_range.range = vk_buffer_range(&buffer->vk, pOffsets[i], size); } + /* Used for meta save/restore */ + if (idx == 0) + cmd->state.gfx.vb0 = addr_range; + nvk_cmd_bind_vertex_buffer(cmd, idx, addr_range); } } @@ -1301,6 +1265,10 @@ vk_to_nv9097_primitive_topology(VkPrimitiveTopology prim) case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: return NV9097_BEGIN_OP_LINE_STRIP; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wswitch" + case VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA: +#pragma GCC diagnostic pop return NV9097_BEGIN_OP_TRIANGLES; case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return NV9097_BEGIN_OP_TRIANGLE_STRIP; diff --git a/src/nouveau/vulkan/nvk_cmd_meta.c b/src/nouveau/vulkan/nvk_cmd_meta.c new file mode 100644 index 00000000000..18b777d437e --- /dev/null +++ b/src/nouveau/vulkan/nvk_cmd_meta.c @@ -0,0 +1,112 @@ +#include "nvk_buffer.h" +#include "nvk_cmd_buffer.h" +#include "nvk_device.h" + +static VkResult +nvk_cmd_bind_map_buffer(struct vk_command_buffer *vk_cmd, + struct vk_meta_device *meta, + VkBuffer _buffer, void **map_out) +{ + struct nvk_cmd_buffer *cmd = + container_of(vk_cmd, struct nvk_cmd_buffer, vk); + VK_FROM_HANDLE(nvk_buffer, buffer, _buffer); + + uint64_t addr; + assert(buffer->vk.size < UINT_MAX); + if (!nvk_cmd_buffer_upload_alloc(cmd, buffer->vk.size, &addr, map_out)) + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + + buffer->addr = addr; + + return VK_SUCCESS; +} + +VkResult +nvk_device_init_meta(struct nvk_device *dev) +{ + VkResult result = vk_meta_device_init(&dev->vk, &dev->meta); + if (result != VK_SUCCESS) + return result; + + dev->meta.cmd_bind_map_buffer = nvk_cmd_bind_map_buffer; + dev->meta.max_bind_map_buffer_size_B = 64 * 1024; /* TODO */ + + return VK_SUCCESS; +} + +void +nvk_device_finish_meta(struct nvk_device *dev) +{ + vk_meta_device_finish(&dev->vk, &dev->meta); +} + +struct nvk_meta_save { + struct vk_dynamic_graphics_state dynamic; + struct nvk_graphics_pipeline *pipeline; + struct nvk_addr_range vb0; + uint8_t push[128]; +}; + +static void +nvk_meta_begin(struct nvk_cmd_buffer *cmd, + struct nvk_meta_save *save) +{ + save->dynamic = cmd->vk.dynamic_graphics_state; + save->pipeline = cmd->state.gfx.pipeline; + save->vb0 = cmd->state.gfx.vb0; + + /* TODO: Push */ +} + +static void +nvk_meta_init_render(struct nvk_cmd_buffer *cmd, + struct vk_meta_rendering_info *info) +{ + const struct nvk_rendering_state *render = &cmd->state.gfx.render; + + *info = (struct vk_meta_rendering_info) { + .view_mask = render->view_mask, + .samples = render->samples, + .color_attachment_count = render->color_att_count, + .depth_attachment_format = render->depth_att.vk_format, + .stencil_attachment_format = render->stencil_att.vk_format, + }; + for (uint32_t a = 0; a < render->color_att_count; a++) + info->color_attachment_formats[a] = render->color_att[a].vk_format; +} + +static void +nvk_meta_end(struct nvk_cmd_buffer *cmd, + struct nvk_meta_save *save) +{ + vk_cmd_set_dynamic_graphics_state(&cmd->vk, &save->dynamic); + if (save->pipeline) + nvk_cmd_bind_graphics_pipeline(cmd, save->pipeline); + + nvk_cmd_bind_vertex_buffer(cmd, 0, save->vb0); + + /* TODO: Push */ +} + +VKAPI_ATTR void VKAPI_CALL +nvk_CmdClearAttachments(VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment *pAttachments, + uint32_t rectCount, + const VkClearRect *pRects) +{ + VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer); + struct nvk_device *dev = nvk_cmd_buffer_device(cmd); + + struct nvk_meta_save save; + nvk_meta_begin(cmd, &save); + + struct vk_meta_rendering_info render; + nvk_meta_init_render(cmd, &render); + + vk_meta_clear_attachments(&cmd->vk, &dev->meta, &render, + attachmentCount, pAttachments, + rectCount, pRects); + + nvk_meta_end(cmd, &save); +} diff --git a/src/nouveau/vulkan/nvk_device.c b/src/nouveau/vulkan/nvk_device.c index 613a5e0b8af..1abcb57d210 100644 --- a/src/nouveau/vulkan/nvk_device.c +++ b/src/nouveau/vulkan/nvk_device.c @@ -261,10 +261,16 @@ nvk_CreateDevice(VkPhysicalDevice physicalDevice, device->pdev = physical_device; + result = nvk_device_init_meta(device); + if (result != VK_SUCCESS) + goto fail_queue_submit; + *pDevice = nvk_device_to_handle(device); return VK_SUCCESS; +fail_queue_submit: + pthread_cond_destroy(&device->queue_submit); fail_mutex: pthread_mutex_destroy(&device->mutex); fail_queue: @@ -290,6 +296,8 @@ nvk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) if (!device) return; + nvk_device_finish_meta(device); + if (device->queue.state.push) nouveau_ws_push_destroy(device->queue.state.push); if (device->queue.empty_push) diff --git a/src/nouveau/vulkan/nvk_device.h b/src/nouveau/vulkan/nvk_device.h index 280b4246ec2..788dd54e843 100644 --- a/src/nouveau/vulkan/nvk_device.h +++ b/src/nouveau/vulkan/nvk_device.h @@ -5,6 +5,7 @@ #include "nvk_descriptor_table.h" #include "vulkan/runtime/vk_device.h" +#include "vulkan/runtime/vk_meta.h" #include "vulkan/runtime/vk_queue.h" struct novueau_ws_context; @@ -42,6 +43,8 @@ struct nvk_device { pthread_mutex_t mutex; pthread_cond_t queue_submit; + + struct vk_meta_device meta; }; VK_DEFINE_HANDLE_CASTS(nvk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE) @@ -52,4 +55,7 @@ nvk_device_physical(struct nvk_device *device) return (struct nvk_physical_device *)device->vk.physical; } +VkResult nvk_device_init_meta(struct nvk_device *dev); +void nvk_device_finish_meta(struct nvk_device *dev); + #endif