blob: c80b686a22e859e28d8c35a3c2fdff6579ef3cad [file] [log] [blame]
Chia-I Wu525c6602014-08-27 10:22:34 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the 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
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
Chia-I Wu525c6602014-08-27 10:22:34 +080026 */
27
28#include "genhw/genhw.h"
29#include "img.h"
30#include "mem.h"
31#include "cmd_priv.h"
32
33enum {
34 MEM_CACHE = 1 << 0,
35 DATA_READ_CACHE = 1 << 1,
36 DATA_WRITE_CACHE = 1 << 2,
37 RENDER_CACHE = 1 << 3,
38 SAMPLER_CACHE = 1 << 4,
39};
40
41static uint32_t mem_get_state_caches(const struct intel_mem *mem,
42 XGL_MEMORY_STATE state)
43{
44 uint32_t caches;
45
46 switch (state) {
47 case XGL_MEMORY_STATE_DATA_TRANSFER:
48 case XGL_MEMORY_STATE_INDEX_DATA:
49 case XGL_MEMORY_STATE_INDIRECT_ARG:
50 case XGL_MEMORY_STATE_WRITE_TIMESTAMP:
51 case XGL_MEMORY_STATE_QUEUE_ATOMIC:
52 caches = MEM_CACHE;
53 break;
54 case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY:
55 case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_ONLY:
56 case XGL_MEMORY_STATE_MULTI_SHADER_READ_ONLY:
57 caches = DATA_READ_CACHE;
58 break;
59 case XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY:
60 case XGL_MEMORY_STATE_COMPUTE_SHADER_WRITE_ONLY:
61 caches = DATA_WRITE_CACHE;
62 break;
63 case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_WRITE:
64 case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_WRITE:
65 caches = DATA_READ_CACHE | DATA_WRITE_CACHE;
66 break;
67 default:
68 caches = 0;
69 break;
70 }
71
72 return caches;
73}
74
75static uint32_t cmd_get_mem_flush_flags(const struct intel_cmd *cmd,
76 const struct intel_mem *mem,
77 uint32_t old_caches,
78 uint32_t new_caches)
79{
80 uint32_t flags = 0;
81
82 /* not dirty */
83 if (!(old_caches & (MEM_CACHE | DATA_WRITE_CACHE)))
84 return 0;
85
86 if ((old_caches & DATA_WRITE_CACHE) &&
87 (new_caches & ~(DATA_READ_CACHE | DATA_WRITE_CACHE))) {
88 if (cmd_gen(cmd) >= INTEL_GEN(7))
89 flags |= GEN7_PIPE_CONTROL_DC_FLUSH_ENABLE;
90 }
91
92 if ((new_caches & DATA_READ_CACHE) && old_caches != DATA_WRITE_CACHE)
93 flags |= GEN6_PIPE_CONTROL_CONSTANT_CACHE_INVALIDATE;
94
95 if (!flags)
96 return 0;
97
98 flags |= GEN6_PIPE_CONTROL_CS_STALL;
99
100 return flags;
101}
102
103static uint32_t img_get_state_caches(const struct intel_img *img,
104 XGL_IMAGE_STATE state)
105{
106 uint32_t caches;
107
108 switch (state) {
109 case XGL_IMAGE_STATE_DATA_TRANSFER:
110 caches = MEM_CACHE;
111 break;
112 case XGL_IMAGE_STATE_GRAPHICS_SHADER_WRITE_ONLY:
113 case XGL_IMAGE_STATE_COMPUTE_SHADER_WRITE_ONLY:
114 caches = DATA_WRITE_CACHE;
115 break;
116 case XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_ONLY:
117 case XGL_IMAGE_STATE_MULTI_SHADER_READ_ONLY:
118 case XGL_IMAGE_STATE_TARGET_AND_SHADER_READ_ONLY:
119 caches = DATA_READ_CACHE | SAMPLER_CACHE;
120 break;
121 case XGL_IMAGE_STATE_COMPUTE_SHADER_READ_ONLY:
122 caches = DATA_READ_CACHE;
123 break;
124 case XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_WRITE:
125 caches = DATA_READ_CACHE | DATA_WRITE_CACHE | SAMPLER_CACHE;
126 break;
127 case XGL_IMAGE_STATE_COMPUTE_SHADER_READ_WRITE:
128 caches = DATA_READ_CACHE | DATA_WRITE_CACHE;
129 break;
130 case XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL:
131 case XGL_IMAGE_STATE_TARGET_SHADER_ACCESS_OPTIMAL:
132 caches = RENDER_CACHE | DATA_WRITE_CACHE;
133 break;
134 case XGL_IMAGE_STATE_CLEAR:
135 case XGL_IMAGE_STATE_RESOLVE_DESTINATION:
136 caches = RENDER_CACHE;
137 break;
138 case XGL_IMAGE_STATE_RESOLVE_SOURCE:
139 caches = SAMPLER_CACHE;
140 break;
141 default:
142 caches = 0;
143 break;
144 }
145
146 return caches;
147}
148
149static uint32_t cmd_get_img_flush_flags(const struct intel_cmd *cmd,
150 const struct intel_img *img,
151 uint32_t old_caches,
152 uint32_t new_caches)
153{
154 uint32_t flags = 0;
155
156 /* not dirty */
157 if (!(old_caches & (MEM_CACHE | RENDER_CACHE | DATA_WRITE_CACHE)))
158 return 0;
159
160 if ((old_caches & RENDER_CACHE) && (new_caches & ~RENDER_CACHE)) {
161 if (img->layout.format.numericFormat == XGL_NUM_FMT_DS)
162 flags |= GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH;
163 else
164 flags |= GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH;
165 }
166
167 if ((old_caches & DATA_WRITE_CACHE) &&
168 (new_caches & ~(DATA_READ_CACHE | DATA_WRITE_CACHE))) {
169 if (cmd_gen(cmd) >= INTEL_GEN(7))
170 flags |= GEN7_PIPE_CONTROL_DC_FLUSH_ENABLE;
171 }
172
173 if (new_caches & SAMPLER_CACHE)
174 flags |= GEN6_PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
175
176 if ((new_caches & DATA_READ_CACHE) && old_caches != DATA_WRITE_CACHE)
177 flags |= GEN6_PIPE_CONTROL_CONSTANT_CACHE_INVALIDATE;
178
179 if (!flags)
180 return 0;
181
182 flags |= GEN6_PIPE_CONTROL_CS_STALL;
183
184 return flags;
185}
186
187XGL_VOID XGLAPI intelCmdPrepareMemoryRegions(
188 XGL_CMD_BUFFER cmdBuffer,
189 XGL_UINT transitionCount,
190 const XGL_MEMORY_STATE_TRANSITION* pStateTransitions)
191{
192 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
193 uint32_t flush_flags = 0;
194 XGL_UINT i;
195
196 for (i = 0; i < transitionCount; i++) {
197 const XGL_MEMORY_STATE_TRANSITION *trans = &pStateTransitions[i];
198 struct intel_mem *mem = intel_mem(trans->mem);
199
200 flush_flags |= cmd_get_mem_flush_flags(cmd, mem,
201 mem_get_state_caches(mem, trans->oldState),
202 mem_get_state_caches(mem, trans->newState));
203 }
204
205 cmd_batch_flush(cmd, flush_flags);
206}
207
208XGL_VOID XGLAPI intelCmdPrepareImages(
209 XGL_CMD_BUFFER cmdBuffer,
210 XGL_UINT transitionCount,
211 const XGL_IMAGE_STATE_TRANSITION* pStateTransitions)
212{
213 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
214 uint32_t flush_flags = 0;
215 XGL_UINT i;
216
217 for (i = 0; i < transitionCount; i++) {
218 const XGL_IMAGE_STATE_TRANSITION *trans = &pStateTransitions[i];
219 struct intel_img *img = intel_img(trans->image);
220
221 flush_flags |= cmd_get_img_flush_flags(cmd, img,
222 img_get_state_caches(img, trans->oldState),
223 img_get_state_caches(img, trans->newState));
224 }
225
226 cmd_batch_flush(cmd, flush_flags);
227}