Merge commit 'origin/7.8'
[mesa.git] / src / mesa / drivers / dri / nouveau / nv20_state_fb.c
1 /*
2 * Copyright (C) 2009 Francisco Jerez.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27 #include "nouveau_driver.h"
28 #include "nouveau_context.h"
29 #include "nouveau_fbo.h"
30 #include "nouveau_gldefs.h"
31 #include "nouveau_util.h"
32 #include "nouveau_class.h"
33 #include "nv20_driver.h"
34
35 static inline unsigned
36 get_rt_format(gl_format format)
37 {
38 switch (format) {
39 case MESA_FORMAT_XRGB8888:
40 return 0x05;
41 case MESA_FORMAT_ARGB8888:
42 return 0x08;
43 case MESA_FORMAT_RGB565:
44 return 0x03;
45 case MESA_FORMAT_Z16:
46 return 0x10;
47 case MESA_FORMAT_Z24_S8:
48 return 0x20;
49 default:
50 assert(0);
51 }
52 }
53
54 void
55 nv20_emit_framebuffer(GLcontext *ctx, int emit)
56 {
57 struct nouveau_channel *chan = context_chan(ctx);
58 struct nouveau_grobj *kelvin = context_eng3d(ctx);
59 struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER);
60 struct gl_framebuffer *fb = ctx->DrawBuffer;
61 struct nouveau_surface *s;
62 unsigned rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR;
63 unsigned rt_pitch = 0, zeta_pitch = 0;
64 unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
65
66 if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT)
67 return;
68
69 /* Render target */
70 if (fb->_ColorDrawBuffers[0]) {
71 s = &to_nouveau_renderbuffer(
72 fb->_ColorDrawBuffers[0])->surface;
73
74 rt_format |= get_rt_format(s->format);
75 zeta_pitch = rt_pitch = s->pitch;
76
77 nouveau_bo_markl(bctx, kelvin, NV20TCL_COLOR_OFFSET,
78 s->bo, 0, bo_flags);
79 }
80
81 /* depth/stencil */
82 if (fb->_DepthBuffer) {
83 s = &to_nouveau_renderbuffer(
84 fb->_DepthBuffer->Wrapped)->surface;
85
86 rt_format |= get_rt_format(s->format);
87 zeta_pitch = s->pitch;
88
89 nouveau_bo_markl(bctx, kelvin, NV20TCL_ZETA_OFFSET,
90 s->bo, 0, bo_flags);
91 }
92
93 BEGIN_RING(chan, kelvin, NV20TCL_RT_FORMAT, 2);
94 OUT_RING(chan, rt_format);
95 OUT_RING(chan, zeta_pitch << 16 | rt_pitch);
96
97 /* Recompute the viewport/scissor state. */
98 context_dirty(ctx, VIEWPORT);
99 context_dirty(ctx, SCISSOR);
100 }
101
102 void
103 nv20_emit_viewport(GLcontext *ctx, int emit)
104 {
105 struct nouveau_channel *chan = context_chan(ctx);
106 struct nouveau_grobj *kelvin = context_eng3d(ctx);
107 struct gl_framebuffer *fb = ctx->DrawBuffer;
108 float a[4] = {};
109
110 get_viewport_translate(ctx, a);
111
112 BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4);
113 OUT_RINGp(chan, a, 4);
114
115 BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1);
116 OUT_RING(chan, (fb->Width - 1) << 16);
117 BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1);
118 OUT_RING(chan, (fb->Height - 1) << 16);
119
120 context_dirty(ctx, PROJECTION);
121 }