/* * Copyright (c) 2012-2013 Etnaviv Project * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* Rotating, animated cube. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "etna_pipe.h" #include "etna_rawshader.h" #include "util/u_inlines.h" #include "write_bmp.h" #include "fbdemos.h" #include "esTransform.h" /*********************************************************************/ #define VERTEX_BUFFER_SIZE 0x60000 uint32_t vs[] = { 0x01831009, 0x00000000, 0x00000000, 0x203fc048, 0x02031009, 0x00000000, 0x00000000, 0x203fc058, 0x07841003, 0x39000800, 0x00000050, 0x00000000, 0x07841002, 0x39001800, 0x00aa0050, 0x00390048, 0x07841002, 0x39002800, 0x01540050, 0x00390048, 0x07841002, 0x39003800, 0x01fe0050, 0x00390048, 0x03851003, 0x29004800, 0x000000d0, 0x00000000, 0x03851002, 0x29005800, 0x00aa00d0, 0x00290058, 0x03811002, 0x29006800, 0x015400d0, 0x00290058, 0x07851003, 0x39007800, 0x00000050, 0x00000000, 0x07851002, 0x39008800, 0x00aa0050, 0x00390058, 0x07851002, 0x39009800, 0x01540050, 0x00390058, 0x07801002, 0x3900a800, 0x01fe0050, 0x00390058, 0x0401100c, 0x00000000, 0x00000000, 0x003fc008, 0x03801002, 0x69000800, 0x01fe00c0, 0x00290038, 0x03831005, 0x29000800, 0x01480040, 0x00000000, 0x0383100d, 0x00000000, 0x00000000, 0x00000038, 0x03801003, 0x29000800, 0x014801c0, 0x00000000, 0x00801005, 0x29001800, 0x01480040, 0x00000000, 0x0080108f, 0x3fc06800, 0x00000050, 0x203fc068, 0x03801003, 0x00000800, 0x01480140, 0x00000000, 0x04001009, 0x00000000, 0x00000000, 0x200000b8, 0x02041001, 0x2a804800, 0x00000000, 0x003fc048, 0x02041003, 0x2a804800, 0x00aa05c0, 0x00000002, }; uint32_t ps[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; const struct etna_shader_program shader = { .num_inputs = 3, .inputs = {{.vs_reg=0},{.vs_reg=1},{.vs_reg=2}}, .num_varyings = 1, .varyings = { {.num_components=4, .special=ETNA_VARYING_VSOUT, .pa_attributes=0x200, .vs_reg=0}, /* color */ }, .vs_code_size = sizeof(vs)/4, .vs_code = (uint32_t*)vs, .vs_pos_out_reg = 4, // t4 out .vs_load_balancing = 0xf3f0542, /* depends on number of inputs/outputs/varyings? XXX how exactly */ .vs_num_temps = 6, .vs_uniforms_size = 12*4, .vs_uniforms = (uint32_t*)(const float[12*4]){ [19] = 2.0f, /* u4.w */ [23] = 20.0f, /* u5.w */ [27] = 0.0f, /* u6.w */ [45] = 0.5f, /* u11.y */ [44] = 1.0f, /* u11.x */ }, .ps_code_size = sizeof(ps)/4, .ps_code = (uint32_t*)ps, .ps_color_out_reg = 1, // t1 out .ps_num_temps = 3, .ps_uniforms_size = 1*4, .ps_uniforms = (uint32_t*)(const float[1*4]){ [0] = 1.0f, }, }; float vVertices[] = { // front -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f, // point magenta -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white // back +1.0f, -1.0f, -1.0f, // point red -1.0f, -1.0f, -1.0f, // point black +1.0f, +1.0f, -1.0f, // point yellow -1.0f, +1.0f, -1.0f, // point green // right +1.0f, -1.0f, +1.0f, // point magenta +1.0f, -1.0f, -1.0f, // point red +1.0f, +1.0f, +1.0f, // point white +1.0f, +1.0f, -1.0f, // point yellow // left -1.0f, -1.0f, -1.0f, // point black -1.0f, -1.0f, +1.0f, // point blue -1.0f, +1.0f, -1.0f, // point green -1.0f, +1.0f, +1.0f, // point cyan // top -1.0f, +1.0f, +1.0f, // point cyan +1.0f, +1.0f, +1.0f, // point white -1.0f, +1.0f, -1.0f, // point green +1.0f, +1.0f, -1.0f, // point yellow // bottom -1.0f, -1.0f, -1.0f, // point black +1.0f, -1.0f, -1.0f, // point red -1.0f, -1.0f, +1.0f, // point blue +1.0f, -1.0f, +1.0f // point magenta }; float vColors[] = { // front 0.0f, 0.0f, 1.0f, // blue 1.0f, 0.0f, 1.0f, // magenta 0.0f, 1.0f, 1.0f, // cyan 1.0f, 1.0f, 1.0f, // white // back 1.0f, 0.0f, 0.0f, // red 0.0f, 0.0f, 0.0f, // black 1.0f, 1.0f, 0.0f, // yellow 0.0f, 1.0f, 0.0f, // green // right 1.0f, 0.0f, 1.0f, // magenta 1.0f, 0.0f, 0.0f, // red 1.0f, 1.0f, 1.0f, // white 1.0f, 1.0f, 0.0f, // yellow // left 0.0f, 0.0f, 0.0f, // black 0.0f, 0.0f, 1.0f, // blue 0.0f, 1.0f, 0.0f, // green 0.0f, 1.0f, 1.0f, // cyan // top 0.0f, 1.0f, 1.0f, // cyan 1.0f, 1.0f, 1.0f, // white 0.0f, 1.0f, 0.0f, // green 1.0f, 1.0f, 0.0f, // yellow // bottom 0.0f, 0.0f, 0.0f, // black 1.0f, 0.0f, 0.0f, // red 0.0f, 0.0f, 1.0f, // blue 1.0f, 0.0f, 1.0f // magenta }; float vNormals[] = { // front +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward +0.0f, +0.0f, +1.0f, // forward // back +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard +0.0f, +0.0f, -1.0f, // backbard // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right +1.0f, +0.0f, +0.0f, // right // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left -1.0f, +0.0f, +0.0f, // left // top +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up +0.0f, +1.0f, +0.0f, // up // bottom +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f, // down +0.0f, -1.0f, +0.0f // down }; #define COMPONENTS_PER_VERTEX (3) #define NUM_VERTICES (6*4) int main(int argc, char **argv) { struct fbdemos_scaffold *fbs = 0; fbdemo_init(&fbs); int width = fbs->width; int height = fbs->height; struct pipe_context *pipe = fbs->pipe; /* resources */ struct pipe_resource *rt_resource = fbdemo_create_2d(fbs->screen, PIPE_BIND_RENDER_TARGET, PIPE_FORMAT_B8G8R8X8_UNORM, width, height, 0); struct pipe_resource *z_resource = fbdemo_create_2d(fbs->screen, PIPE_BIND_RENDER_TARGET, PIPE_FORMAT_Z16_UNORM, width, height, 0); /* bind render target to framebuffer */ etna_fb_bind_resource(fbs, rt_resource); /* geometry */ struct pipe_resource *vtx_resource = pipe_buffer_create(fbs->screen, PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_IMMUTABLE, VERTEX_BUFFER_SIZE); struct pipe_transfer *transfer = 0; float *vtx_logical = pipe_buffer_map(pipe, vtx_resource, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED, &transfer); assert(vtx_logical); for(int vert=0; vertcreate_vertex_elements_state(pipe, sizeof(pipe_vertex_elements)/sizeof(pipe_vertex_elements[0]), pipe_vertex_elements); /* compile other gallium3d states */ void *blend = pipe->create_blend_state(pipe, &(struct pipe_blend_state) { .rt[0] = { .blend_enable = 0, .rgb_func = PIPE_BLEND_ADD, .rgb_src_factor = PIPE_BLENDFACTOR_ONE, .rgb_dst_factor = PIPE_BLENDFACTOR_ZERO, .alpha_func = PIPE_BLEND_ADD, .alpha_src_factor = PIPE_BLENDFACTOR_ONE, .alpha_dst_factor = PIPE_BLENDFACTOR_ZERO, .colormask = 0xf } }); void *rasterizer = pipe->create_rasterizer_state(pipe, &(struct pipe_rasterizer_state){ .flatshade = 0, .light_twoside = 1, .clamp_vertex_color = 1, .clamp_fragment_color = 1, .front_ccw = 0, .cull_face = PIPE_FACE_BACK, /**< PIPE_FACE_x */ .fill_front = PIPE_POLYGON_MODE_FILL, /**< PIPE_POLYGON_MODE_x */ .fill_back = PIPE_POLYGON_MODE_FILL, /**< PIPE_POLYGON_MODE_x */ .offset_point = 0, .offset_line = 0, .offset_tri = 0, .scissor = 0, .poly_smooth = 1, .poly_stipple_enable = 0, .point_smooth = 0, .sprite_coord_mode = 0, /**< PIPE_SPRITE_COORD_ */ .point_quad_rasterization = 0, /** points rasterized as quads or points */ .point_size_per_vertex = 0, /**< size computed in vertex shader */ .multisample = 0, .line_smooth = 0, .line_stipple_enable = 0, .line_last_pixel = 0, .flatshade_first = 0, .half_pixel_center = 1, .rasterizer_discard = 0, .depth_clip = 0, .clip_plane_enable = 0, .line_stipple_factor = 0, .line_stipple_pattern = 0, .sprite_coord_enable = 0, .line_width = 1.0f, .point_size = 1.0f, .offset_units = 0.0f, .offset_scale = 0.0f, .offset_clamp = 0.0f }); void *dsa = pipe->create_depth_stencil_alpha_state(pipe, &(struct pipe_depth_stencil_alpha_state){ .depth = { .enabled = 1, .writemask = 1, .func = PIPE_FUNC_LESS /* GL default */ }, .stencil[0] = { .enabled = 0 }, .stencil[1] = { .enabled = 0 }, .alpha = { .enabled = 0 } }); struct pipe_surface *cbuf = pipe->create_surface(pipe, rt_resource, &(struct pipe_surface){ .texture = rt_resource, .format = rt_resource->format, .u.tex.level = 0 }); struct pipe_surface *zsbuf = pipe->create_surface(pipe, z_resource, &(struct pipe_surface){ .texture = z_resource, .format = z_resource->format, .u.tex.level = 0 }); /* bind */ pipe->bind_blend_state(pipe, blend); pipe->bind_rasterizer_state(pipe, rasterizer); pipe->bind_depth_stencil_alpha_state(pipe, dsa); pipe->bind_vertex_elements_state(pipe, vertex_elements); pipe->set_blend_color(pipe, &(struct pipe_blend_color){ .color = {0.0f,0.0f,0.0f,1.0f} }); pipe->set_stencil_ref(pipe, &(struct pipe_stencil_ref){ .ref_value[0] = 0xff, .ref_value[1] = 0xff }); pipe->set_sample_mask(pipe, 0xf); pipe->set_framebuffer_state(pipe, &(struct pipe_framebuffer_state){ .width = width, .height = height, .nr_cbufs = 1, .cbufs[0] = cbuf, .zsbuf = zsbuf }); pipe->set_scissor_states(pipe, 0, 1, &(struct pipe_scissor_state){ .minx = 0, .miny = 0, .maxx = 65535, .maxy = 65535 }); pipe->set_viewport_states(pipe, 0, 1, &(struct pipe_viewport_state){ .scale = {width/2.0f, height/2.0f, 0.5f, 1.0f}, .translate = {width/2.0f, height/2.0f, 0.5f, 1.0f} }); pipe->set_vertex_buffers(pipe, 0, 1, &vertex_buffer_desc); pipe->set_index_buffer(pipe, NULL); void *shader_state = etna_create_shader_state(pipe, &shader); etna_bind_shader_state(pipe, shader_state); for(int frame=0; frame<1000; ++frame) { if(frame%50 == 0) printf("*** FRAME %i ****\n", frame); /* Compute transform matrices in the same way as cube egl demo */ ESMatrix modelview, projection, modelviewprojection; ESMatrix inverse, normal; esMatrixLoadIdentity(&modelview); esTranslate(&modelview, 0.0f, 0.0f, -8.0f); esRotate(&modelview, 45.0f, 1.0f, 0.0f, 0.0f); esRotate(&modelview, 45.0f, 0.0f, 1.0f, 0.0f); esRotate(&modelview, frame*0.5f, 0.0f, 0.0f, 1.0f); float aspect = (float)(height) / (float)(width); esMatrixLoadIdentity(&projection); esFrustum(&projection, -2.8f, +2.8f, -2.8f * aspect, +2.8f * aspect, 6.0f, 10.0f); esMatrixLoadIdentity(&modelviewprojection); esMatrixMultiply(&modelviewprojection, &modelview, &projection); esMatrixInverse3x3(&inverse, &modelview); esMatrixTranspose(&normal, &inverse); /* Clear render target */ pipe->clear(pipe, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, &(const union pipe_color_union) { .f = {0.2, 0.2, 0.2, 1.0} }, 1.0, 0xff); etna_set_uniforms(pipe, PIPE_SHADER_VERTEX, 0, 16, (uint32_t*)&modelviewprojection.m[0][0]); etna_set_uniforms(pipe, PIPE_SHADER_VERTEX, 16, 3, (uint32_t*)&normal.m[0][0]); /* u4.xyz */ etna_set_uniforms(pipe, PIPE_SHADER_VERTEX, 20, 3, (uint32_t*)&normal.m[1][0]); /* u5.xyz */ etna_set_uniforms(pipe, PIPE_SHADER_VERTEX, 24, 3, (uint32_t*)&normal.m[2][0]); /* u6.xyz */ etna_set_uniforms(pipe, PIPE_SHADER_VERTEX, 28, 16, (uint32_t*)&modelview.m[0][0]); for(int prim=0; prim<6; ++prim) { pipe->draw_vbo(pipe, &(struct pipe_draw_info){ .indexed = 0, .mode = PIPE_PRIM_TRIANGLE_STRIP, .start = prim*4, .count = 4 }); } etna_swap_buffers(fbs->buffers); } #ifdef DUMP bmp_dump32(etna_bo_map(fbs->fb.buffer[1-fbs->buffers->backbuffer]), width, height, false, "/mnt/sdcard/fb.bmp"); printf("Dump complete\n"); #endif fbdemo_free(fbs); return 0; }