1bf215546Sopenharmony_ci/* Display a cleared blue window.  This demo has no dependencies on
2bf215546Sopenharmony_ci * any utility code, just the graw interface and gallium.
3bf215546Sopenharmony_ci */
4bf215546Sopenharmony_ci
5bf215546Sopenharmony_ci#include <stdio.h>
6bf215546Sopenharmony_ci#include "frontend/graw.h"
7bf215546Sopenharmony_ci#include "pipe/p_screen.h"
8bf215546Sopenharmony_ci#include "pipe/p_context.h"
9bf215546Sopenharmony_ci#include "pipe/p_state.h"
10bf215546Sopenharmony_ci#include "pipe/p_defines.h"
11bf215546Sopenharmony_ci
12bf215546Sopenharmony_ci#include "util/u_memory.h"      /* Offset() */
13bf215546Sopenharmony_ci#include "util/u_draw_quad.h"
14bf215546Sopenharmony_ci#include "util/u_inlines.h"
15bf215546Sopenharmony_ci
16bf215546Sopenharmony_cienum pipe_format formats[] = {
17bf215546Sopenharmony_ci   PIPE_FORMAT_RGBA8888_UNORM,
18bf215546Sopenharmony_ci   PIPE_FORMAT_BGRA8888_UNORM,
19bf215546Sopenharmony_ci   PIPE_FORMAT_NONE
20bf215546Sopenharmony_ci};
21bf215546Sopenharmony_ci
22bf215546Sopenharmony_cistatic const int WIDTH = 300;
23bf215546Sopenharmony_cistatic const int HEIGHT = 300;
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_cistatic struct pipe_screen *screen = NULL;
26bf215546Sopenharmony_cistatic struct pipe_context *ctx = NULL;
27bf215546Sopenharmony_cistatic struct pipe_surface *surf = NULL;
28bf215546Sopenharmony_cistatic struct pipe_resource *tex = NULL;
29bf215546Sopenharmony_cistatic void *window = NULL;
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_cistruct vertex {
32bf215546Sopenharmony_ci   float position[4];
33bf215546Sopenharmony_ci   float color[4];
34bf215546Sopenharmony_ci};
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_cistatic struct vertex vertices[4] =
37bf215546Sopenharmony_ci{
38bf215546Sopenharmony_ci   { { 0.0f, -0.9f, 0.0f, 1.0f },
39bf215546Sopenharmony_ci     { 1.0f, 0.0f, 0.0f, 1.0f }
40bf215546Sopenharmony_ci   },
41bf215546Sopenharmony_ci   { { -0.9f, 0.9f, 0.0f, 1.0f },
42bf215546Sopenharmony_ci     { 0.0f, 1.0f, 0.0f, 1.0f }
43bf215546Sopenharmony_ci   },
44bf215546Sopenharmony_ci   { { 0.9f, 0.9f, 0.0f, 1.0f },
45bf215546Sopenharmony_ci     { 0.0f, 0.0f, 1.0f, 1.0f }
46bf215546Sopenharmony_ci   }
47bf215546Sopenharmony_ci};
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_cistatic void set_viewport( float x, float y,
53bf215546Sopenharmony_ci                          float width, float height,
54bf215546Sopenharmony_ci                          float zNear, float zFar)
55bf215546Sopenharmony_ci{
56bf215546Sopenharmony_ci   float z = zFar;
57bf215546Sopenharmony_ci   float half_width = (float)width / 2.0f;
58bf215546Sopenharmony_ci   float half_height = (float)height / 2.0f;
59bf215546Sopenharmony_ci   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
60bf215546Sopenharmony_ci   struct pipe_viewport_state vp;
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci   vp.scale[0] = half_width;
63bf215546Sopenharmony_ci   vp.scale[1] = half_height;
64bf215546Sopenharmony_ci   vp.scale[2] = half_depth;
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   vp.translate[0] = half_width + x;
67bf215546Sopenharmony_ci   vp.translate[1] = half_height + y;
68bf215546Sopenharmony_ci   vp.translate[2] = half_depth + z;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
71bf215546Sopenharmony_ci   vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
72bf215546Sopenharmony_ci   vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
73bf215546Sopenharmony_ci   vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   ctx->set_viewport_states( ctx, 0, 1, &vp );
76bf215546Sopenharmony_ci}
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_cistatic void set_vertices( void )
79bf215546Sopenharmony_ci{
80bf215546Sopenharmony_ci   struct pipe_vertex_element ve[2];
81bf215546Sopenharmony_ci   struct pipe_vertex_buffer vbuf;
82bf215546Sopenharmony_ci   void *handle;
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   memset(ve, 0, sizeof ve);
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   ve[0].src_offset = Offset(struct vertex, position);
87bf215546Sopenharmony_ci   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
88bf215546Sopenharmony_ci   ve[1].src_offset = Offset(struct vertex, color);
89bf215546Sopenharmony_ci   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci   handle = ctx->create_vertex_elements_state(ctx, 2, ve);
92bf215546Sopenharmony_ci   ctx->bind_vertex_elements_state(ctx, handle);
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   memset(&vbuf, 0, sizeof vbuf);
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci   vbuf.stride = sizeof( struct vertex );
97bf215546Sopenharmony_ci   vbuf.buffer_offset = 0;
98bf215546Sopenharmony_ci   vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
99bf215546Sopenharmony_ci                                              PIPE_BIND_VERTEX_BUFFER,
100bf215546Sopenharmony_ci                                              PIPE_USAGE_DEFAULT,
101bf215546Sopenharmony_ci                                              sizeof(vertices),
102bf215546Sopenharmony_ci                                              vertices);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf);
105bf215546Sopenharmony_ci}
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_cistatic void set_vertex_shader( void )
108bf215546Sopenharmony_ci{
109bf215546Sopenharmony_ci   void *handle;
110bf215546Sopenharmony_ci   const char *text =
111bf215546Sopenharmony_ci      "VERT\n"
112bf215546Sopenharmony_ci      "DCL IN[0]\n"
113bf215546Sopenharmony_ci      "DCL IN[1]\n"
114bf215546Sopenharmony_ci      "DCL OUT[0], POSITION\n"
115bf215546Sopenharmony_ci      "DCL OUT[1], COLOR\n"
116bf215546Sopenharmony_ci      "  0: MOV OUT[1], IN[1]\n"
117bf215546Sopenharmony_ci      "  1: MOV OUT[0], IN[0]\n"
118bf215546Sopenharmony_ci      "  2: END\n";
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci   handle = graw_parse_vertex_shader(ctx, text);
121bf215546Sopenharmony_ci   ctx->bind_vs_state(ctx, handle);
122bf215546Sopenharmony_ci}
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_cistatic void set_fragment_shader( void )
125bf215546Sopenharmony_ci{
126bf215546Sopenharmony_ci   void *handle;
127bf215546Sopenharmony_ci   const char *text =
128bf215546Sopenharmony_ci      "FRAG\n"
129bf215546Sopenharmony_ci      "DCL IN[0], COLOR, LINEAR\n"
130bf215546Sopenharmony_ci      "DCL OUT[0], COLOR\n"
131bf215546Sopenharmony_ci      "  0: MOV OUT[0], IN[0]\n"
132bf215546Sopenharmony_ci      "  1: END\n";
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   handle = graw_parse_fragment_shader(ctx, text);
135bf215546Sopenharmony_ci   ctx->bind_fs_state(ctx, handle);
136bf215546Sopenharmony_ci}
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_cistatic void set_geometry_shader( void )
140bf215546Sopenharmony_ci{
141bf215546Sopenharmony_ci   void *handle;
142bf215546Sopenharmony_ci   const char *text =
143bf215546Sopenharmony_ci      "GEOM\n"
144bf215546Sopenharmony_ci      "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n"
145bf215546Sopenharmony_ci      "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n"
146bf215546Sopenharmony_ci      "DCL IN[][0], POSITION, CONSTANT\n"
147bf215546Sopenharmony_ci      "DCL IN[][1], COLOR, CONSTANT\n"
148bf215546Sopenharmony_ci      "DCL OUT[0], POSITION, CONSTANT\n"
149bf215546Sopenharmony_ci      "DCL OUT[1], COLOR, CONSTANT\n"
150bf215546Sopenharmony_ci      "0:MOV OUT[0], IN[0][0]\n"
151bf215546Sopenharmony_ci      "1:MOV OUT[1], IN[0][1]\n"
152bf215546Sopenharmony_ci      "2:EMIT\n"
153bf215546Sopenharmony_ci      "3:MOV OUT[0], IN[1][0]\n"
154bf215546Sopenharmony_ci      "4:MOV OUT[1], IN[0][1]\n" /* copy color from input vertex 0 */
155bf215546Sopenharmony_ci      "5:EMIT\n"
156bf215546Sopenharmony_ci      "6:MOV OUT[0], IN[2][0]\n"
157bf215546Sopenharmony_ci      "7:MOV OUT[1], IN[2][1]\n"
158bf215546Sopenharmony_ci      "8:EMIT\n"
159bf215546Sopenharmony_ci      "9:ENDPRIM\n"
160bf215546Sopenharmony_ci      "10:END\n";
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   handle = graw_parse_geometry_shader(ctx, text);
163bf215546Sopenharmony_ci   ctx->bind_gs_state(ctx, handle);
164bf215546Sopenharmony_ci}
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_cistatic void draw( void )
167bf215546Sopenharmony_ci{
168bf215546Sopenharmony_ci   union pipe_color_union clear_color = { {1,0,1,1} };
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci   ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
171bf215546Sopenharmony_ci   util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
172bf215546Sopenharmony_ci   ctx->flush(ctx, NULL, 0);
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci   screen->flush_frontbuffer(screen, ctx, tex, 0, 0, window, NULL);
175bf215546Sopenharmony_ci}
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_cistatic void init( void )
179bf215546Sopenharmony_ci{
180bf215546Sopenharmony_ci   struct pipe_framebuffer_state fb;
181bf215546Sopenharmony_ci   struct pipe_resource templat;
182bf215546Sopenharmony_ci   struct pipe_surface surf_tmpl;
183bf215546Sopenharmony_ci   int i;
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ci   /* It's hard to say whether window or screen should be created
186bf215546Sopenharmony_ci    * first.  Different environments would prefer one or the other.
187bf215546Sopenharmony_ci    *
188bf215546Sopenharmony_ci    * Also, no easy way of querying supported formats if the screen
189bf215546Sopenharmony_ci    * cannot be created first.
190bf215546Sopenharmony_ci    */
191bf215546Sopenharmony_ci   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
192bf215546Sopenharmony_ci      screen = graw_create_window_and_screen(0, 0, 300, 300,
193bf215546Sopenharmony_ci                                             formats[i],
194bf215546Sopenharmony_ci                                             &window);
195bf215546Sopenharmony_ci      if (window && screen)
196bf215546Sopenharmony_ci         break;
197bf215546Sopenharmony_ci   }
198bf215546Sopenharmony_ci   if (!screen || !window) {
199bf215546Sopenharmony_ci      fprintf(stderr, "Unable to create window\n");
200bf215546Sopenharmony_ci      exit(1);
201bf215546Sopenharmony_ci   }
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci   ctx = screen->context_create(screen, NULL, 0);
204bf215546Sopenharmony_ci   if (ctx == NULL)
205bf215546Sopenharmony_ci      exit(3);
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   memset(&templat, 0, sizeof(templat));
208bf215546Sopenharmony_ci   templat.target = PIPE_TEXTURE_2D;
209bf215546Sopenharmony_ci   templat.format = formats[i];
210bf215546Sopenharmony_ci   templat.width0 = WIDTH;
211bf215546Sopenharmony_ci   templat.height0 = HEIGHT;
212bf215546Sopenharmony_ci   templat.depth0 = 1;
213bf215546Sopenharmony_ci   templat.array_size = 1;
214bf215546Sopenharmony_ci   templat.last_level = 0;
215bf215546Sopenharmony_ci   templat.bind = (PIPE_BIND_RENDER_TARGET |
216bf215546Sopenharmony_ci                   PIPE_BIND_DISPLAY_TARGET);
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci   tex = screen->resource_create(screen,
219bf215546Sopenharmony_ci                                 &templat);
220bf215546Sopenharmony_ci   if (tex == NULL)
221bf215546Sopenharmony_ci      exit(4);
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci   surf_tmpl.format = templat.format;
224bf215546Sopenharmony_ci   surf_tmpl.u.tex.level = 0;
225bf215546Sopenharmony_ci   surf_tmpl.u.tex.first_layer = 0;
226bf215546Sopenharmony_ci   surf_tmpl.u.tex.last_layer = 0;
227bf215546Sopenharmony_ci   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
228bf215546Sopenharmony_ci   if (surf == NULL)
229bf215546Sopenharmony_ci      exit(5);
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   memset(&fb, 0, sizeof fb);
232bf215546Sopenharmony_ci   fb.nr_cbufs = 1;
233bf215546Sopenharmony_ci   fb.width = WIDTH;
234bf215546Sopenharmony_ci   fb.height = HEIGHT;
235bf215546Sopenharmony_ci   fb.cbufs[0] = surf;
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci   ctx->set_framebuffer_state(ctx, &fb);
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   {
240bf215546Sopenharmony_ci      struct pipe_blend_state blend;
241bf215546Sopenharmony_ci      void *handle;
242bf215546Sopenharmony_ci      memset(&blend, 0, sizeof blend);
243bf215546Sopenharmony_ci      blend.rt[0].colormask = PIPE_MASK_RGBA;
244bf215546Sopenharmony_ci      handle = ctx->create_blend_state(ctx, &blend);
245bf215546Sopenharmony_ci      ctx->bind_blend_state(ctx, handle);
246bf215546Sopenharmony_ci   }
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci   {
249bf215546Sopenharmony_ci      struct pipe_depth_stencil_alpha_state depthstencil;
250bf215546Sopenharmony_ci      void *handle;
251bf215546Sopenharmony_ci      memset(&depthstencil, 0, sizeof depthstencil);
252bf215546Sopenharmony_ci      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
253bf215546Sopenharmony_ci      ctx->bind_depth_stencil_alpha_state(ctx, handle);
254bf215546Sopenharmony_ci   }
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   {
257bf215546Sopenharmony_ci      struct pipe_rasterizer_state rasterizer;
258bf215546Sopenharmony_ci      void *handle;
259bf215546Sopenharmony_ci      memset(&rasterizer, 0, sizeof rasterizer);
260bf215546Sopenharmony_ci      rasterizer.cull_face = PIPE_FACE_NONE;
261bf215546Sopenharmony_ci      rasterizer.half_pixel_center = 1;
262bf215546Sopenharmony_ci      rasterizer.bottom_edge_rule = 1;
263bf215546Sopenharmony_ci      rasterizer.depth_clip_near = 1;
264bf215546Sopenharmony_ci      rasterizer.depth_clip_far = 1;
265bf215546Sopenharmony_ci      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
266bf215546Sopenharmony_ci      ctx->bind_rasterizer_state(ctx, handle);
267bf215546Sopenharmony_ci   }
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
270bf215546Sopenharmony_ci   set_vertices();
271bf215546Sopenharmony_ci   set_vertex_shader();
272bf215546Sopenharmony_ci   set_fragment_shader();
273bf215546Sopenharmony_ci   set_geometry_shader();
274bf215546Sopenharmony_ci}
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ciint main( int argc, char *argv[] )
278bf215546Sopenharmony_ci{
279bf215546Sopenharmony_ci   init();
280bf215546Sopenharmony_ci
281bf215546Sopenharmony_ci   graw_set_display_func( draw );
282bf215546Sopenharmony_ci   graw_main_loop();
283bf215546Sopenharmony_ci   return 0;
284bf215546Sopenharmony_ci}
285