Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / sis / sis_dd.c
1 /**************************************************************************
2
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29  * Authors:
30  *    Sung-Ching Lin <sclin@sis.com.tw>
31  *    Eric Anholt <anholt@FreeBSD.org>
32  *
33  */
34
35 #include "sis_context.h"
36 #include "sis_dd.h"
37 #include "sis_lock.h"
38 #include "sis_alloc.h"
39 #include "sis_span.h"
40 #include "sis_state.h"
41 #include "sis_tris.h"
42
43 #include "main/formats.h"
44 #include "main/renderbuffer.h"
45
46 #include "utils.h"
47
48 /* Return the width and height of the given buffer.
49  */
50 static void
51 sisGetBufferSize( struct gl_framebuffer *buffer,
52                               GLuint *width, GLuint *height )
53 {
54    GET_CURRENT_CONTEXT(ctx);
55    sisContextPtr smesa = SIS_CONTEXT(ctx);
56
57    LOCK_HARDWARE();
58    *width  = smesa->driDrawable->w;
59    *height = smesa->driDrawable->h;
60    UNLOCK_HARDWARE();
61 }
62
63 /* Return various strings for glGetString().
64  */
65 static const GLubyte *
66 sisGetString( struct gl_context *ctx, GLenum name )
67 {
68    sisContextPtr smesa = SIS_CONTEXT(ctx);
69    static char buffer[128];
70    unsigned   offset;
71    GLuint agp_mode = (smesa->AGPSize > 0);
72
73    switch ( name )
74    {
75    case GL_VENDOR:
76       return (GLubyte *)"Eric Anholt";
77
78    case GL_RENDERER:
79       offset = driGetRendererString( buffer, "SiS", agp_mode );
80
81       return (GLubyte *)buffer;
82
83    default:
84       return NULL;
85    }
86 }
87
88 /* Send all commands to the hardware.
89  */
90 static void
91 sisFlush( struct gl_context *ctx )
92 {
93    sisContextPtr smesa = SIS_CONTEXT(ctx);
94
95    SIS_FIREVERTICES(smesa);
96 }
97
98 /* Make sure all commands have been sent to the hardware and have
99  * completed processing.
100  */
101 static void
102 sisFinish( struct gl_context *ctx )
103 {
104    sisContextPtr smesa = SIS_CONTEXT(ctx);
105
106    SIS_FIREVERTICES(smesa);
107    LOCK_HARDWARE();
108    WaitEngIdle( smesa );
109    UNLOCK_HARDWARE();
110 }
111
112 static void
113 sisDeleteRenderbuffer(struct gl_renderbuffer *rb)
114 {
115    /* Don't free() since we're contained in sis_context struct. */
116 }
117
118 static GLboolean
119 sisRenderbufferStorage(struct gl_context *ctx, struct gl_renderbuffer *rb,
120                        GLenum internalFormat, GLuint width, GLuint height)
121 {
122    rb->Width = width;
123    rb->Height = height;
124    rb->InternalFormat = internalFormat;
125    return GL_TRUE;
126 }
127
128 static void
129 sisInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format)
130 {
131    const GLuint name = 0;
132
133    _mesa_init_renderbuffer(rb, name);
134
135    /* Make sure we're using a null-valued GetPointer routine */
136    assert(rb->GetPointer(NULL, rb, 0, 0) == NULL);
137
138    rb->InternalFormat = format;
139
140    if (format == GL_RGBA) {
141       /* Color */
142       rb->Format = MESA_FORMAT_ARGB8888;
143       rb->DataType = GL_UNSIGNED_BYTE;
144    }
145    else if (format == GL_DEPTH_COMPONENT16) {
146       /* Depth */
147       /* we always Get/Put 32-bit Z values */
148       rb->Format = MESA_FORMAT_Z16;
149       rb->DataType = GL_UNSIGNED_INT;
150    }
151    else if (format == GL_DEPTH_COMPONENT24) {
152       /* Depth */
153       /* we always Get/Put 32-bit Z values */
154       rb->Format = MESA_FORMAT_Z32;
155       rb->DataType = GL_UNSIGNED_INT;
156    }
157    else {
158       /* Stencil */
159       ASSERT(format == GL_STENCIL_INDEX8_EXT);
160       rb->Format = MESA_FORMAT_S8;
161       rb->DataType = GL_UNSIGNED_BYTE;
162    }
163
164    rb->Delete = sisDeleteRenderbuffer;
165    rb->AllocStorage = sisRenderbufferStorage;
166 }
167
168 void
169 sisUpdateBufferSize(sisContextPtr smesa)
170 {
171    __GLSiSHardware *current = &smesa->current;
172    __GLSiSHardware *prev = &smesa->prev;
173    struct gl_framebuffer *fb = smesa->glCtx->DrawBuffer;
174
175    if (!smesa->front.Base.InternalFormat) {
176       /* do one-time init for the renderbuffers */
177       sisInitRenderbuffer(&smesa->front.Base, GL_RGBA);
178       sisSetSpanFunctions(&smesa->front, &fb->Visual);
179       _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &smesa->front.Base);
180
181       if (fb->Visual.doubleBufferMode) {
182          sisInitRenderbuffer(&smesa->back.Base, GL_RGBA);
183          sisSetSpanFunctions(&smesa->back, &fb->Visual);
184          _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &smesa->back.Base);
185       }
186
187       if (smesa->glCtx->Visual.depthBits > 0) {
188          sisInitRenderbuffer(&smesa->depth.Base, 
189                              (smesa->glCtx->Visual.depthBits == 16
190                               ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24));
191          sisSetSpanFunctions(&smesa->depth, &fb->Visual);
192          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &smesa->depth.Base);
193       }
194
195       if (smesa->glCtx->Visual.stencilBits > 0) {
196          sisInitRenderbuffer(&smesa->stencil.Base, GL_STENCIL_INDEX8_EXT);
197          sisSetSpanFunctions(&smesa->stencil, &fb->Visual);
198          _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &smesa->stencil.Base);
199       }
200    }
201
202    /* Make sure initialization did what we think it should */
203    assert(smesa->front.Base.InternalFormat);
204    assert(smesa->front.Base.AllocStorage);
205    if (fb->Visual.doubleBufferMode) {
206       assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
207       assert(smesa->front.Base.AllocStorage);
208    }
209    if (fb->Visual.depthBits) {
210       assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
211       assert(smesa->depth.Base.AllocStorage);
212    }
213
214    /* XXX Should get the base offset of the frontbuffer from the X Server */
215    smesa->front.offset = smesa->driDrawable->x * smesa->bytesPerPixel +
216                          smesa->driDrawable->y * smesa->front.pitch;
217    smesa->front.map = (char *) smesa->driScreen->pFB + smesa->front.offset;
218
219    if ( smesa->width == smesa->driDrawable->w &&
220         smesa->height == smesa->driDrawable->h )
221    {
222       return;
223    }
224
225    smesa->front.bpp = smesa->bytesPerPixel * 8;
226    /* Front pitch set on context create */
227    smesa->front.size = smesa->front.pitch * smesa->driDrawable->h;
228
229    smesa->width = smesa->driDrawable->w;
230    smesa->height = smesa->driDrawable->h;
231    smesa->bottom = smesa->height - 1;
232
233    if (smesa->back.offset)
234       sisFreeBackbuffer( smesa );
235    if (smesa->depth.offset)
236       sisFreeZStencilBuffer( smesa );
237
238    if ( smesa->glCtx->Visual.depthBits > 0 )
239       sisAllocZStencilBuffer( smesa );
240    if ( smesa->glCtx->Visual.doubleBufferMode )
241       sisAllocBackbuffer( smesa );
242
243    current->hwZ &= ~MASK_ZBufferPitch;
244    current->hwZ |= smesa->depth.pitch >> 2;
245    current->hwOffsetZ = smesa->depth.offset >> 2;
246
247    if ((current->hwOffsetZ != prev->hwOffsetZ) || (current->hwZ != prev->hwZ)) {
248       prev->hwOffsetZ = current->hwOffsetZ;
249       prev->hwZ = current->hwZ;
250       smesa->GlobalFlag |= GFLAG_ZSETTING;
251    }
252   
253    sisUpdateClipping( smesa->glCtx );
254 }
255
256 /* Initialize the driver's misc functions.
257  */
258 void
259 sisInitDriverFuncs( struct dd_function_table *functions )
260 {
261    functions->GetBufferSize = sisGetBufferSize;
262    functions->GetString     = sisGetString;
263    functions->Finish        = sisFinish;
264    functions->Flush         = sisFlush;
265 }