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