101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2016-2018 Broadcom
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#include <ctype.h>
2501e04c3fSmrg#include <stdlib.h>
2601e04c3fSmrg#include <string.h>
2701e04c3fSmrg#include "util/macros.h"
2801e04c3fSmrg#include "broadcom/cle/v3d_decoder.h"
2901e04c3fSmrg#include "clif_dump.h"
3001e04c3fSmrg#include "clif_private.h"
3101e04c3fSmrg
3201e04c3fSmrg#define __gen_user_data void
3301e04c3fSmrg#define __gen_address_type uint32_t
3401e04c3fSmrg#define __gen_address_offset(reloc) (*reloc)
3501e04c3fSmrg#define __gen_emit_reloc(cl, reloc)
3601e04c3fSmrg#define __gen_unpack_address(cl, s, e) (__gen_unpack_uint(cl, s, e) << (31 - (e - s)))
3701e04c3fSmrg#include "broadcom/cle/v3dx_pack.h"
3801e04c3fSmrg#include "broadcom/common/v3d_macros.h"
3901e04c3fSmrg
4001e04c3fSmrgstatic char *
4101e04c3fSmrgclif_name(const char *xml_name)
4201e04c3fSmrg{
4301e04c3fSmrg        char *name = malloc(strlen(xml_name) + 1);
4401e04c3fSmrg
4501e04c3fSmrg        int j = 0;
4601e04c3fSmrg        for (int i = 0; i < strlen(xml_name); i++) {
4701e04c3fSmrg                if (xml_name[i] == ' ') {
4801e04c3fSmrg                        name[j++] = '_';
4901e04c3fSmrg                } else if (xml_name[i] == '(' || xml_name[i] == ')') {
5001e04c3fSmrg                        /* skip */
5101e04c3fSmrg                } else {
5201e04c3fSmrg                        name[j++] = toupper(xml_name[i]);
5301e04c3fSmrg                }
5401e04c3fSmrg        }
5501e04c3fSmrg        name[j++] = 0;
5601e04c3fSmrg
5701e04c3fSmrg        return name;
5801e04c3fSmrg}
5901e04c3fSmrg
6001e04c3fSmrgbool
6101e04c3fSmrgv3dX(clif_dump_packet)(struct clif_dump *clif, uint32_t offset,
6201e04c3fSmrg                       const uint8_t *cl, uint32_t *size, bool reloc_mode)
6301e04c3fSmrg{
6401e04c3fSmrg        struct v3d_group *inst = v3d_spec_find_instruction(clif->spec, cl);
6501e04c3fSmrg        if (!inst) {
6601e04c3fSmrg                out(clif, "0x%08x: Unknown packet %d!\n", offset, *cl);
6701e04c3fSmrg                return false;
6801e04c3fSmrg        }
6901e04c3fSmrg
7001e04c3fSmrg        *size = v3d_group_get_length(inst);
7101e04c3fSmrg
7201e04c3fSmrg        if (!reloc_mode) {
7301e04c3fSmrg                char *name = clif_name(v3d_group_get_name(inst));
7401e04c3fSmrg                out(clif, "%s\n", name);
7501e04c3fSmrg                free(name);
7601e04c3fSmrg                v3d_print_group(clif, inst, 0, cl);
7701e04c3fSmrg        }
7801e04c3fSmrg
7901e04c3fSmrg        switch (*cl) {
8001e04c3fSmrg        case V3DX(GL_SHADER_STATE_opcode): {
8101e04c3fSmrg                struct V3DX(GL_SHADER_STATE) values;
8201e04c3fSmrg                V3DX(GL_SHADER_STATE_unpack)(cl, &values);
8301e04c3fSmrg
8401e04c3fSmrg                if (reloc_mode) {
8501e04c3fSmrg                        struct reloc_worklist_entry *reloc =
8601e04c3fSmrg                                clif_dump_add_address_to_worklist(clif,
8701e04c3fSmrg                                                                  reloc_gl_shader_state,
8801e04c3fSmrg                                                                  values.address);
8901e04c3fSmrg                        if (reloc) {
9001e04c3fSmrg                                reloc->shader_state.num_attrs =
9101e04c3fSmrg                                        values.number_of_attribute_arrays;
9201e04c3fSmrg                        }
9301e04c3fSmrg                }
9401e04c3fSmrg                return true;
9501e04c3fSmrg        }
9601e04c3fSmrg
9701e04c3fSmrg#if V3D_VERSION < 40
9801e04c3fSmrg        case V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_opcode): {
9901e04c3fSmrg                struct V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED) values;
10001e04c3fSmrg                V3DX(STORE_MULTI_SAMPLE_RESOLVED_TILE_COLOR_BUFFER_EXTENDED_unpack)(cl, &values);
10101e04c3fSmrg
10201e04c3fSmrg                if (values.last_tile_of_frame)
10301e04c3fSmrg                        return false;
10401e04c3fSmrg                break;
10501e04c3fSmrg        }
10601e04c3fSmrg#endif /* V3D_VERSION < 40 */
10701e04c3fSmrg
10801e04c3fSmrg#if V3D_VERSION > 40
10901e04c3fSmrg        case V3DX(TRANSFORM_FEEDBACK_SPECS_opcode): {
11001e04c3fSmrg                struct V3DX(TRANSFORM_FEEDBACK_SPECS) values;
11101e04c3fSmrg                V3DX(TRANSFORM_FEEDBACK_SPECS_unpack)(cl, &values);
11201e04c3fSmrg                struct v3d_group *spec = v3d_spec_find_struct(clif->spec,
11301e04c3fSmrg                                                              "Transform Feedback Output Data Spec");
11401e04c3fSmrg                assert(spec);
11501e04c3fSmrg
11601e04c3fSmrg                cl += *size;
11701e04c3fSmrg
11801e04c3fSmrg                for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) {
11901e04c3fSmrg                        if (!reloc_mode)
12001e04c3fSmrg                                v3d_print_group(clif, spec, 0, cl);
12101e04c3fSmrg                        cl += v3d_group_get_length(spec);
12201e04c3fSmrg                        *size += v3d_group_get_length(spec);
12301e04c3fSmrg                }
12401e04c3fSmrg                if (!reloc_mode)
12501e04c3fSmrg                        out(clif, "@format ctrllist\n");
12601e04c3fSmrg                break;
12701e04c3fSmrg        }
12801e04c3fSmrg#else /* V3D_VERSION < 40 */
12901e04c3fSmrg        case V3DX(TRANSFORM_FEEDBACK_ENABLE_opcode): {
13001e04c3fSmrg                struct V3DX(TRANSFORM_FEEDBACK_ENABLE) values;
13101e04c3fSmrg                V3DX(TRANSFORM_FEEDBACK_ENABLE_unpack)(cl, &values);
13201e04c3fSmrg                struct v3d_group *spec = v3d_spec_find_struct(clif->spec,
13301e04c3fSmrg                                                              "Transform Feedback Output Data Spec");
13401e04c3fSmrg                struct v3d_group *addr = v3d_spec_find_struct(clif->spec,
13501e04c3fSmrg                                                              "Transform Feedback Output Address");
13601e04c3fSmrg                assert(spec);
13701e04c3fSmrg                assert(addr);
13801e04c3fSmrg
13901e04c3fSmrg                cl += *size;
14001e04c3fSmrg
14101e04c3fSmrg                for (int i = 0; i < values.number_of_16_bit_output_data_specs_following; i++) {
14201e04c3fSmrg                        if (!reloc_mode)
14301e04c3fSmrg                                v3d_print_group(clif, spec, 0, cl);
14401e04c3fSmrg                        cl += v3d_group_get_length(spec);
14501e04c3fSmrg                        *size += v3d_group_get_length(spec);
14601e04c3fSmrg                }
14701e04c3fSmrg
14801e04c3fSmrg                for (int i = 0; i < values.number_of_32_bit_output_buffer_address_following; i++) {
14901e04c3fSmrg                        if (!reloc_mode)
15001e04c3fSmrg                                v3d_print_group(clif, addr, 0, cl);
15101e04c3fSmrg                        cl += v3d_group_get_length(addr);
15201e04c3fSmrg                        *size += v3d_group_get_length(addr);
15301e04c3fSmrg                }
15401e04c3fSmrg                break;
15501e04c3fSmrg        }
15601e04c3fSmrg#endif /* V3D_VERSION < 40 */
15701e04c3fSmrg
15801e04c3fSmrg        case V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST_opcode): {
15901e04c3fSmrg                struct V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST) values;
16001e04c3fSmrg                V3DX(START_ADDRESS_OF_GENERIC_TILE_LIST_unpack)(cl, &values);
16101e04c3fSmrg                struct reloc_worklist_entry *reloc =
16201e04c3fSmrg                        clif_dump_add_address_to_worklist(clif,
16301e04c3fSmrg                                                          reloc_generic_tile_list,
16401e04c3fSmrg                                                          values.start);
16501e04c3fSmrg                reloc->generic_tile_list.end = values.end;
16601e04c3fSmrg                break;
16701e04c3fSmrg        }
16801e04c3fSmrg
16901e04c3fSmrg        case V3DX(HALT_opcode):
17001e04c3fSmrg                return false;
17101e04c3fSmrg        }
17201e04c3fSmrg
17301e04c3fSmrg        return true;
17401e04c3fSmrg}
175