From 0e49c6237ffeeb51fb92ae4025fbb87fd6c59684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Sun, 5 Jan 2020 01:51:04 +0100 Subject: [PATCH] v3dv/cmd_buffer: emit CFG_BITS Part-of: --- src/broadcom/vulkan/v3dv_cl.h | 21 ++++++++ src/broadcom/vulkan/v3dv_cmd_buffer.c | 1 + src/broadcom/vulkan/v3dv_pipeline.c | 76 +++++++++++++++++++++++++++ src/broadcom/vulkan/v3dv_private.h | 6 +++ 4 files changed, 104 insertions(+) diff --git a/src/broadcom/vulkan/v3dv_cl.h b/src/broadcom/vulkan/v3dv_cl.h index c95110f48e0..1784f8e7bb9 100644 --- a/src/broadcom/vulkan/v3dv_cl.h +++ b/src/broadcom/vulkan/v3dv_cl.h @@ -170,4 +170,25 @@ cl_pack_emit_reloc(struct v3dv_cl *cl, const struct v3dv_cl_reloc *reloc) v3dv_job_add_bo(cl->job, reloc->bo); } +#define cl_emit_prepacked_sized(cl, packet, size) do { \ + memcpy((cl)->next, packet, size); \ + cl_advance(&(cl)->next, size); \ +} while (0) + +#define cl_emit_prepacked(cl, packet) \ + cl_emit_prepacked_sized(cl, packet, sizeof(*(packet))) + +#define v3dv_pack(packed, packet, name) \ + for (struct cl_packet_struct(packet) name = { \ + cl_packet_header(packet) \ + }, \ + *_loop_terminate = &name; \ + __builtin_expect(_loop_terminate != NULL, 1); \ + ({ \ + cl_packet_pack(packet)(NULL, (uint8_t *)packed, &name); \ + VG(VALGRIND_CHECK_MEM_IS_DEFINED((uint8_t *)packed, \ + cl_packet_length(packet))); \ + _loop_terminate = NULL; \ + })) \ + #endif /* V3DV_CL_H */ diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 2bf7711d773..fd0984feecf 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -1711,6 +1711,7 @@ cmd_buffer_emit_graphics_pipeline(struct v3dv_cmd_buffer *cmd_buffer) state.number_of_attribute_arrays = num_elements_to_emit; } + cl_emit_prepacked(&job->bcl, &pipeline->cfg_bits); } /* FIXME: C&P from v3dx_draw. Refactor to common place? */ diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c index cd593dcc6a9..75b67b4759e 100644 --- a/src/broadcom/vulkan/v3dv_pipeline.c +++ b/src/broadcom/vulkan/v3dv_pipeline.c @@ -32,6 +32,8 @@ #include "vulkan/util/vk_format.h" +#include "broadcom/cle/v3dx_pack.h" + VkResult v3dv_CreateShaderModule(VkDevice _device, const VkShaderModuleCreateInfo *pCreateInfo, @@ -755,6 +757,63 @@ pipeline_init_dynamic_state(struct v3dv_pipeline *pipeline, pipeline->dynamic_state.mask = states; } +static void +pack_cfg_bits(struct v3dv_pipeline *pipeline, + const VkPipelineDepthStencilStateCreateInfo *ds_info, + const VkPipelineRasterizationStateCreateInfo *rs_info, + const VkPipelineColorBlendStateCreateInfo *cb_info) +{ + assert(sizeof(pipeline->cfg_bits) == cl_packet_length(CFG_BITS)); + + /* CFG_BITS allow to set a overall blend_enable that it is anded with the + * per-target blend enable. v3d so far creates a mask with each target, so + * we just set to true if any attachment has blending enabled + */ + bool overall_blend_enable = false; + if (cb_info) { + for (uint32_t i = 0; i < cb_info->attachmentCount; i++) { + const VkPipelineColorBlendAttachmentState *b_state = + &cb_info->pAttachments[i]; + + overall_blend_enable |= b_state->blendEnable; + } + } + + v3dv_pack(pipeline->cfg_bits, CFG_BITS, config) { + config.enable_forward_facing_primitive = + rs_info ? !(rs_info->cullMode & VK_CULL_MODE_FRONT_BIT) : false; + + config.enable_reverse_facing_primitive = + rs_info ? !(rs_info->cullMode & VK_CULL_MODE_BACK_BIT) : false; + + config.clockwise_primitives = + rs_info ? rs_info->frontFace == VK_FRONT_FACE_CLOCKWISE : false; + + config.enable_depth_offset = rs_info ? rs_info->depthBiasEnable: false; + + /* FIXME: oversample_mode postponed until msaa gets supported */ + config.rasterizer_oversample_mode = false; + + config.direct3d_provoking_vertex = false; /* FIXME */ + + config.blend_enable = overall_blend_enable; + + /* Note: ez state may update based on the compiled FS, along with zsa + * (FIXME: not done) + */ + config.early_z_updates_enable = true; + if (ds_info && ds_info->depthTestEnable) { + config.z_updates_enable = false; + config.early_z_enable = config.early_z_enable; + config.depth_test_function = ds_info->depthCompareOp; + } else { + config.depth_test_function = VK_COMPARE_OP_ALWAYS; + } + + config.stencil_enable = ds_info ? ds_info->stencilTestEnable : false; + }; +} + static VkResult pipeline_init(struct v3dv_pipeline *pipeline, struct v3dv_device *device, @@ -771,6 +830,23 @@ pipeline_init(struct v3dv_pipeline *pipeline, pipeline_init_dynamic_state(pipeline, pCreateInfo); + /* If rasterization is not enabled, various CreateInfo structs must be + * ignored. + */ + const bool raster_enabled = + !pCreateInfo->pRasterizationState->rasterizerDiscardEnable; + + const VkPipelineDepthStencilStateCreateInfo *ds_info = + raster_enabled ? pCreateInfo->pDepthStencilState : NULL; + + const VkPipelineRasterizationStateCreateInfo *rs_info = + raster_enabled ? pCreateInfo->pRasterizationState : NULL; + + const VkPipelineColorBlendStateCreateInfo *cb_info = + raster_enabled ? pCreateInfo->pColorBlendState : NULL; + + pack_cfg_bits(pipeline, ds_info, rs_info, cb_info); + result = pipeline_compile_graphics(pipeline, pCreateInfo, alloc); if (result != VK_SUCCESS) { diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 32400b96b30..8f617f29c6d 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -84,6 +84,8 @@ pack_emit_reloc(void *cl, const void *reloc) {} */ #include "util/u_box.h" +#include "broadcom/cle/v3dx_pack.h" + /* A non-fatal assert. Useful for debugging. */ #ifdef DEBUG #define v3dv_assert(x) ({ \ @@ -596,6 +598,10 @@ struct v3dv_pipeline { struct v3dv_pipeline_stage *fs; struct v3dv_dynamic_state dynamic_state; + + /* Packets prepacked during pipeline creation + */ + uint8_t cfg_bits[cl_packet_length(CFG_BITS)]; }; uint32_t v3dv_physical_device_api_version(struct v3dv_physical_device *dev);