OSDN Git Service

i965/meta: Use internal functions for renderbuffer access
[android-x86/external-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 struct gl_renderbuffer *
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 CreateRenderbuffers name into an actual struct
59     * intel_renderbuffer.
60     */
61    _mesa_CreateRenderbuffers(1, &rbo);
62
63    rb = _mesa_lookup_renderbuffer(ctx, rbo);
64    irb = intel_renderbuffer(rb);
65
66    rb->Format = mt->format;
67    rb->_BaseFormat = _mesa_get_format_base_format(mt->format);
68
69    /* Program takes care of msaa and mip-level access manually for stencil.
70     * The surface is also treated as Y-tiled instead of as W-tiled calling for
71     * twice the width and half the height in dimensions.
72     */
73    if (flat) {
74       const unsigned halign_stencil = 8;
75
76       rb->NumSamples = 0;
77       rb->Width = ALIGN(mt->total_width, halign_stencil) * 2;
78       rb->Height = (mt->total_height / mt->physical_depth0) / 2;
79       irb->mt_level = 0;
80    } else {
81       rb->NumSamples = mt->num_samples;
82       rb->Width = mt->logical_width0;
83       rb->Height = mt->logical_height0;
84       irb->mt_level = level;
85    }
86
87    irb->mt_layer = layer;
88
89    intel_miptree_reference(&irb->mt, mt);
90
91    return rb;
92 }
93
94 /**
95  * Implementation of up or downsampling for window-system MSAA miptrees.
96  */
97 void
98 brw_meta_updownsample(struct brw_context *brw,
99                       struct intel_mipmap_tree *src_mt,
100                       struct intel_mipmap_tree *dst_mt)
101 {
102    struct gl_context *ctx = &brw->ctx;
103    GLuint fbos[2], src_fbo, dst_fbo;
104    struct gl_renderbuffer *src_rb;
105    struct gl_renderbuffer *dst_rb;
106    GLenum drawbuffer;
107    GLbitfield attachment, blit_bit;
108
109    if (_mesa_get_format_base_format(src_mt->format) == GL_DEPTH_COMPONENT ||
110        _mesa_get_format_base_format(src_mt->format) == GL_DEPTH_STENCIL) {
111       attachment = GL_DEPTH_ATTACHMENT;
112       drawbuffer = GL_NONE;
113       blit_bit = GL_DEPTH_BUFFER_BIT;
114    } else {
115       attachment = GL_COLOR_ATTACHMENT0;
116       drawbuffer = GL_COLOR_ATTACHMENT0;
117       blit_bit = GL_COLOR_BUFFER_BIT;
118    }
119
120    brw_emit_mi_flush(brw);
121
122    _mesa_meta_begin(ctx, MESA_META_ALL);
123    _mesa_GenFramebuffers(2, fbos);
124    src_rb = brw_get_rb_for_slice(brw, src_mt, 0, 0, false);
125    dst_rb = brw_get_rb_for_slice(brw, dst_mt, 0, 0, false);
126    src_fbo = fbos[0];
127    dst_fbo = fbos[1];
128
129    _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, src_fbo);
130    _mesa_framebuffer_renderbuffer(ctx, ctx->ReadBuffer, attachment, src_rb);
131    _mesa_ReadBuffer(drawbuffer);
132
133    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo);
134    _mesa_framebuffer_renderbuffer(ctx, ctx->DrawBuffer, attachment, dst_rb);
135    _mesa_DrawBuffer(drawbuffer);
136
137    _mesa_BlitFramebuffer(0, 0,
138                          src_mt->logical_width0, src_mt->logical_height0,
139                          0, 0,
140                          dst_mt->logical_width0, dst_mt->logical_height0,
141                          blit_bit, GL_NEAREST);
142
143    _mesa_DeleteRenderbuffers(1, &src_rb->Name);
144    _mesa_DeleteRenderbuffers(1, &dst_rb->Name);
145    _mesa_DeleteFramebuffers(2, fbos);
146
147    _mesa_meta_end(ctx);
148
149    brw_emit_mi_flush(brw);
150 }