blob: 07a8b92d779fc85e09f5ac4f5094e9b2e6d95bca [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.
23 */
24
25#include "genhw/genhw.h"
26#include "img.h"
27#include "mem.h"
28#include "cmd_priv.h"
29
30enum {
31 MEM_CACHE = 1 << 0,
32 DATA_READ_CACHE = 1 << 1,
33 DATA_WRITE_CACHE = 1 << 2,
34 RENDER_CACHE = 1 << 3,
35 SAMPLER_CACHE = 1 << 4,
36};
37
38static uint32_t mem_get_state_caches(const struct intel_mem *mem,
39 XGL_MEMORY_STATE state)
40{
41 uint32_t caches;
42
43 switch (state) {
44 case XGL_MEMORY_STATE_DATA_TRANSFER:
45 case XGL_MEMORY_STATE_INDEX_DATA:
46 case XGL_MEMORY_STATE_INDIRECT_ARG:
47 case XGL_MEMORY_STATE_WRITE_TIMESTAMP:
48 case XGL_MEMORY_STATE_QUEUE_ATOMIC:
49 caches = MEM_CACHE;
50 break;
51 case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY:
52 case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_ONLY:
53 case XGL_MEMORY_STATE_MULTI_SHADER_READ_ONLY:
54 caches = DATA_READ_CACHE;
55 break;
56 case XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY:
57 case XGL_MEMORY_STATE_COMPUTE_SHADER_WRITE_ONLY:
58 caches = DATA_WRITE_CACHE;
59 break;
60 case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_WRITE:
61 case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_WRITE:
62 caches = DATA_READ_CACHE | DATA_WRITE_CACHE;
63 break;
64 default:
65 caches = 0;
66 break;
67 }
68
69 return caches;
70}
71
72static uint32_t cmd_get_mem_flush_flags(const struct intel_cmd *cmd,
73 const struct intel_mem *mem,
74 uint32_t old_caches,
75 uint32_t new_caches)
76{
77 uint32_t flags = 0;
78
79 /* not dirty */
80 if (!(old_caches & (MEM_CACHE | DATA_WRITE_CACHE)))
81 return 0;
82
83 if ((old_caches & DATA_WRITE_CACHE) &&
84 (new_caches & ~(DATA_READ_CACHE | DATA_WRITE_CACHE))) {
85 if (cmd_gen(cmd) >= INTEL_GEN(7))
86 flags |= GEN7_PIPE_CONTROL_DC_FLUSH_ENABLE;
87 }
88
89 if ((new_caches & DATA_READ_CACHE) && old_caches != DATA_WRITE_CACHE)
90 flags |= GEN6_PIPE_CONTROL_CONSTANT_CACHE_INVALIDATE;
91
92 if (!flags)
93 return 0;
94
95 flags |= GEN6_PIPE_CONTROL_CS_STALL;
96
97 return flags;
98}
99
100static uint32_t img_get_state_caches(const struct intel_img *img,
101 XGL_IMAGE_STATE state)
102{
103 uint32_t caches;
104
105 switch (state) {
106 case XGL_IMAGE_STATE_DATA_TRANSFER:
107 caches = MEM_CACHE;
108 break;
109 case XGL_IMAGE_STATE_GRAPHICS_SHADER_WRITE_ONLY:
110 case XGL_IMAGE_STATE_COMPUTE_SHADER_WRITE_ONLY:
111 caches = DATA_WRITE_CACHE;
112 break;
113 case XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_ONLY:
114 case XGL_IMAGE_STATE_MULTI_SHADER_READ_ONLY:
115 case XGL_IMAGE_STATE_TARGET_AND_SHADER_READ_ONLY:
116 caches = DATA_READ_CACHE | SAMPLER_CACHE;
117 break;
118 case XGL_IMAGE_STATE_COMPUTE_SHADER_READ_ONLY:
119 caches = DATA_READ_CACHE;
120 break;
121 case XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_WRITE:
122 caches = DATA_READ_CACHE | DATA_WRITE_CACHE | SAMPLER_CACHE;
123 break;
124 case XGL_IMAGE_STATE_COMPUTE_SHADER_READ_WRITE:
125 caches = DATA_READ_CACHE | DATA_WRITE_CACHE;
126 break;
127 case XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL:
128 case XGL_IMAGE_STATE_TARGET_SHADER_ACCESS_OPTIMAL:
129 caches = RENDER_CACHE | DATA_WRITE_CACHE;
130 break;
131 case XGL_IMAGE_STATE_CLEAR:
132 case XGL_IMAGE_STATE_RESOLVE_DESTINATION:
133 caches = RENDER_CACHE;
134 break;
135 case XGL_IMAGE_STATE_RESOLVE_SOURCE:
136 caches = SAMPLER_CACHE;
137 break;
138 default:
139 caches = 0;
140 break;
141 }
142
143 return caches;
144}
145
146static uint32_t cmd_get_img_flush_flags(const struct intel_cmd *cmd,
147 const struct intel_img *img,
148 uint32_t old_caches,
149 uint32_t new_caches)
150{
151 uint32_t flags = 0;
152
153 /* not dirty */
154 if (!(old_caches & (MEM_CACHE | RENDER_CACHE | DATA_WRITE_CACHE)))
155 return 0;
156
157 if ((old_caches & RENDER_CACHE) && (new_caches & ~RENDER_CACHE)) {
158 if (img->layout.format.numericFormat == XGL_NUM_FMT_DS)
159 flags |= GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH;
160 else
161 flags |= GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH;
162 }
163
164 if ((old_caches & DATA_WRITE_CACHE) &&
165 (new_caches & ~(DATA_READ_CACHE | DATA_WRITE_CACHE))) {
166 if (cmd_gen(cmd) >= INTEL_GEN(7))
167 flags |= GEN7_PIPE_CONTROL_DC_FLUSH_ENABLE;
168 }
169
170 if (new_caches & SAMPLER_CACHE)
171 flags |= GEN6_PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
172
173 if ((new_caches & DATA_READ_CACHE) && old_caches != DATA_WRITE_CACHE)
174 flags |= GEN6_PIPE_CONTROL_CONSTANT_CACHE_INVALIDATE;
175
176 if (!flags)
177 return 0;
178
179 flags |= GEN6_PIPE_CONTROL_CS_STALL;
180
181 return flags;
182}
183
184XGL_VOID XGLAPI intelCmdPrepareMemoryRegions(
185 XGL_CMD_BUFFER cmdBuffer,
186 XGL_UINT transitionCount,
187 const XGL_MEMORY_STATE_TRANSITION* pStateTransitions)
188{
189 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
190 uint32_t flush_flags = 0;
191 XGL_UINT i;
192
193 for (i = 0; i < transitionCount; i++) {
194 const XGL_MEMORY_STATE_TRANSITION *trans = &pStateTransitions[i];
195 struct intel_mem *mem = intel_mem(trans->mem);
196
197 flush_flags |= cmd_get_mem_flush_flags(cmd, mem,
198 mem_get_state_caches(mem, trans->oldState),
199 mem_get_state_caches(mem, trans->newState));
200 }
201
202 cmd_batch_flush(cmd, flush_flags);
203}
204
205XGL_VOID XGLAPI intelCmdPrepareImages(
206 XGL_CMD_BUFFER cmdBuffer,
207 XGL_UINT transitionCount,
208 const XGL_IMAGE_STATE_TRANSITION* pStateTransitions)
209{
210 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
211 uint32_t flush_flags = 0;
212 XGL_UINT i;
213
214 for (i = 0; i < transitionCount; i++) {
215 const XGL_IMAGE_STATE_TRANSITION *trans = &pStateTransitions[i];
216 struct intel_img *img = intel_img(trans->image);
217
218 flush_flags |= cmd_get_img_flush_flags(cmd, img,
219 img_get_state_caches(img, trans->oldState),
220 img_get_state_caches(img, trans->newState));
221 }
222
223 cmd_batch_flush(cmd, flush_flags);
224}