13464ebd5Sriastradh/* Display a cleared blue window. This demo has no dependencies on 23464ebd5Sriastradh * any utility code, just the graw interface and gallium. 33464ebd5Sriastradh */ 43464ebd5Sriastradh 53464ebd5Sriastradh#include <stdio.h> 67ec681f3Smrg#include "frontend/graw.h" 73464ebd5Sriastradh#include "pipe/p_screen.h" 83464ebd5Sriastradh#include "pipe/p_context.h" 93464ebd5Sriastradh#include "pipe/p_state.h" 103464ebd5Sriastradh#include "pipe/p_defines.h" 113464ebd5Sriastradh 123464ebd5Sriastradh#include "util/u_memory.h" /* Offset() */ 133464ebd5Sriastradh#include "util/u_draw_quad.h" 14af69d88dSmrg#include "util/u_inlines.h" 153464ebd5Sriastradh 163464ebd5Sriastradhenum pipe_format formats[] = { 17af69d88dSmrg PIPE_FORMAT_RGBA8888_UNORM, 18af69d88dSmrg PIPE_FORMAT_BGRA8888_UNORM, 193464ebd5Sriastradh PIPE_FORMAT_NONE 203464ebd5Sriastradh}; 213464ebd5Sriastradh 223464ebd5Sriastradhstatic const int WIDTH = 300; 233464ebd5Sriastradhstatic const int HEIGHT = 300; 243464ebd5Sriastradh 253464ebd5Sriastradhstatic struct pipe_screen *screen = NULL; 263464ebd5Sriastradhstatic struct pipe_context *ctx = NULL; 273464ebd5Sriastradhstatic struct pipe_surface *surf = NULL; 283464ebd5Sriastradhstatic struct pipe_resource *tex = NULL; 293464ebd5Sriastradhstatic void *window = NULL; 303464ebd5Sriastradh 313464ebd5Sriastradhstruct vertex { 323464ebd5Sriastradh float position[4]; 333464ebd5Sriastradh float color[4]; 343464ebd5Sriastradh}; 353464ebd5Sriastradh 363464ebd5Sriastradhstatic struct vertex vertices[4] = 373464ebd5Sriastradh{ 383464ebd5Sriastradh { { 0.0f, -0.9f, 0.0f, 1.0f }, 393464ebd5Sriastradh { 1.0f, 0.0f, 0.0f, 1.0f } 403464ebd5Sriastradh }, 413464ebd5Sriastradh { { -0.9f, 0.9f, 0.0f, 1.0f }, 423464ebd5Sriastradh { 0.0f, 1.0f, 0.0f, 1.0f } 433464ebd5Sriastradh }, 443464ebd5Sriastradh { { 0.9f, 0.9f, 0.0f, 1.0f }, 453464ebd5Sriastradh { 0.0f, 0.0f, 1.0f, 1.0f } 463464ebd5Sriastradh } 473464ebd5Sriastradh}; 483464ebd5Sriastradh 493464ebd5Sriastradh 503464ebd5Sriastradh 513464ebd5Sriastradh 523464ebd5Sriastradhstatic void set_viewport( float x, float y, 533464ebd5Sriastradh float width, float height, 5401e04c3fSmrg float zNear, float zFar) 553464ebd5Sriastradh{ 5601e04c3fSmrg float z = zFar; 573464ebd5Sriastradh float half_width = (float)width / 2.0f; 583464ebd5Sriastradh float half_height = (float)height / 2.0f; 5901e04c3fSmrg float half_depth = ((float)zFar - (float)zNear) / 2.0f; 603464ebd5Sriastradh struct pipe_viewport_state vp; 613464ebd5Sriastradh 623464ebd5Sriastradh vp.scale[0] = half_width; 633464ebd5Sriastradh vp.scale[1] = half_height; 643464ebd5Sriastradh vp.scale[2] = half_depth; 653464ebd5Sriastradh 663464ebd5Sriastradh vp.translate[0] = half_width + x; 673464ebd5Sriastradh vp.translate[1] = half_height + y; 683464ebd5Sriastradh vp.translate[2] = half_depth + z; 693464ebd5Sriastradh 707ec681f3Smrg vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 717ec681f3Smrg vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 727ec681f3Smrg vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 737ec681f3Smrg vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 747ec681f3Smrg 75af69d88dSmrg ctx->set_viewport_states( ctx, 0, 1, &vp ); 763464ebd5Sriastradh} 773464ebd5Sriastradh 783464ebd5Sriastradhstatic void set_vertices( void ) 793464ebd5Sriastradh{ 803464ebd5Sriastradh struct pipe_vertex_element ve[2]; 813464ebd5Sriastradh struct pipe_vertex_buffer vbuf; 823464ebd5Sriastradh void *handle; 833464ebd5Sriastradh 843464ebd5Sriastradh memset(ve, 0, sizeof ve); 853464ebd5Sriastradh 863464ebd5Sriastradh ve[0].src_offset = Offset(struct vertex, position); 873464ebd5Sriastradh ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 883464ebd5Sriastradh ve[1].src_offset = Offset(struct vertex, color); 893464ebd5Sriastradh ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 903464ebd5Sriastradh 913464ebd5Sriastradh handle = ctx->create_vertex_elements_state(ctx, 2, ve); 923464ebd5Sriastradh ctx->bind_vertex_elements_state(ctx, handle); 933464ebd5Sriastradh 94af69d88dSmrg memset(&vbuf, 0, sizeof vbuf); 953464ebd5Sriastradh 963464ebd5Sriastradh vbuf.stride = sizeof( struct vertex ); 973464ebd5Sriastradh vbuf.buffer_offset = 0; 9801e04c3fSmrg vbuf.buffer.resource = pipe_buffer_create_with_data(ctx, 99af69d88dSmrg PIPE_BIND_VERTEX_BUFFER, 100af69d88dSmrg PIPE_USAGE_DEFAULT, 101af69d88dSmrg sizeof(vertices), 102af69d88dSmrg vertices); 1033464ebd5Sriastradh 1047ec681f3Smrg ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf); 1053464ebd5Sriastradh} 1063464ebd5Sriastradh 1073464ebd5Sriastradhstatic void set_vertex_shader( void ) 1083464ebd5Sriastradh{ 1093464ebd5Sriastradh void *handle; 1103464ebd5Sriastradh const char *text = 1113464ebd5Sriastradh "VERT\n" 1123464ebd5Sriastradh "DCL IN[0]\n" 1133464ebd5Sriastradh "DCL IN[1]\n" 1143464ebd5Sriastradh "DCL OUT[0], POSITION\n" 1153464ebd5Sriastradh "DCL OUT[1], COLOR\n" 1163464ebd5Sriastradh " 0: MOV OUT[1], IN[1]\n" 1173464ebd5Sriastradh " 1: MOV OUT[0], IN[0]\n" 1183464ebd5Sriastradh " 2: END\n"; 1193464ebd5Sriastradh 1203464ebd5Sriastradh handle = graw_parse_vertex_shader(ctx, text); 1213464ebd5Sriastradh ctx->bind_vs_state(ctx, handle); 1223464ebd5Sriastradh} 1233464ebd5Sriastradh 1243464ebd5Sriastradhstatic void set_fragment_shader( void ) 1253464ebd5Sriastradh{ 1263464ebd5Sriastradh void *handle; 1273464ebd5Sriastradh const char *text = 1283464ebd5Sriastradh "FRAG\n" 1293464ebd5Sriastradh "DCL IN[0], COLOR, LINEAR\n" 1303464ebd5Sriastradh "DCL OUT[0], COLOR\n" 1313464ebd5Sriastradh " 0: MOV OUT[0], IN[0]\n" 1323464ebd5Sriastradh " 1: END\n"; 1333464ebd5Sriastradh 1343464ebd5Sriastradh handle = graw_parse_fragment_shader(ctx, text); 1353464ebd5Sriastradh ctx->bind_fs_state(ctx, handle); 1363464ebd5Sriastradh} 1373464ebd5Sriastradh 1383464ebd5Sriastradh 1393464ebd5Sriastradhstatic void set_geometry_shader( void ) 1403464ebd5Sriastradh{ 1413464ebd5Sriastradh void *handle; 1423464ebd5Sriastradh const char *text = 1433464ebd5Sriastradh "GEOM\n" 1443464ebd5Sriastradh "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n" 1453464ebd5Sriastradh "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n" 1463464ebd5Sriastradh "DCL IN[][0], POSITION, CONSTANT\n" 1473464ebd5Sriastradh "DCL IN[][1], COLOR, CONSTANT\n" 1483464ebd5Sriastradh "DCL OUT[0], POSITION, CONSTANT\n" 1493464ebd5Sriastradh "DCL OUT[1], COLOR, CONSTANT\n" 1503464ebd5Sriastradh "0:MOV OUT[0], IN[0][0]\n" 1513464ebd5Sriastradh "1:MOV OUT[1], IN[0][1]\n" 1523464ebd5Sriastradh "2:EMIT\n" 1533464ebd5Sriastradh "3:MOV OUT[0], IN[1][0]\n" 1543464ebd5Sriastradh "4:MOV OUT[1], IN[0][1]\n" /* copy color from input vertex 0 */ 1553464ebd5Sriastradh "5:EMIT\n" 1563464ebd5Sriastradh "6:MOV OUT[0], IN[2][0]\n" 1573464ebd5Sriastradh "7:MOV OUT[1], IN[2][1]\n" 1583464ebd5Sriastradh "8:EMIT\n" 1593464ebd5Sriastradh "9:ENDPRIM\n" 1603464ebd5Sriastradh "10:END\n"; 1613464ebd5Sriastradh 1623464ebd5Sriastradh handle = graw_parse_geometry_shader(ctx, text); 1633464ebd5Sriastradh ctx->bind_gs_state(ctx, handle); 1643464ebd5Sriastradh} 1653464ebd5Sriastradh 1663464ebd5Sriastradhstatic void draw( void ) 1673464ebd5Sriastradh{ 168af69d88dSmrg union pipe_color_union clear_color = { {1,0,1,1} }; 1693464ebd5Sriastradh 1707ec681f3Smrg ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0); 1713464ebd5Sriastradh util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); 172af69d88dSmrg ctx->flush(ctx, NULL, 0); 1733464ebd5Sriastradh 1747ec681f3Smrg screen->flush_frontbuffer(screen, ctx, tex, 0, 0, window, NULL); 1753464ebd5Sriastradh} 1763464ebd5Sriastradh 1773464ebd5Sriastradh 1783464ebd5Sriastradhstatic void init( void ) 1793464ebd5Sriastradh{ 1803464ebd5Sriastradh struct pipe_framebuffer_state fb; 1813464ebd5Sriastradh struct pipe_resource templat; 1823464ebd5Sriastradh struct pipe_surface surf_tmpl; 1833464ebd5Sriastradh int i; 1843464ebd5Sriastradh 1853464ebd5Sriastradh /* It's hard to say whether window or screen should be created 1863464ebd5Sriastradh * first. Different environments would prefer one or the other. 1873464ebd5Sriastradh * 1883464ebd5Sriastradh * Also, no easy way of querying supported formats if the screen 1893464ebd5Sriastradh * cannot be created first. 1903464ebd5Sriastradh */ 1913464ebd5Sriastradh for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) { 1923464ebd5Sriastradh screen = graw_create_window_and_screen(0, 0, 300, 300, 1933464ebd5Sriastradh formats[i], 1943464ebd5Sriastradh &window); 1953464ebd5Sriastradh if (window && screen) 1963464ebd5Sriastradh break; 1973464ebd5Sriastradh } 1983464ebd5Sriastradh if (!screen || !window) { 1993464ebd5Sriastradh fprintf(stderr, "Unable to create window\n"); 2003464ebd5Sriastradh exit(1); 2013464ebd5Sriastradh } 2023464ebd5Sriastradh 20301e04c3fSmrg ctx = screen->context_create(screen, NULL, 0); 2043464ebd5Sriastradh if (ctx == NULL) 2053464ebd5Sriastradh exit(3); 2063464ebd5Sriastradh 20701e04c3fSmrg memset(&templat, 0, sizeof(templat)); 2083464ebd5Sriastradh templat.target = PIPE_TEXTURE_2D; 2093464ebd5Sriastradh templat.format = formats[i]; 2103464ebd5Sriastradh templat.width0 = WIDTH; 2113464ebd5Sriastradh templat.height0 = HEIGHT; 2123464ebd5Sriastradh templat.depth0 = 1; 2133464ebd5Sriastradh templat.array_size = 1; 2143464ebd5Sriastradh templat.last_level = 0; 2153464ebd5Sriastradh templat.bind = (PIPE_BIND_RENDER_TARGET | 2163464ebd5Sriastradh PIPE_BIND_DISPLAY_TARGET); 2173464ebd5Sriastradh 2183464ebd5Sriastradh tex = screen->resource_create(screen, 2193464ebd5Sriastradh &templat); 2203464ebd5Sriastradh if (tex == NULL) 2213464ebd5Sriastradh exit(4); 2223464ebd5Sriastradh 2233464ebd5Sriastradh surf_tmpl.format = templat.format; 2243464ebd5Sriastradh surf_tmpl.u.tex.level = 0; 2253464ebd5Sriastradh surf_tmpl.u.tex.first_layer = 0; 2263464ebd5Sriastradh surf_tmpl.u.tex.last_layer = 0; 2273464ebd5Sriastradh surf = ctx->create_surface(ctx, tex, &surf_tmpl); 2283464ebd5Sriastradh if (surf == NULL) 2293464ebd5Sriastradh exit(5); 2303464ebd5Sriastradh 2313464ebd5Sriastradh memset(&fb, 0, sizeof fb); 2323464ebd5Sriastradh fb.nr_cbufs = 1; 2333464ebd5Sriastradh fb.width = WIDTH; 2343464ebd5Sriastradh fb.height = HEIGHT; 2353464ebd5Sriastradh fb.cbufs[0] = surf; 2363464ebd5Sriastradh 2373464ebd5Sriastradh ctx->set_framebuffer_state(ctx, &fb); 2383464ebd5Sriastradh 2393464ebd5Sriastradh { 2403464ebd5Sriastradh struct pipe_blend_state blend; 2413464ebd5Sriastradh void *handle; 2423464ebd5Sriastradh memset(&blend, 0, sizeof blend); 2433464ebd5Sriastradh blend.rt[0].colormask = PIPE_MASK_RGBA; 2443464ebd5Sriastradh handle = ctx->create_blend_state(ctx, &blend); 2453464ebd5Sriastradh ctx->bind_blend_state(ctx, handle); 2463464ebd5Sriastradh } 2473464ebd5Sriastradh 2483464ebd5Sriastradh { 2493464ebd5Sriastradh struct pipe_depth_stencil_alpha_state depthstencil; 2503464ebd5Sriastradh void *handle; 2513464ebd5Sriastradh memset(&depthstencil, 0, sizeof depthstencil); 2523464ebd5Sriastradh handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil); 2533464ebd5Sriastradh ctx->bind_depth_stencil_alpha_state(ctx, handle); 2543464ebd5Sriastradh } 2553464ebd5Sriastradh 2563464ebd5Sriastradh { 2573464ebd5Sriastradh struct pipe_rasterizer_state rasterizer; 2583464ebd5Sriastradh void *handle; 2593464ebd5Sriastradh memset(&rasterizer, 0, sizeof rasterizer); 2603464ebd5Sriastradh rasterizer.cull_face = PIPE_FACE_NONE; 261af69d88dSmrg rasterizer.half_pixel_center = 1; 262af69d88dSmrg rasterizer.bottom_edge_rule = 1; 26301e04c3fSmrg rasterizer.depth_clip_near = 1; 26401e04c3fSmrg rasterizer.depth_clip_far = 1; 2653464ebd5Sriastradh handle = ctx->create_rasterizer_state(ctx, &rasterizer); 2663464ebd5Sriastradh ctx->bind_rasterizer_state(ctx, handle); 2673464ebd5Sriastradh } 2683464ebd5Sriastradh 2693464ebd5Sriastradh set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000); 2703464ebd5Sriastradh set_vertices(); 2713464ebd5Sriastradh set_vertex_shader(); 2723464ebd5Sriastradh set_fragment_shader(); 2733464ebd5Sriastradh set_geometry_shader(); 2743464ebd5Sriastradh} 2753464ebd5Sriastradh 2763464ebd5Sriastradh 2773464ebd5Sriastradhint main( int argc, char *argv[] ) 2783464ebd5Sriastradh{ 2793464ebd5Sriastradh init(); 2803464ebd5Sriastradh 2813464ebd5Sriastradh graw_set_display_func( draw ); 2823464ebd5Sriastradh graw_main_loop(); 2833464ebd5Sriastradh return 0; 2843464ebd5Sriastradh} 285