• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 Rob Clark <robclark@freedesktop.org>
3  * Copyright © 2018 Google, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *    Rob Clark <robclark@freedesktop.org>
26  */
27 
28 #include "pipe/p_state.h"
29 
30 #include "freedreno_resource.h"
31 #include "freedreno_state.h"
32 
33 #include "fd6_image.h"
34 #include "fd6_resource.h"
35 #include "fd6_texture.h"
36 
37 static const uint8_t swiz_identity[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
38                                          PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W};
39 
40 static void
fd6_emit_single_plane_descriptor(struct fd_ringbuffer * ring,struct pipe_resource * prsc,uint32_t * descriptor)41 fd6_emit_single_plane_descriptor(struct fd_ringbuffer *ring,
42                                  struct pipe_resource *prsc,
43                                  uint32_t *descriptor)
44 {
45    /* If the resource isn't present (holes are allowed), zero-fill the slot. */
46    if (!prsc) {
47       for (int i = 0; i < 16; i++)
48          OUT_RING(ring, 0);
49       return;
50    }
51 
52    struct fd_resource *rsc = fd_resource(prsc);
53    for (int i = 0; i < 4; i++)
54       OUT_RING(ring, descriptor[i]);
55 
56    OUT_RELOC(ring, rsc->bo, descriptor[4], (uint64_t)descriptor[5] << 32, 0);
57 
58    OUT_RING(ring, descriptor[6]);
59 
60    OUT_RELOC(ring, rsc->bo, descriptor[7], (uint64_t)descriptor[8] << 32, 0);
61 
62    for (int i = 9; i < FDL6_TEX_CONST_DWORDS; i++)
63       OUT_RING(ring, descriptor[i]);
64 }
65 
66 static void
fd6_ssbo_descriptor(struct fd_context * ctx,const struct pipe_shader_buffer * buf,uint32_t * descriptor)67 fd6_ssbo_descriptor(struct fd_context *ctx,
68                     const struct pipe_shader_buffer *buf, uint32_t *descriptor)
69 {
70    fdl6_buffer_view_init(
71       descriptor,
72       ctx->screen->info->a6xx.storage_16bit ? PIPE_FORMAT_R16_UINT
73                                             : PIPE_FORMAT_R32_UINT,
74       swiz_identity, buf->buffer_offset, /* Using relocs for addresses */
75       buf->buffer_size);
76 }
77 
78 static void
fd6_emit_image_descriptor(struct fd_context * ctx,struct fd_ringbuffer * ring,const struct pipe_image_view * buf,bool ibo)79 fd6_emit_image_descriptor(struct fd_context *ctx, struct fd_ringbuffer *ring, const struct pipe_image_view *buf, bool ibo)
80 {
81    struct fd_resource *rsc = fd_resource(buf->resource);
82    if (!rsc) {
83       for (int i = 0; i < FDL6_TEX_CONST_DWORDS; i++)
84          OUT_RING(ring, 0);
85       return;
86    }
87 
88    if (buf->resource->target == PIPE_BUFFER) {
89    uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
90       fdl6_buffer_view_init(descriptor, buf->format, swiz_identity,
91                            buf->u.buf.offset, /* Using relocs for addresses */
92                            buf->u.buf.size);
93    fd6_emit_single_plane_descriptor(ring, buf->resource, descriptor);
94    } else {
95       struct fdl_view_args args = {
96          /* Using relocs for addresses */
97          .iova = 0,
98 
99          .base_miplevel = buf->u.tex.level,
100          .level_count = 1,
101 
102          .base_array_layer = buf->u.tex.first_layer,
103          .layer_count = buf->u.tex.last_layer - buf->u.tex.first_layer + 1,
104 
105          .format = buf->format,
106          .swiz = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z,
107                   PIPE_SWIZZLE_W},
108 
109          .type = fdl_type_from_pipe_target(buf->resource->target),
110          .chroma_offsets = {FDL_CHROMA_LOCATION_COSITED_EVEN,
111                             FDL_CHROMA_LOCATION_COSITED_EVEN},
112       };
113 
114       /* fdl6_view makes the storage descriptor treat cubes like a 2D array (so
115        * you can reference a specific layer), but we need to do that for the
116        * texture descriptor as well to get our layer.
117        */
118       if (args.type == FDL_VIEW_TYPE_CUBE)
119          args.type = FDL_VIEW_TYPE_2D;
120 
121       struct fdl6_view view;
122       const struct fdl_layout *layouts[3] = {&rsc->layout, NULL, NULL};
123       fdl6_view_init(&view, layouts, &args,
124                      ctx->screen->info->a6xx.has_z24uint_s8uint);
125       if (ibo)
126          fd6_emit_single_plane_descriptor(ring, buf->resource, view.storage_descriptor);
127       else
128          fd6_emit_single_plane_descriptor(ring, buf->resource, view.descriptor);
129    }
130 }
131 
132 void
fd6_emit_image_tex(struct fd_context * ctx,struct fd_ringbuffer * ring,const struct pipe_image_view * pimg)133 fd6_emit_image_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
134                    const struct pipe_image_view *pimg)
135 {
136    fd6_emit_image_descriptor(ctx, ring, pimg, false);
137 }
138 
139 void
fd6_emit_ssbo_tex(struct fd_context * ctx,struct fd_ringbuffer * ring,const struct pipe_shader_buffer * pbuf)140 fd6_emit_ssbo_tex(struct fd_context *ctx, struct fd_ringbuffer *ring,
141                   const struct pipe_shader_buffer *pbuf)
142 {
143    uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
144    fd6_ssbo_descriptor(ctx, pbuf, descriptor);
145    fd6_emit_single_plane_descriptor(ring, pbuf->buffer, descriptor);
146 }
147 
148 /* Build combined image/SSBO "IBO" state, returns ownership of state reference */
149 struct fd_ringbuffer *
fd6_build_ibo_state(struct fd_context * ctx,const struct ir3_shader_variant * v,enum pipe_shader_type shader)150 fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
151                     enum pipe_shader_type shader)
152 {
153    struct fd_shaderbuf_stateobj *bufso = &ctx->shaderbuf[shader];
154    struct fd_shaderimg_stateobj *imgso = &ctx->shaderimg[shader];
155 
156    struct fd_ringbuffer *state = fd_submit_new_ringbuffer(
157       ctx->batch->submit,
158       ir3_shader_nibo(v) * 16 * 4,
159       FD_RINGBUFFER_STREAMING);
160 
161    assert(shader == PIPE_SHADER_COMPUTE || shader == PIPE_SHADER_FRAGMENT);
162 
163    uint32_t descriptor[FDL6_TEX_CONST_DWORDS];
164    for (unsigned i = 0; i < v->num_ssbos; i++) {
165       fd6_ssbo_descriptor(ctx, &bufso->sb[i], descriptor);
166       fd6_emit_single_plane_descriptor(state, bufso->sb[i].buffer, descriptor);
167    }
168 
169    for (unsigned i = v->num_ssbos; i < v->num_ibos; i++) {
170       fd6_emit_image_descriptor(ctx, state, &imgso->si[i - v->num_ssbos], true);
171    }
172 
173    return state;
174 }
175 
176 static void
fd6_set_shader_images(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start,unsigned count,unsigned unbind_num_trailing_slots,const struct pipe_image_view * images)177 fd6_set_shader_images(struct pipe_context *pctx, enum pipe_shader_type shader,
178                       unsigned start, unsigned count,
179                       unsigned unbind_num_trailing_slots,
180                       const struct pipe_image_view *images) in_dt
181 {
182    struct fd_context *ctx = fd_context(pctx);
183    struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader];
184 
185    fd_set_shader_images(pctx, shader, start, count, unbind_num_trailing_slots,
186                         images);
187 
188    if (!images)
189       return;
190 
191    for (unsigned i = 0; i < count; i++) {
192       unsigned n = i + start;
193       struct pipe_image_view *buf = &so->si[n];
194 
195       if (!buf->resource)
196          continue;
197 
198       fd6_validate_format(ctx, fd_resource(buf->resource), buf->format);
199    }
200 }
201 
202 void
fd6_image_init(struct pipe_context * pctx)203 fd6_image_init(struct pipe_context *pctx)
204 {
205    pctx->set_shader_images = fd6_set_shader_images;
206 }
207