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