Path: blob/21.2-virgl/src/gallium/tests/graw/quad-sample.c
4565 views
/* Display a cleared blue window. This demo has no dependencies on1* any utility code, just the graw interface and gallium.2*/34#include "frontend/graw.h"5#include "pipe/p_screen.h"6#include "pipe/p_context.h"7#include "pipe/p_shader_tokens.h"8#include "pipe/p_state.h"9#include "pipe/p_defines.h"1011#include "util/u_debug.h" /* debug_dump_surface_bmp() */12#include "util/u_inlines.h"13#include "util/u_memory.h" /* Offset() */14#include "util/u_draw_quad.h"15#include "util/u_box.h"1617#include <stdio.h>1819enum pipe_format formats[] = {20PIPE_FORMAT_RGBA8888_UNORM,21PIPE_FORMAT_BGRA8888_UNORM,22PIPE_FORMAT_NONE23};2425static const int WIDTH = 300;26static const int HEIGHT = 300;2728static struct pipe_screen *screen = NULL;29static struct pipe_context *ctx = NULL;30static struct pipe_resource *rttex = NULL;31static struct pipe_resource *samptex = NULL;32static struct pipe_surface *surf = NULL;33static struct pipe_sampler_view *sv = NULL;34static void *sampler = NULL;35static void *window = NULL;3637struct vertex {38float position[4];39float color[4];40};4142static struct vertex vertices[] =43{44{ { 0.9, -0.9, 0.0, 1.0 },45{ 1, 0, 0, 1 } },4647{ { 0.9, 0.9, 0.0, 1.0 },48{ 1, 1, 0, 1 } },4950{ {-0.9, 0.9, 0.0, 1.0 },51{ 0, 1, 0, 1 } },5253{ {-0.9, -0.9, 0.0, 1.0 },54{ 0, 0, 0, 1 } },55};5657585960static void set_viewport( float x, float y,61float width, float height,62float zNear, float zFar)63{64float z = zFar;65float half_width = (float)width / 2.0f;66float half_height = (float)height / 2.0f;67float half_depth = ((float)zFar - (float)zNear) / 2.0f;68struct pipe_viewport_state vp;6970vp.scale[0] = half_width;71vp.scale[1] = half_height;72vp.scale[2] = half_depth;7374vp.translate[0] = half_width + x;75vp.translate[1] = half_height + y;76vp.translate[2] = half_depth + z;7778vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;79vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;80vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;81vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;8283ctx->set_viewport_states( ctx, 0, 1, &vp );84}8586static void set_vertices( void )87{88struct pipe_vertex_element ve[2];89struct pipe_vertex_buffer vbuf;90void *handle;9192memset(ve, 0, sizeof ve);9394ve[0].src_offset = Offset(struct vertex, position);95ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;96ve[1].src_offset = Offset(struct vertex, color);97ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;9899handle = ctx->create_vertex_elements_state(ctx, 2, ve);100ctx->bind_vertex_elements_state(ctx, handle);101102memset(&vbuf, 0, sizeof vbuf);103104vbuf.stride = sizeof( struct vertex );105vbuf.buffer_offset = 0;106vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,107PIPE_BIND_VERTEX_BUFFER,108PIPE_USAGE_DEFAULT,109sizeof(vertices),110vertices);111112ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf);113}114115static void set_vertex_shader( void )116{117void *handle;118const char *text =119"VERT\n"120"DCL IN[0]\n"121"DCL IN[1]\n"122"DCL OUT[0], POSITION\n"123"DCL OUT[1], GENERIC[0]\n"124" 0: MOV OUT[1], IN[1]\n"125" 1: MOV OUT[0], IN[0]\n"126" 2: END\n";127128handle = graw_parse_vertex_shader(ctx, text);129ctx->bind_vs_state(ctx, handle);130}131132static void set_fragment_shader( void )133{134void *handle;135const char *text =136"FRAG\n"137"DCL IN[0], GENERIC[0], PERSPECTIVE\n"138"DCL OUT[0], COLOR\n"139"DCL TEMP[0]\n"140"DCL SAMP[0]\n"141"DCL RES[0], 2D, FLOAT\n"142" 0: SAMPLE TEMP[0], IN[0], RES[0], SAMP[0]\n"143" 1: MOV OUT[0], TEMP[0]\n"144" 2: END\n";145146handle = graw_parse_fragment_shader(ctx, text);147ctx->bind_fs_state(ctx, handle);148}149150151static void draw( void )152{153union pipe_color_union clear_color = { {.5,.5,.5,1} };154155ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);156util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4);157ctx->flush(ctx, NULL, 0);158159graw_save_surface_to_file(ctx, surf, NULL);160161screen->flush_frontbuffer(screen, ctx, rttex, 0, 0, window, NULL);162}163164#define SIZE 16165166static void init_tex( void )167{168struct pipe_sampler_view sv_template;169struct pipe_sampler_state sampler_desc;170struct pipe_resource templat;171struct pipe_box box;172ubyte tex2d[SIZE][SIZE][4];173int s, t;174175#if (SIZE != 2)176for (s = 0; s < SIZE; s++) {177for (t = 0; t < SIZE; t++) {178if (0) {179int x = (s ^ t) & 1;180tex2d[t][s][0] = (x) ? 0 : 63;181tex2d[t][s][1] = (x) ? 0 : 128;182tex2d[t][s][2] = 0;183tex2d[t][s][3] = 0xff;184}185else {186int x = ((s ^ t) >> 2) & 1;187tex2d[t][s][0] = s*255/(SIZE-1);188tex2d[t][s][1] = t*255/(SIZE-1);189tex2d[t][s][2] = (x) ? 0 : 128;190tex2d[t][s][3] = 0xff;191}192}193}194#else195tex2d[0][0][0] = 0;196tex2d[0][0][1] = 255;197tex2d[0][0][2] = 255;198tex2d[0][0][3] = 0;199200tex2d[0][1][0] = 0;201tex2d[0][1][1] = 0;202tex2d[0][1][2] = 255;203tex2d[0][1][3] = 255;204205tex2d[1][0][0] = 255;206tex2d[1][0][1] = 255;207tex2d[1][0][2] = 0;208tex2d[1][0][3] = 255;209210tex2d[1][1][0] = 255;211tex2d[1][1][1] = 0;212tex2d[1][1][2] = 0;213tex2d[1][1][3] = 255;214#endif215216memset(&templat, 0, sizeof(templat));217templat.target = PIPE_TEXTURE_2D;218templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;219templat.width0 = SIZE;220templat.height0 = SIZE;221templat.depth0 = 1;222templat.last_level = 0;223templat.bind = PIPE_BIND_SAMPLER_VIEW;224225226samptex = screen->resource_create(screen,227&templat);228if (samptex == NULL)229exit(4);230231u_box_2d(0,0,SIZE,SIZE, &box);232233ctx->texture_subdata(ctx,234samptex,2350,236PIPE_MAP_WRITE,237&box,238tex2d,239sizeof tex2d[0],240sizeof tex2d);241242/* Possibly read back & compare against original data:243*/244if (0)245{246struct pipe_transfer *t;247uint32_t *ptr;248ptr = pipe_texture_map(ctx, samptex,2490, 0, /* level, layer */250PIPE_MAP_READ,2510, 0, SIZE, SIZE, &t); /* x, y, width, height */252253if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {254assert(0);255exit(9);256}257258ctx->texture_unmap(ctx, t);259}260261memset(&sv_template, 0, sizeof sv_template);262sv_template.format = samptex->format;263sv_template.texture = samptex;264sv_template.swizzle_r = 0;265sv_template.swizzle_g = 1;266sv_template.swizzle_b = 2;267sv_template.swizzle_a = 3;268sv = ctx->create_sampler_view(ctx, samptex, &sv_template);269if (sv == NULL)270exit(5);271272ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, 0, &sv);273274275memset(&sampler_desc, 0, sizeof sampler_desc);276sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;277sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;278sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;279sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;280sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;281sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;282sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;283sampler_desc.compare_func = 0;284sampler_desc.normalized_coords = 1;285sampler_desc.max_anisotropy = 0;286287sampler = ctx->create_sampler_state(ctx, &sampler_desc);288if (sampler == NULL)289exit(6);290291ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);292293}294295static void init( void )296{297struct pipe_framebuffer_state fb;298struct pipe_resource templat;299struct pipe_surface surf_tmpl;300int i;301302/* It's hard to say whether window or screen should be created303* first. Different environments would prefer one or the other.304*305* Also, no easy way of querying supported formats if the screen306* cannot be created first.307*/308for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {309screen = graw_create_window_and_screen(0, 0, 300, 300,310formats[i],311&window);312if (window && screen)313break;314}315if (!screen || !window) {316fprintf(stderr, "Unable to create window\n");317exit(1);318}319320ctx = screen->context_create(screen, NULL, 0);321if (ctx == NULL)322exit(3);323324memset(&templat, 0, sizeof(templat));325templat.target = PIPE_TEXTURE_2D;326templat.format = formats[i];327templat.width0 = WIDTH;328templat.height0 = HEIGHT;329templat.depth0 = 1;330templat.array_size = 1;331templat.last_level = 0;332templat.bind = (PIPE_BIND_RENDER_TARGET |333PIPE_BIND_DISPLAY_TARGET);334335rttex = screen->resource_create(screen,336&templat);337if (rttex == NULL)338exit(4);339340surf_tmpl.format = templat.format;341surf_tmpl.u.tex.level = 0;342surf_tmpl.u.tex.first_layer = 0;343surf_tmpl.u.tex.last_layer = 0;344surf = ctx->create_surface(ctx, rttex, &surf_tmpl);345if (surf == NULL)346exit(5);347348memset(&fb, 0, sizeof fb);349fb.nr_cbufs = 1;350fb.width = WIDTH;351fb.height = HEIGHT;352fb.cbufs[0] = surf;353354ctx->set_framebuffer_state(ctx, &fb);355356{357struct pipe_blend_state blend;358void *handle;359memset(&blend, 0, sizeof blend);360blend.rt[0].colormask = PIPE_MASK_RGBA;361handle = ctx->create_blend_state(ctx, &blend);362ctx->bind_blend_state(ctx, handle);363}364365{366struct pipe_depth_stencil_alpha_state depthstencil;367void *handle;368memset(&depthstencil, 0, sizeof depthstencil);369handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);370ctx->bind_depth_stencil_alpha_state(ctx, handle);371}372373{374struct pipe_rasterizer_state rasterizer;375void *handle;376memset(&rasterizer, 0, sizeof rasterizer);377rasterizer.cull_face = PIPE_FACE_NONE;378rasterizer.half_pixel_center = 1;379rasterizer.bottom_edge_rule = 1;380rasterizer.depth_clip_near = 1;381rasterizer.depth_clip_far = 1;382handle = ctx->create_rasterizer_state(ctx, &rasterizer);383ctx->bind_rasterizer_state(ctx, handle);384}385386set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);387388init_tex();389390set_vertices();391set_vertex_shader();392set_fragment_shader();393}394395static void args(int argc, char *argv[])396{397int i;398399for (i = 1; i < argc;) {400if (graw_parse_args(&i, argc, argv)) {401continue;402}403exit(1);404}405}406407408int main( int argc, char *argv[] )409{410args(argc, argv);411init();412413graw_set_display_func( draw );414graw_main_loop();415return 0;416}417418419