glsl: move to compiler/
[mesa.git] / src / mesa / drivers / dri / i965 / brw_meta_updownsample.c
1 /*
2 * Copyright © 2014 Intel Corporation
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 "brw_context.h"
25 #include "intel_batchbuffer.h"
26 #include "intel_fbo.h"
27
28 #include "main/blit.h"
29 #include "main/buffers.h"
30 #include "main/enums.h"
31 #include "main/fbobject.h"
32
33 #include "drivers/common/meta.h"
34
35 /**
36 * @file brw_meta_updownsample.c
37 *
38 * Implements upsampling and downsampling of miptrees for window system
39 * framebuffers.
40 */
41
42 /**
43 * Creates a new named renderbuffer that wraps the first slice
44 * of an existing miptree.
45 *
46 * Clobbers the current renderbuffer binding (ctx->CurrentRenderbuffer).
47 */
48 GLuint
49 brw_get_rb_for_slice(struct brw_context *brw,
50 struct intel_mipmap_tree *mt,
51 unsigned level, unsigned layer, bool flat)
52 {
53 struct gl_context *ctx = &brw->ctx;
54 GLuint rbo;
55 struct gl_renderbuffer *rb;
56 struct intel_renderbuffer *irb;
57
58 /* This turns the GenRenderbuffers name into an actual struct
59 * intel_renderbuffer.
60 */
61 _mesa_GenRenderbuffers(1, &rbo);
62 _mesa_BindRenderbuffer(GL_RENDERBUFFER, rbo);
63
64 rb = ctx->CurrentRenderbuffer;
65 irb = intel_renderbuffer(rb);
66
67 rb->Format = mt->format;
68 rb->_BaseFormat = _mesa_get_format_base_format(mt->format);
69
70 /* Program takes care of msaa and mip-level access manually for stencil.
71 * The surface is also treated as Y-tiled instead of as W-tiled calling for
72 * twice the width and half the height in dimensions.
73 */
74 if (flat) {
75 const unsigned halign_stencil = 8;
76
77 rb->NumSamples = 0;
78 rb->Width = ALIGN(mt->total_width, halign_stencil) * 2;
79 rb->Height = (mt->total_height / mt->physical_depth0) / 2;
80 irb->mt_level = 0;
81 } else {
82 rb->NumSamples = mt->num_samples;
83 rb->Width = mt->logical_width0;
84 rb->Height = mt->logical_height0;
85 irb->mt_level = level;
86 }
87
88 irb->mt_layer = layer;
89
90 intel_miptree_reference(&irb->mt, mt);
91
92 return rbo;
93 }
94
95 /**
96 * Implementation of up or downsampling for window-system MSAA miptrees.
97 */
98 void
99 brw_meta_updownsample(struct brw_context *brw,
100 struct intel_mipmap_tree *src_mt,
101 struct intel_mipmap_tree *dst_mt)
102 {
103 struct gl_context *ctx = &brw->ctx;
104 GLuint fbos[2], src_rbo, dst_rbo, src_fbo, dst_fbo;
105 GLenum drawbuffer;
106 GLbitfield attachment, blit_bit;
107
108 if (_mesa_get_format_base_format(src_mt->format) == GL_DEPTH_COMPONENT ||
109 _mesa_get_format_base_format(src_mt->format) == GL_DEPTH_STENCIL) {
110 attachment = GL_DEPTH_ATTACHMENT;
111 drawbuffer = GL_NONE;
112 blit_bit = GL_DEPTH_BUFFER_BIT;
113 } else {
114 attachment = GL_COLOR_ATTACHMENT0;
115 drawbuffer = GL_COLOR_ATTACHMENT0;
116 blit_bit = GL_COLOR_BUFFER_BIT;
117 }
118
119 brw_emit_mi_flush(brw);
120
121 _mesa_meta_begin(ctx, MESA_META_ALL);
122 _mesa_GenFramebuffers(2, fbos);
123 src_rbo = brw_get_rb_for_slice(brw, src_mt, 0, 0, false);
124 dst_rbo = brw_get_rb_for_slice(brw, dst_mt, 0, 0, false);
125 src_fbo = fbos[0];
126 dst_fbo = fbos[1];
127
128 _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, src_fbo);
129 _mesa_FramebufferRenderbuffer(GL_READ_FRAMEBUFFER, attachment,
130 GL_RENDERBUFFER, src_rbo);
131 _mesa_ReadBuffer(drawbuffer);
132
133 _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo);
134 _mesa_FramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, attachment,
135 GL_RENDERBUFFER, dst_rbo);
136 _mesa_DrawBuffer(drawbuffer);
137
138 _mesa_BlitFramebuffer(0, 0,
139 src_mt->logical_width0, src_mt->logical_height0,
140 0, 0,
141 dst_mt->logical_width0, dst_mt->logical_height0,
142 blit_bit, GL_NEAREST);
143
144 _mesa_DeleteRenderbuffers(1, &src_rbo);
145 _mesa_DeleteRenderbuffers(1, &dst_rbo);
146 _mesa_DeleteFramebuffers(2, fbos);
147
148 _mesa_meta_end(ctx);
149
150 brw_emit_mi_flush(brw);
151 }