swr: [rasterizer core] disable cull for rect_list
[mesa.git] / src / gallium / drivers / swr / swr_context.cpp
1 /****************************************************************************
2 * Copyright (C) 2015 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 ***************************************************************************/
23
24 #include "util/u_memory.h"
25 #include "util/u_inlines.h"
26 #include "util/u_format.h"
27 #include "util/u_atomic.h"
28
29 extern "C" {
30 #include "util/u_transfer.h"
31 #include "util/u_surface.h"
32 }
33
34 #include "swr_context.h"
35 #include "swr_memory.h"
36 #include "swr_screen.h"
37 #include "swr_resource.h"
38 #include "swr_scratch.h"
39 #include "swr_query.h"
40 #include "swr_fence.h"
41
42 #include "api.h"
43 #include "backend.h"
44
45 static struct pipe_surface *
46 swr_create_surface(struct pipe_context *pipe,
47 struct pipe_resource *pt,
48 const struct pipe_surface *surf_tmpl)
49 {
50 struct pipe_surface *ps;
51
52 ps = CALLOC_STRUCT(pipe_surface);
53 if (ps) {
54 pipe_reference_init(&ps->reference, 1);
55 pipe_resource_reference(&ps->texture, pt);
56 ps->context = pipe;
57 ps->format = surf_tmpl->format;
58 if (pt->target != PIPE_BUFFER) {
59 assert(surf_tmpl->u.tex.level <= pt->last_level);
60 ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
61 ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
62 ps->u.tex.level = surf_tmpl->u.tex.level;
63 ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
64 ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
65 if (ps->u.tex.first_layer != ps->u.tex.last_layer) {
66 debug_printf("creating surface with multiple layers, rendering "
67 "to first layer only\n");
68 }
69 } else {
70 /* setting width as number of elements should get us correct
71 * renderbuffer width */
72 ps->width = surf_tmpl->u.buf.last_element
73 - surf_tmpl->u.buf.first_element + 1;
74 ps->height = pt->height0;
75 ps->u.buf.first_element = surf_tmpl->u.buf.first_element;
76 ps->u.buf.last_element = surf_tmpl->u.buf.last_element;
77 assert(ps->u.buf.first_element <= ps->u.buf.last_element);
78 assert(ps->u.buf.last_element < ps->width);
79 }
80 }
81 return ps;
82 }
83
84 static void
85 swr_surface_destroy(struct pipe_context *pipe, struct pipe_surface *surf)
86 {
87 assert(surf->texture);
88 struct pipe_resource *resource = surf->texture;
89
90 /* If the resource has been drawn to, store tiles. */
91 swr_store_dirty_resource(pipe, resource, SWR_TILE_RESOLVED);
92
93 pipe_resource_reference(&resource, NULL);
94 FREE(surf);
95 }
96
97
98 static void *
99 swr_transfer_map(struct pipe_context *pipe,
100 struct pipe_resource *resource,
101 unsigned level,
102 unsigned usage,
103 const struct pipe_box *box,
104 struct pipe_transfer **transfer)
105 {
106 struct swr_screen *screen = swr_screen(pipe->screen);
107 struct swr_resource *spr = swr_resource(resource);
108 struct pipe_transfer *pt;
109 enum pipe_format format = resource->format;
110
111 assert(resource);
112 assert(level <= resource->last_level);
113
114 /* If mapping an attached rendertarget, store tiles to surface and set
115 * postStoreTileState to SWR_TILE_INVALID so tiles get reloaded on next use
116 * and nothing needs to be done at unmap. */
117 swr_store_dirty_resource(pipe, resource, SWR_TILE_INVALID);
118
119 if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
120 /* If resource is in use, finish fence before mapping.
121 * Unless requested not to block, then if not done return NULL map */
122 if (usage & PIPE_TRANSFER_DONTBLOCK) {
123 if (swr_is_fence_pending(screen->flush_fence))
124 return NULL;
125 } else {
126 if (spr->status) {
127 /* But, if there's no fence pending, submit one.
128 * XXX: Remove once draw timestamps are finished. */
129 if (!swr_is_fence_pending(screen->flush_fence))
130 swr_fence_submit(swr_context(pipe), screen->flush_fence);
131
132 swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
133 swr_resource_unused(resource);
134 }
135 }
136 }
137
138 pt = CALLOC_STRUCT(pipe_transfer);
139 if (!pt)
140 return NULL;
141 pipe_resource_reference(&pt->resource, resource);
142 pt->level = level;
143 pt->box = *box;
144 pt->stride = spr->row_stride[level];
145 pt->layer_stride = spr->img_stride[level];
146
147 /* if we're mapping the depth/stencil, copy in stencil */
148 if (spr->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT
149 && spr->has_stencil) {
150 for (unsigned i = 0; i < spr->alignedWidth * spr->alignedHeight; i++) {
151 spr->swr.pBaseAddress[4 * i + 3] = spr->secondary.pBaseAddress[i];
152 }
153 } else if (spr->base.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
154 && spr->has_stencil) {
155 for (unsigned i = 0; i < spr->alignedWidth * spr->alignedHeight; i++) {
156 spr->swr.pBaseAddress[8 * i + 4] = spr->secondary.pBaseAddress[i];
157 }
158 }
159
160 unsigned offset = box->z * pt->layer_stride + box->y * pt->stride
161 + box->x * util_format_get_blocksize(format);
162
163 *transfer = pt;
164
165 return spr->swr.pBaseAddress + offset + spr->mip_offsets[level];
166 }
167
168 static void
169 swr_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer)
170 {
171 assert(transfer->resource);
172
173 struct swr_resource *res = swr_resource(transfer->resource);
174 /* if we're mapping the depth/stencil, copy out stencil */
175 if (res->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT
176 && res->has_stencil) {
177 for (unsigned i = 0; i < res->alignedWidth * res->alignedHeight; i++) {
178 res->secondary.pBaseAddress[i] = res->swr.pBaseAddress[4 * i + 3];
179 }
180 } else if (res->base.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
181 && res->has_stencil) {
182 for (unsigned i = 0; i < res->alignedWidth * res->alignedHeight; i++) {
183 res->secondary.pBaseAddress[i] = res->swr.pBaseAddress[8 * i + 4];
184 }
185 }
186
187 pipe_resource_reference(&transfer->resource, NULL);
188 FREE(transfer);
189 }
190
191
192 static void
193 swr_resource_copy(struct pipe_context *pipe,
194 struct pipe_resource *dst,
195 unsigned dst_level,
196 unsigned dstx,
197 unsigned dsty,
198 unsigned dstz,
199 struct pipe_resource *src,
200 unsigned src_level,
201 const struct pipe_box *src_box)
202 {
203 struct swr_screen *screen = swr_screen(pipe->screen);
204
205 /* If either the src or dst is a renderTarget, store tiles before copy */
206 swr_store_dirty_resource(pipe, src, SWR_TILE_RESOLVED);
207 swr_store_dirty_resource(pipe, dst, SWR_TILE_RESOLVED);
208
209 swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
210 swr_resource_unused(src);
211 swr_resource_unused(dst);
212
213 if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER)
214 || (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER)) {
215 util_resource_copy_region(
216 pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box);
217 return;
218 }
219
220 debug_printf("unhandled swr_resource_copy\n");
221 }
222
223
224 static void
225 swr_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info)
226 {
227 struct swr_context *ctx = swr_context(pipe);
228 struct pipe_blit_info info = *blit_info;
229
230 if (blit_info->render_condition_enable && !swr_check_render_cond(pipe))
231 return;
232
233 if (info.src.resource->nr_samples > 1 && info.dst.resource->nr_samples <= 1
234 && !util_format_is_depth_or_stencil(info.src.resource->format)
235 && !util_format_is_pure_integer(info.src.resource->format)) {
236 debug_printf("swr: color resolve unimplemented\n");
237 return;
238 }
239
240 if (util_try_blit_via_copy_region(pipe, &info)) {
241 return; /* done */
242 }
243
244 if (info.mask & PIPE_MASK_S) {
245 debug_printf("swr: cannot blit stencil, skipping\n");
246 info.mask &= ~PIPE_MASK_S;
247 }
248
249 if (!util_blitter_is_blit_supported(ctx->blitter, &info)) {
250 debug_printf("swr: blit unsupported %s -> %s\n",
251 util_format_short_name(info.src.resource->format),
252 util_format_short_name(info.dst.resource->format));
253 return;
254 }
255
256 /* XXX turn off occlusion and streamout queries */
257
258 util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertex_buffer);
259 util_blitter_save_vertex_elements(ctx->blitter, (void *)ctx->velems);
260 util_blitter_save_vertex_shader(ctx->blitter, (void *)ctx->vs);
261 /*util_blitter_save_geometry_shader(ctx->blitter, (void*)ctx->gs);*/
262 util_blitter_save_so_targets(
263 ctx->blitter,
264 ctx->num_so_targets,
265 (struct pipe_stream_output_target **)ctx->so_targets);
266 util_blitter_save_rasterizer(ctx->blitter, (void *)ctx->rasterizer);
267 util_blitter_save_viewport(ctx->blitter, &ctx->viewport);
268 util_blitter_save_scissor(ctx->blitter, &ctx->scissor);
269 util_blitter_save_fragment_shader(ctx->blitter, ctx->fs);
270 util_blitter_save_blend(ctx->blitter, (void *)ctx->blend);
271 util_blitter_save_depth_stencil_alpha(ctx->blitter,
272 (void *)ctx->depth_stencil);
273 util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
274 util_blitter_save_sample_mask(ctx->blitter, ctx->sample_mask);
275 util_blitter_save_framebuffer(ctx->blitter, &ctx->framebuffer);
276 util_blitter_save_fragment_sampler_states(
277 ctx->blitter,
278 ctx->num_samplers[PIPE_SHADER_FRAGMENT],
279 (void **)ctx->samplers[PIPE_SHADER_FRAGMENT]);
280 util_blitter_save_fragment_sampler_views(
281 ctx->blitter,
282 ctx->num_sampler_views[PIPE_SHADER_FRAGMENT],
283 ctx->sampler_views[PIPE_SHADER_FRAGMENT]);
284 util_blitter_save_render_condition(ctx->blitter,
285 ctx->render_cond_query,
286 ctx->render_cond_cond,
287 ctx->render_cond_mode);
288
289 util_blitter_blit(ctx->blitter, &info);
290 }
291
292
293 static void
294 swr_destroy(struct pipe_context *pipe)
295 {
296 struct swr_context *ctx = swr_context(pipe);
297 struct swr_screen *screen = swr_screen(pipe->screen);
298
299 if (ctx->blitter)
300 util_blitter_destroy(ctx->blitter);
301
302 /* Idle core before deleting context */
303 SwrWaitForIdle(ctx->swrContext);
304
305 for (unsigned i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
306 pipe_surface_reference(&ctx->framebuffer.cbufs[i], NULL);
307 }
308
309 pipe_surface_reference(&ctx->framebuffer.zsbuf, NULL);
310
311 for (unsigned i = 0; i < ARRAY_SIZE(ctx->sampler_views[0]); i++) {
312 pipe_sampler_view_reference(&ctx->sampler_views[PIPE_SHADER_FRAGMENT][i], NULL);
313 }
314
315 for (unsigned i = 0; i < ARRAY_SIZE(ctx->sampler_views[0]); i++) {
316 pipe_sampler_view_reference(&ctx->sampler_views[PIPE_SHADER_VERTEX][i], NULL);
317 }
318
319 if (ctx->swrContext)
320 SwrDestroyContext(ctx->swrContext);
321
322 delete ctx->blendJIT;
323
324 swr_destroy_scratch_buffers(ctx);
325
326 /* Only update screen->pipe if current context is being destroyed */
327 assert(screen);
328 if (screen->pipe == pipe)
329 screen->pipe = NULL;
330
331 FREE(ctx);
332 }
333
334
335 static void
336 swr_render_condition(struct pipe_context *pipe,
337 struct pipe_query *query,
338 boolean condition,
339 uint mode)
340 {
341 struct swr_context *ctx = swr_context(pipe);
342
343 ctx->render_cond_query = query;
344 ctx->render_cond_mode = mode;
345 ctx->render_cond_cond = condition;
346 }
347
348 static void
349 swr_UpdateStats(HANDLE hPrivateContext, const SWR_STATS *pStats)
350 {
351 swr_draw_context *pDC = (swr_draw_context*)hPrivateContext;
352
353 if (!pDC)
354 return;
355
356 struct swr_query_result *pqr = (struct swr_query_result *)pDC->pStats;
357
358 SWR_STATS *pSwrStats = &pqr->core;
359
360 pSwrStats->DepthPassCount += pStats->DepthPassCount;
361 pSwrStats->PsInvocations += pStats->PsInvocations;
362 pSwrStats->CsInvocations += pStats->CsInvocations;
363 }
364
365 static void
366 swr_UpdateStatsFE(HANDLE hPrivateContext, const SWR_STATS_FE *pStats)
367 {
368 swr_draw_context *pDC = (swr_draw_context*)hPrivateContext;
369
370 if (!pDC)
371 return;
372
373 struct swr_query_result *pqr = (struct swr_query_result *)pDC->pStats;
374
375 SWR_STATS_FE *pSwrStats = &pqr->coreFE;
376 p_atomic_add(&pSwrStats->IaVertices, pStats->IaVertices);
377 p_atomic_add(&pSwrStats->IaPrimitives, pStats->IaPrimitives);
378 p_atomic_add(&pSwrStats->VsInvocations, pStats->VsInvocations);
379 p_atomic_add(&pSwrStats->HsInvocations, pStats->HsInvocations);
380 p_atomic_add(&pSwrStats->DsInvocations, pStats->DsInvocations);
381 p_atomic_add(&pSwrStats->GsInvocations, pStats->GsInvocations);
382 p_atomic_add(&pSwrStats->CInvocations, pStats->CInvocations);
383 p_atomic_add(&pSwrStats->CPrimitives, pStats->CPrimitives);
384 p_atomic_add(&pSwrStats->GsPrimitives, pStats->GsPrimitives);
385
386 for (unsigned i = 0; i < 4; i++) {
387 p_atomic_add(&pSwrStats->SoPrimStorageNeeded[i],
388 pStats->SoPrimStorageNeeded[i]);
389 p_atomic_add(&pSwrStats->SoNumPrimsWritten[i],
390 pStats->SoNumPrimsWritten[i]);
391 }
392 }
393
394 struct pipe_context *
395 swr_create_context(struct pipe_screen *p_screen, void *priv, unsigned flags)
396 {
397 struct swr_context *ctx = CALLOC_STRUCT(swr_context);
398 ctx->blendJIT =
399 new std::unordered_map<BLEND_COMPILE_STATE, PFN_BLEND_JIT_FUNC>;
400
401 SWR_CREATECONTEXT_INFO createInfo;
402 memset(&createInfo, 0, sizeof(createInfo));
403 createInfo.driver = GL;
404 createInfo.privateStateSize = sizeof(swr_draw_context);
405 createInfo.pfnLoadTile = swr_LoadHotTile;
406 createInfo.pfnStoreTile = swr_StoreHotTile;
407 createInfo.pfnClearTile = swr_StoreHotTileClear;
408 createInfo.pfnUpdateStats = swr_UpdateStats;
409 createInfo.pfnUpdateStatsFE = swr_UpdateStatsFE;
410 ctx->swrContext = SwrCreateContext(&createInfo);
411
412 /* Init Load/Store/ClearTiles Tables */
413 swr_InitMemoryModule();
414
415 InitBackendFuncTables();
416
417 if (ctx->swrContext == NULL)
418 goto fail;
419
420 ctx->pipe.screen = p_screen;
421 ctx->pipe.destroy = swr_destroy;
422 ctx->pipe.priv = priv;
423 ctx->pipe.create_surface = swr_create_surface;
424 ctx->pipe.surface_destroy = swr_surface_destroy;
425 ctx->pipe.transfer_map = swr_transfer_map;
426 ctx->pipe.transfer_unmap = swr_transfer_unmap;
427
428 ctx->pipe.transfer_flush_region = u_default_transfer_flush_region;
429 ctx->pipe.buffer_subdata = u_default_buffer_subdata;
430 ctx->pipe.texture_subdata = u_default_texture_subdata;
431
432 ctx->pipe.resource_copy_region = swr_resource_copy;
433 ctx->pipe.render_condition = swr_render_condition;
434
435 swr_state_init(&ctx->pipe);
436 swr_clear_init(&ctx->pipe);
437 swr_draw_init(&ctx->pipe);
438 swr_query_init(&ctx->pipe);
439
440 ctx->pipe.blit = swr_blit;
441 ctx->blitter = util_blitter_create(&ctx->pipe);
442 if (!ctx->blitter)
443 goto fail;
444
445 swr_init_scratch_buffers(ctx);
446
447 return &ctx->pipe;
448
449 fail:
450 /* Should really validate the init steps and fail gracefully */
451 swr_destroy(&ctx->pipe);
452 return NULL;
453 }