1 /**************************************************************************
3 * Copyright 2019 Sonny Jiang <sonnyj608@gmail.com>
4 * Copyright 2019 Advanced Micro Devices, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 #include "pipe/p_context.h"
30 #include "pipe/p_state.h"
32 #include "u_bitcast.h"
33 #include "util/format/u_format.h"
34 #include "u_sampler.h"
35 #include "tgsi/tgsi_text.h"
36 #include "tgsi/tgsi_ureg.h"
37 #include "u_inlines.h"
38 #include "u_compute.h"
40 static void *blit_compute_shader(struct pipe_context
*ctx
)
42 static const char text
[] =
44 "PROPERTY CS_FIXED_BLOCK_WIDTH 64\n"
45 "PROPERTY CS_FIXED_BLOCK_HEIGHT 1\n"
46 "PROPERTY CS_FIXED_BLOCK_DEPTH 1\n"
47 "DCL SV[0], THREAD_ID\n"
48 "DCL SV[1], BLOCK_ID\n"
49 "DCL IMAGE[0], 2D_ARRAY, PIPE_FORMAT_R32G32B32A32_FLOAT, WR\n"
51 "DCL SVIEW[0], 2D_ARRAY, FLOAT\n"
52 "DCL CONST[0][0..2]\n" // 0:xyzw 1:xyzw
53 "DCL TEMP[0..4], LOCAL\n"
54 "IMM[0] UINT32 {64, 1, 0, 0}\n"
56 "UMAD TEMP[0].xyz, SV[1].xyzz, IMM[0].xyyy, SV[0].xyzz\n"
57 "U2F TEMP[1].xyz, TEMP[0]\n"
58 "MAD TEMP[2].xyz, TEMP[1], CONST[0][1], CONST[0][0]\n"
59 "TEX_LZ TEMP[3], TEMP[2], SAMP[0], 2D_ARRAY\n"
60 "UADD TEMP[4].xyz, TEMP[0], CONST[0][2]\n"
61 "STORE IMAGE[0], TEMP[4], TEMP[3], 2D_ARRAY, PIPE_FORMAT_R32G32B32A32_FLOAT\n"
64 struct tgsi_token tokens
[1024];
65 struct pipe_compute_state state
= {0};
67 if (!tgsi_text_translate(text
, tokens
, ARRAY_SIZE(tokens
))) {
72 state
.ir_type
= PIPE_SHADER_IR_TGSI
;
75 return ctx
->create_compute_state(ctx
, &state
);
78 void util_compute_blit(struct pipe_context
*ctx
, struct pipe_blit_info
*blit_info
,
81 if (blit_info
->src
.box
.width
== 0 || blit_info
->src
.box
.height
== 0 ||
82 blit_info
->dst
.box
.width
== 0 || blit_info
->dst
.box
.height
== 0)
85 struct pipe_resource
*src
= blit_info
->src
.resource
;
86 struct pipe_resource
*dst
= blit_info
->dst
.resource
;
87 struct pipe_sampler_view src_templ
= {0}, *src_view
;
88 void *sampler_state_p
;
89 unsigned width
= blit_info
->dst
.box
.width
;
90 unsigned height
= blit_info
->dst
.box
.height
;
91 float x_scale
= blit_info
->src
.box
.width
/ (float)blit_info
->dst
.box
.width
;
92 float y_scale
= blit_info
->src
.box
.height
/ (float)blit_info
->dst
.box
.height
;
93 float z_scale
= blit_info
->src
.box
.depth
/ (float)blit_info
->dst
.box
.depth
;
95 unsigned data
[] = {u_bitcast_f2u((blit_info
->src
.box
.x
+ 0.5) / (float)src
->width0
),
96 u_bitcast_f2u((blit_info
->src
.box
.y
+ 0.5) / (float)src
->height0
),
97 u_bitcast_f2u(blit_info
->src
.box
.z
),
99 u_bitcast_f2u(x_scale
/ src
->width0
),
100 u_bitcast_f2u(y_scale
/ src
->height0
),
101 u_bitcast_f2u(z_scale
),
103 blit_info
->dst
.box
.x
,
104 blit_info
->dst
.box
.y
,
105 blit_info
->dst
.box
.z
,
108 struct pipe_constant_buffer cb
= {0};
109 cb
.buffer_size
= sizeof(data
);
110 cb
.user_buffer
= data
;
111 ctx
->set_constant_buffer(ctx
, PIPE_SHADER_COMPUTE
, 0, &cb
);
113 struct pipe_image_view image
= {0};
114 image
.resource
= dst
;
115 image
.shader_access
= image
.access
= PIPE_IMAGE_ACCESS_WRITE
;
116 image
.format
= util_format_linear(blit_info
->dst
.format
);
117 image
.u
.tex
.level
= blit_info
->dst
.level
;
118 image
.u
.tex
.first_layer
= 0;
119 image
.u
.tex
.last_layer
= (unsigned)(dst
->array_size
- 1);
121 ctx
->set_shader_images(ctx
, PIPE_SHADER_COMPUTE
, 0, 1, &image
);
123 /* Initialize the sampler view. */
124 u_sampler_view_default_template(&src_templ
, src
, src
->format
);
125 src_templ
.format
= util_format_linear(blit_info
->src
.format
);
126 src_view
= ctx
->create_sampler_view(ctx
, src
, &src_templ
);
127 ctx
->set_sampler_views(ctx
, PIPE_SHADER_COMPUTE
, 0, 1, &src_view
);
129 struct pipe_sampler_state sampler_state
={0};
130 sampler_state
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
131 sampler_state
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
132 sampler_state
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
133 sampler_state
.normalized_coords
= 1;
135 if (blit_info
->filter
== PIPE_TEX_FILTER_LINEAR
) {
136 sampler_state
.min_img_filter
= PIPE_TEX_FILTER_LINEAR
;
137 sampler_state
.mag_img_filter
= PIPE_TEX_FILTER_LINEAR
;
140 sampler_state_p
= ctx
->create_sampler_state(ctx
, &sampler_state
);
141 ctx
->bind_sampler_states(ctx
, PIPE_SHADER_COMPUTE
, 0, 1, &sampler_state_p
);
144 *compute_state
= blit_compute_shader(ctx
);
145 ctx
->bind_compute_state(ctx
, *compute_state
);
147 struct pipe_grid_info grid_info
= {0};
148 grid_info
.block
[0] = 64;
149 grid_info
.last_block
[0] = width
% 64;
150 grid_info
.block
[1] = 1;
151 grid_info
.block
[2] = 1;
152 grid_info
.grid
[0] = DIV_ROUND_UP(width
, 64);
153 grid_info
.grid
[1] = height
;
154 grid_info
.grid
[2] = 1;
156 ctx
->launch_grid(ctx
, &grid_info
);
158 ctx
->memory_barrier(ctx
, PIPE_BARRIER_ALL
);
160 ctx
->set_shader_images(ctx
, PIPE_SHADER_COMPUTE
, 0, 1, NULL
);
161 ctx
->set_constant_buffer(ctx
, PIPE_SHADER_COMPUTE
, 0, NULL
);
162 ctx
->set_sampler_views(ctx
, PIPE_SHADER_COMPUTE
, 0, 1, NULL
);
163 pipe_sampler_view_reference(&src_view
, NULL
);
164 ctx
->delete_sampler_state(ctx
, sampler_state_p
);
165 ctx
->bind_compute_state(ctx
, NULL
);