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