diff --git a/src/imagination/vulkan/pvr_csb.h b/src/imagination/vulkan/pvr_csb.h index 07001299c7c..2ff428df5f5 100644 --- a/src/imagination/vulkan/pvr_csb.h +++ b/src/imagination/vulkan/pvr_csb.h @@ -131,27 +131,6 @@ VkResult pvr_csb_emit_terminate(struct pvr_csb *csb); #define pvr_cmd_header(x) PVRX(x##_header) #define pvr_cmd_pack(x) PVRX(x##_pack) -/** - * \brief Packs a command/state into one or more dwords and stores them in the - * memory pointed to by _dst. - * - * \param[out] _dst Pointer to store the packed command/state. - * \param[in] cmd Command/state type. - * \param[in,out] name Name to give to the command/state structure variable, - * which contains the information to be packed and emitted. - * This can be used by the caller to modify the command or - * state information before it's packed. - */ -#define pvr_csb_pack(_dst, cmd, name) \ - for (struct PVRX(cmd) name = { pvr_cmd_header(cmd) }, \ - *_loop_terminate = &name; \ - __builtin_expect(_loop_terminate != NULL, 1); \ - ({ \ - STATIC_ASSERT(sizeof(*(_dst)) == pvr_cmd_length(cmd) * 4); \ - pvr_cmd_pack(cmd)((_dst), &name); \ - _loop_terminate = NULL; \ - })) - /** * \brief Merges dwords0 and dwords1 arrays and stores the result into the * control stream pointed by the csb object. @@ -208,4 +187,76 @@ VkResult pvr_csb_emit_terminate(struct pvr_csb *csb); *dw = dword; \ } while (0) +/** + * \name Raw command/state buffer helpers. + * These provide functionality to write control/state words to a raw buffer, + * accessed through a pointer, with some extra checks. + * + * The raw buffer doesn't have to be related to a control stream builder object + * so these can be used with any cpu accessible buffer. + */ +/**@{*/ + +/** + * \brief Packs a command/state into one or more dwords and stores them in the + * memory pointed to by _dst. + * + * \param[out] _dst Pointer to store the packed command/state. + * \param[in] cmd Command/state type. + * \param[in,out] name Name to give to the command/state structure variable, + * which contains the information to be packed and emitted. + * This can be used by the caller to modify the command or + * state information before it's packed. + */ +#define pvr_csb_pack(_dst, cmd, name) \ + for (struct PVRX(cmd) name = { pvr_cmd_header(cmd) }, \ + *_loop_terminate = &name; \ + __builtin_expect(_loop_terminate != NULL, 1); \ + ({ \ + STATIC_ASSERT(sizeof(*(_dst)) == pvr_cmd_length(cmd) * 4); \ + pvr_cmd_pack(cmd)((_dst), &name); \ + _loop_terminate = NULL; \ + })) + +/** + * \brief Writes a command/state word value into a raw buffer and advance. + * + * The buffer pointer is incremented appropriately based on the control stream + * word length. + * + * \param[in,out] dst Raw buffer pointer for writing. + * \param[in] cmd Command/state type. + * \param[in] val Pre-packed value to write. + */ +#define pvr_csb_write_value(dst, cmd, val) \ + do { \ + static_assert(sizeof(*(dst)) == pvr_cmd_length(cmd) * sizeof(uint32_t), \ + "Size mismatch"); \ + static_assert(sizeof(*(dst)) == sizeof(val), "Size mismatch"); \ + *(dst) = (val); \ + (dst)++; \ + } while (0) + +/** + * \brief Packs a command/state word struct and writes the value into a raw + * buffer and advance. + * + * The buffer pointer is incremented appropriately based on the control stream + * word length. + * + * \param[in,out] dst Raw buffer pointer for writing. + * \param[in] cmd Command/state type. + * \param[in] val Command/state struct to pack and write. + */ +#define pvr_csb_write_struct(dst, cmd, val) \ + do { \ + static_assert(sizeof(*(dst)) == pvr_cmd_length(cmd) * sizeof(uint32_t), \ + "Size mismatch"); \ + pvr_cmd_pack(cmd)((dst), (val)); \ + (dst)++; \ + } while (0) + +/**@}*/ +/* End of \name Raw command/state buffer helpers. */ + #endif /* PVR_CSB_H */ diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index 13890b6efd3..1448691cd3a 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -1620,29 +1620,12 @@ VkResult pvr_emit_ppp_from_template( return result; } -#define CS_WRITE(_dst, cmd, val) \ - do { \ - static_assert(sizeof(*(_dst)) == pvr_cmd_length(cmd) * 4, \ - "Size mismatch"); \ - static_assert(sizeof(*(_dst)) == sizeof(val), "Size mismatch"); \ - *(_dst) = val; \ - (_dst) += pvr_cmd_length(cmd); \ - } while (0) - -#define CS_PACK_WRITE(_dst, cmd, val) \ - do { \ - static_assert(sizeof(*(_dst)) == pvr_cmd_length(cmd) * 4, \ - "Size mismatch"); \ - pvr_cmd_pack(cmd)((_dst), val); \ - (_dst) += pvr_cmd_length(cmd); \ - } while (0) - stream = (uint32_t *)pvr_bo->bo->map; - CS_WRITE(stream, TA_STATE_HEADER, template->header); - CS_PACK_WRITE(stream, TA_STATE_ISPCTL, &template->config.ispctl); - CS_PACK_WRITE(stream, TA_STATE_ISPA, &template->config.ispa); - CS_WRITE(stream, TA_STATE_ISPB, template->ispb); + pvr_csb_write_value(stream, TA_STATE_HEADER, template->header); + pvr_csb_write_struct(stream, TA_STATE_ISPCTL, &template->config.ispctl); + pvr_csb_write_struct(stream, TA_STATE_ISPA, &template->config.ispa); + pvr_csb_write_value(stream, TA_STATE_ISPB, template->ispb); if (template->requires_pds_state) { static_assert(sizeof(*stream) == sizeof((*template->config.pds_state)[0]), @@ -1651,24 +1634,25 @@ VkResult pvr_emit_ppp_from_template( *stream++ = (*template->config.pds_state)[i]; } - CS_PACK_WRITE(stream, TA_REGION_CLIP0, &template->config.region_clip0); - CS_PACK_WRITE(stream, TA_REGION_CLIP1, &template->config.region_clip1); - CS_WRITE(stream, TA_WCLAMP, base->wclamp); - CS_PACK_WRITE(stream, TA_OUTPUT_SEL, &template->config.output_sel); - CS_WRITE(stream, TA_STATE_VARYING0, base->varying_word[0]); - CS_WRITE(stream, TA_STATE_VARYING1, base->varying_word[1]); - CS_WRITE(stream, TA_STATE_VARYING2, base->varying_word[2]); - CS_WRITE(stream, TA_STATE_PPP_CTRL, base->ppp_ctrl); - CS_WRITE(stream, TA_STATE_STREAM_OUT0, base->stream_out0); + pvr_csb_write_struct(stream, + TA_REGION_CLIP0, + &template->config.region_clip0); + pvr_csb_write_struct(stream, + TA_REGION_CLIP1, + &template->config.region_clip1); + pvr_csb_write_value(stream, TA_WCLAMP, base->wclamp); + pvr_csb_write_struct(stream, TA_OUTPUT_SEL, &template->config.output_sel); + pvr_csb_write_value(stream, TA_STATE_VARYING0, base->varying_word[0]); + pvr_csb_write_value(stream, TA_STATE_VARYING1, base->varying_word[1]); + pvr_csb_write_value(stream, TA_STATE_VARYING2, base->varying_word[2]); + pvr_csb_write_value(stream, TA_STATE_PPP_CTRL, base->ppp_ctrl); + pvr_csb_write_value(stream, TA_STATE_STREAM_OUT0, base->stream_out0); assert((uint64_t)(stream - (uint32_t *)pvr_bo->bo->map) == dword_count); pvr_bo_cpu_unmap(device, pvr_bo); stream = NULL; -#undef CS_PACK_WRITE -#undef CS_WRITE - pvr_csb_emit (csb, VDMCTRL_PPP_STATE0, state) { state.word_count = dword_count; state.addrmsb = pvr_bo->vma->dev_addr;