Path: blob/21.2-virgl/src/gallium/tests/graw/tri-instanced.c
4565 views
/*1* Test draw instancing.2*/34#include <stdio.h>5#include <string.h>67#include "frontend/graw.h"8#include "pipe/p_screen.h"9#include "pipe/p_context.h"10#include "pipe/p_state.h"11#include "pipe/p_defines.h"1213#include "util/u_memory.h" /* Offset() */14#include "util/u_draw_quad.h"15#include "util/u_inlines.h"161718enum pipe_format formats[] = {19PIPE_FORMAT_RGBA8888_UNORM,20PIPE_FORMAT_BGRA8888_UNORM,21PIPE_FORMAT_NONE22};2324static const int WIDTH = 300;25static const int HEIGHT = 300;2627static struct pipe_screen *screen = NULL;28static struct pipe_context *ctx = NULL;29static struct pipe_surface *surf = NULL;30static struct pipe_resource *tex = NULL;31static void *window = NULL;3233struct vertex {34float position[4];35float color[4];36};373839static int draw_elements = 0;404142/**43* Vertex data.44* Each vertex has three attributes: position, color and translation.45* The translation attribute is a per-instance attribute. See46* "instance_divisor" below.47*/48static struct vertex vertices[4] =49{50{51{ 0.0f, -0.3f, 0.0f, 1.0f }, /* pos */52{ 1.0f, 0.0f, 0.0f, 1.0f } /* color */53},54{55{ -0.2f, 0.3f, 0.0f, 1.0f },56{ 0.0f, 1.0f, 0.0f, 1.0f }57},58{59{ 0.2f, 0.3f, 0.0f, 1.0f },60{ 0.0f, 0.0f, 1.0f, 1.0f }61}62};636465#define NUM_INST 56667static float inst_data[NUM_INST][4] =68{69{ -0.50f, 0.4f, 0.0f, 0.0f },70{ -0.25f, 0.1f, 0.0f, 0.0f },71{ 0.00f, 0.2f, 0.0f, 0.0f },72{ 0.25f, 0.1f, 0.0f, 0.0f },73{ 0.50f, 0.3f, 0.0f, 0.0f }74};757677static ushort indices[3] = { 0, 2, 1 };787980static void set_viewport( float x, float y,81float width, float height,82float zNear, float zFar)83{84float z = zFar;85float half_width = (float)width / 2.0f;86float half_height = (float)height / 2.0f;87float half_depth = ((float)zFar - (float)zNear) / 2.0f;88struct pipe_viewport_state vp;8990vp.scale[0] = half_width;91vp.scale[1] = half_height;92vp.scale[2] = half_depth;9394vp.translate[0] = half_width + x;95vp.translate[1] = half_height + y;96vp.translate[2] = half_depth + z;9798vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;99vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;100vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;101vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;102103ctx->set_viewport_states( ctx, 0, 1, &vp );104}105106107static void set_vertices( void )108{109struct pipe_vertex_element ve[3];110struct pipe_vertex_buffer vbuf[2];111void *handle;112113memset(ve, 0, sizeof ve);114115/* pos */116ve[0].src_offset = Offset(struct vertex, position);117ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;118ve[0].vertex_buffer_index = 0;119120/* color */121ve[1].src_offset = Offset(struct vertex, color);122ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;123ve[1].vertex_buffer_index = 0;124125/* per-instance info */126ve[2].src_offset = 0;127ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;128ve[2].vertex_buffer_index = 1;129ve[2].instance_divisor = 1;130131handle = ctx->create_vertex_elements_state(ctx, 3, ve);132ctx->bind_vertex_elements_state(ctx, handle);133134memset(&vbuf, 0, sizeof vbuf);135136/* vertex data */137vbuf[0].stride = sizeof( struct vertex );138vbuf[0].buffer_offset = 0;139vbuf[0].buffer.resource = pipe_buffer_create_with_data(ctx,140PIPE_BIND_VERTEX_BUFFER,141PIPE_USAGE_DEFAULT,142sizeof(vertices),143vertices);144145/* instance data */146vbuf[1].stride = sizeof( inst_data[0] );147vbuf[1].buffer_offset = 0;148vbuf[1].buffer.resource = pipe_buffer_create_with_data(ctx,149PIPE_BIND_VERTEX_BUFFER,150PIPE_USAGE_DEFAULT,151sizeof(inst_data),152inst_data);153154ctx->set_vertex_buffers(ctx, 0, 2, 0, false, vbuf);155}156157static void set_vertex_shader( void )158{159void *handle;160const char *text =161"VERT\n"162"DCL IN[0]\n"163"DCL IN[1]\n"164"DCL IN[2]\n"165"DCL OUT[0], POSITION\n"166"DCL OUT[1], COLOR\n"167" 0: MOV OUT[1], IN[1]\n"168" 1: ADD OUT[0], IN[0], IN[2]\n" /* add instance pos to vertex pos */169" 2: END\n";170171handle = graw_parse_vertex_shader(ctx, text);172ctx->bind_vs_state(ctx, handle);173}174175static void set_fragment_shader( void )176{177void *handle;178const char *text =179"FRAG\n"180"DCL IN[0], COLOR, LINEAR\n"181"DCL OUT[0], COLOR\n"182" 0: MOV OUT[0], IN[0]\n"183" 1: END\n";184185handle = graw_parse_fragment_shader(ctx, text);186ctx->bind_fs_state(ctx, handle);187}188189190static void draw( void )191{192union pipe_color_union clear_color = { {1,0,1,1} };193struct pipe_draw_info info;194struct pipe_draw_start_count_bias draw;195196ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);197198199util_draw_init_info(&info);200info.index_size = draw_elements ? 2 : 0;201info.mode = PIPE_PRIM_TRIANGLES;202draw.start = 0;203draw.count = 3;204draw.index_bias = 0;205/* draw NUM_INST triangles */206info.instance_count = NUM_INST;207208/* index data */209if (info.index_size) {210info.index.resource =211pipe_buffer_create_with_data(ctx,212PIPE_BIND_INDEX_BUFFER,213PIPE_USAGE_DEFAULT,214sizeof(indices),215indices);216}217218ctx->draw_vbo(ctx, &info, 0, NULL, &draw, 1);219220pipe_resource_reference(&info.index.resource, NULL);221222ctx->flush(ctx, NULL, 0);223224graw_save_surface_to_file(ctx, surf, NULL);225226screen->flush_frontbuffer(screen, ctx, tex, 0, 0, window, NULL);227}228229230static void init( void )231{232struct pipe_framebuffer_state fb;233struct pipe_resource templat;234struct pipe_surface surf_tmpl;235int i;236237/* It's hard to say whether window or screen should be created238* first. Different environments would prefer one or the other.239*240* Also, no easy way of querying supported formats if the screen241* cannot be created first.242*/243for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {244screen = graw_create_window_and_screen(0, 0, 300, 300,245formats[i],246&window);247if (window && screen)248break;249}250if (!screen || !window) {251fprintf(stderr, "Unable to create window\n");252exit(1);253}254255ctx = screen->context_create(screen, NULL, 0);256if (ctx == NULL)257exit(3);258259memset(&templat, 0, sizeof(templat));260templat.target = PIPE_TEXTURE_2D;261templat.format = formats[i];262templat.width0 = WIDTH;263templat.height0 = HEIGHT;264templat.depth0 = 1;265templat.array_size = 1;266templat.last_level = 0;267templat.bind = (PIPE_BIND_RENDER_TARGET |268PIPE_BIND_DISPLAY_TARGET);269270tex = screen->resource_create(screen,271&templat);272if (tex == NULL)273exit(4);274275surf_tmpl.format = templat.format;276surf_tmpl.u.tex.level = 0;277surf_tmpl.u.tex.first_layer = 0;278surf_tmpl.u.tex.last_layer = 0;279surf = ctx->create_surface(ctx, tex, &surf_tmpl);280if (surf == NULL)281exit(5);282283memset(&fb, 0, sizeof fb);284fb.nr_cbufs = 1;285fb.width = WIDTH;286fb.height = HEIGHT;287fb.cbufs[0] = surf;288289ctx->set_framebuffer_state(ctx, &fb);290291{292struct pipe_blend_state blend;293void *handle;294memset(&blend, 0, sizeof blend);295blend.rt[0].colormask = PIPE_MASK_RGBA;296handle = ctx->create_blend_state(ctx, &blend);297ctx->bind_blend_state(ctx, handle);298}299300{301struct pipe_depth_stencil_alpha_state depthstencil;302void *handle;303memset(&depthstencil, 0, sizeof depthstencil);304handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);305ctx->bind_depth_stencil_alpha_state(ctx, handle);306}307308{309struct pipe_rasterizer_state rasterizer;310void *handle;311memset(&rasterizer, 0, sizeof rasterizer);312rasterizer.cull_face = PIPE_FACE_NONE;313rasterizer.half_pixel_center = 1;314rasterizer.bottom_edge_rule = 1;315rasterizer.depth_clip_near = 1;316rasterizer.depth_clip_far = 1;317handle = ctx->create_rasterizer_state(ctx, &rasterizer);318ctx->bind_rasterizer_state(ctx, handle);319}320321set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);322set_vertices();323set_vertex_shader();324set_fragment_shader();325}326327328static void options(int argc, char *argv[])329{330int i;331332for (i = 1; i < argc;) {333if (graw_parse_args(&i, argc, argv)) {334continue;335}336if (strcmp(argv[i], "-e") == 0) {337draw_elements = 1;338i++;339}340else {341i++;342}343}344if (draw_elements)345printf("Using pipe_context::draw_elements_instanced()\n");346else347printf("Using pipe_context::draw_arrays_instanced()\n");348}349350351int main( int argc, char *argv[] )352{353options(argc, argv);354355init();356357graw_set_display_func( draw );358graw_main_loop();359return 0;360}361362363