int main(int argc, char **argv) { int rv; int width = 256; int height = 256; fb_info fb; rv = fb_open(0, &fb); if(rv!=0) { exit(1); } width = fb.fb_var.xres; height = fb.fb_var.yres; rv = viv_open(); if(rv!=0) { fprintf(stderr, "Error opening device\n"); exit(1); } printf("Succesfully opened device\n"); etna_ctx *ctx = 0; struct pipe_context *pipe = 0; etna_bswap_buffers *buffers = 0; if(etna_create(&ctx) != ETNA_OK || etna_bswap_create(ctx, &buffers, (etna_set_buffer_cb_t)&fb_set_buffer, (etna_copy_buffer_cb_t)&etna_fb_copy_buffer, &fb) != ETNA_OK || (pipe = etna_new_pipe_context(ctx)) == NULL) { printf("Unable to create etna context\n"); exit(1); } /* Convert and upload embedded texture */ struct pipe_resource *tex_resource = etna_pipe_create_2d(pipe, ETNA_IS_TEXTURE, PIPE_FORMAT_B8G8R8X8_UNORM, COMPANION_TEXTURE_WIDTH, COMPANION_TEXTURE_HEIGHT, 0); void *temp = malloc(COMPANION_TEXTURE_WIDTH * COMPANION_TEXTURE_HEIGHT * 4); etna_convert_r8g8b8_to_b8g8r8x8(temp, (const uint8_t*)companion_texture, COMPANION_TEXTURE_WIDTH * COMPANION_TEXTURE_HEIGHT); etna_pipe_inline_write(pipe, tex_resource, 0, 0, temp, COMPANION_TEXTURE_WIDTH * COMPANION_TEXTURE_HEIGHT * 4); free(temp); /* resources */ struct pipe_resource *rt_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_B8G8R8X8_UNORM, width, height, 0); struct pipe_resource *z_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_Z16_UNORM, width, height, 0); /* bind render target to framebuffer */ etna_fb_bind_resource(&fb, rt_resource); /* geometry */ struct pipe_resource *vtx_resource = etna_pipe_create_buffer(pipe, ETNA_IS_VERTEX, VERTEX_BUFFER_SIZE); struct pipe_resource *idx_resource = etna_pipe_create_buffer(pipe, ETNA_IS_INDEX, INDEX_BUFFER_SIZE); float *vtx_logical = etna_pipe_get_resource_ptr(pipe, vtx_resource, 0, 0); assert(vtx_logical); float *idx_logical = etna_pipe_get_resource_ptr(pipe, idx_resource, 0, 0); assert(idx_logical); #ifndef INDEXED printf("Interleaving vertices...\n"); float *vertices_array = companion_vertices_array(); float *texture_coordinates_array = companion_texture_coordinates_array(); float *normals_array = companion_normals_array(); assert(COMPANION_ARRAY_COUNT*(3+3+2)*sizeof(float) < VERTEX_BUFFER_SIZE); for(int vert=0; vert<COMPANION_ARRAY_COUNT; ++vert) { int dest_idx = vert * (3 + 3 + 2); for(int comp=0; comp<3; ++comp) ((float*)vtx_logical)[dest_idx+comp+0] = vertices_array[vert*3 + comp]; /* 0 */ for(int comp=0; comp<3; ++comp) ((float*)vtx_logical)[dest_idx+comp+3] = normals_array[vert*3 + comp]; /* 1 */ for(int comp=0; comp<2; ++comp) ((float*)vtx_logical)[dest_idx+comp+6] = texture_coordinates_array[vert*2 + comp]; /* 2 */ } #else printf("Interleaving vertices and copying index buffer...\n"); assert(COMPANION_VERTEX_COUNT*(3+3+2)*sizeof(float) < VERTEX_BUFFER_SIZE); for(int vert=0; vert<COMPANION_VERTEX_COUNT; ++vert) { int dest_idx = vert * (3 + 3 + 2); for(int comp=0; comp<3; ++comp) ((float*)vtx_logical)[dest_idx+comp+0] = companion_vertices[vert][comp]; /* 0 */ for(int comp=0; comp<3; ++comp) ((float*)vtx_logical)[dest_idx+comp+3] = companion_normals[vert][comp]; /* 1 */ for(int comp=0; comp<2; ++comp) ((float*)vtx_logical)[dest_idx+comp+6] = companion_texture_coordinates[vert][comp]; /* 2 */ } assert(COMPANION_TRIANGLE_COUNT*3*sizeof(unsigned short) < INDEX_BUFFER_SIZE); memcpy(idx_logical, &companion_triangles[0][0], COMPANION_TRIANGLE_COUNT*3*sizeof(unsigned short)); #endif struct pipe_vertex_buffer vertex_buffer_desc = { .stride = (3 + 3 + 2)*4, .buffer_offset = 0, .buffer = vtx_resource, .user_buffer = 0 }; struct pipe_index_buffer index_buffer_desc = { .index_size = sizeof(unsigned short), .offset = 0, .buffer = idx_resource, .user_buffer = 0 }; struct pipe_vertex_element pipe_vertex_elements[] = { { /* positions */ .src_offset = 0, .instance_divisor = 0, .vertex_buffer_index = 0, .src_format = PIPE_FORMAT_R32G32B32_FLOAT }, { /* normals */ .src_offset = 0xc, .instance_divisor = 0, .vertex_buffer_index = 0, .src_format = PIPE_FORMAT_R32G32B32_FLOAT }, { /* texture coord */ .src_offset = 0x18, .instance_divisor = 0, .vertex_buffer_index = 0, .src_format = PIPE_FORMAT_R32G32_FLOAT } };
.maxx = 65535, .maxy = 65535 }); pipe->set_viewport_state(pipe, &(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_fragment_sampler_views(pipe, 1, &sampler_view); pipe->set_vertex_buffers(pipe, 0, 1, &vertex_buffer_desc); pipe->set_index_buffer(pipe, NULL); void *shader_state = pipe->create_etna_shader_state(pipe, &shader); pipe->bind_etna_shader_state(pipe, shader_state); /* Fill in particle data array */ float *vtx_logical = etna_pipe_get_resource_ptr(pipe, vtx_resource, 0, 0); srand(0); for(int i = 0; i < NUM_PARTICLES; i++) { float *particleData = &vtx_logical[i * PARTICLE_SIZE]; // Lifetime of particle (*particleData++) = ( (float)(rand() % 10000) / 10000.0f ); // End position of particle (*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f; (*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f; (*particleData++) = ( (float)(rand() % 10000) / 5000.0f ) - 1.0f; // Start position of particle (*particleData++) = ( (float)(rand() % 10000) / 40000.0f ) - 0.125f;
int main(int argc, char **argv) { int rv; int width = 256; int height = 256; fb_info fb; rv = fb_open(0, &fb); if(rv!=0) { exit(1); } width = fb.fb_var.xres; height = fb.fb_var.yres; rv = viv_open(); if(rv!=0) { fprintf(stderr, "Error opening device\n"); exit(1); } printf("Succesfully opened device\n"); etna_ctx *ctx = 0; struct pipe_context *pipe = 0; etna_bswap_buffers *buffers = 0; if(etna_create(&ctx) != ETNA_OK || etna_bswap_create(ctx, &buffers, (etna_set_buffer_cb_t)&fb_set_buffer, (etna_copy_buffer_cb_t)&etna_fb_copy_buffer, &fb) != ETNA_OK || (pipe = etna_new_pipe_context(ctx)) == NULL) { printf("Unable to create etna context\n"); exit(1); } /* resources */ struct pipe_resource *rt_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_B8G8R8X8_UNORM, width, height, 0); struct pipe_resource *z_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_Z16_UNORM, width, height, 0); struct pipe_resource *vtx_resource = etna_pipe_create_buffer(pipe, ETNA_IS_VERTEX, VERTEX_BUFFER_SIZE); /* bind render target to framebuffer */ etna_fb_bind_resource(&fb, rt_resource); /* interleave vertex data */ float *vtx_logical = etna_pipe_get_resource_ptr(pipe, vtx_resource, 0, 0); assert(vtx_logical); for(int vert=0; vert<NUM_VERTICES; ++vert) { int dest_idx = vert * (3 + 3 + 3); for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+0] = vVertices[vert*3 + comp]; /* 0 */ for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+3] = vNormals[vert*3 + comp]; /* 1 */ for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+6] = vColors[vert*3 + comp]; /* 2 */ } /* compile gallium3d states */ void *blend = pipe->create_blend_state(pipe, &(struct pipe_blend_state) { .rt[0] = { .blend_enable = 1, .rgb_func = PIPE_BLEND_ADD, .rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA, .rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA, .alpha_func = PIPE_BLEND_ADD, .alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA, .alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA, .colormask = 0xf } });
int main(int argc, char **argv) { int rv; int width = 256; int height = 256; fb_info fb; rv = fb_open(0, &fb); if(rv!=0) { exit(1); } width = fb.fb_var.xres; height = fb.fb_var.yres; rv = viv_open(); if(rv!=0) { fprintf(stderr, "Error opening device\n"); exit(1); } printf("Succesfully opened device\n"); etna_ctx *ctx = 0; struct pipe_context *pipe = 0; etna_bswap_buffers *buffers = 0; if(etna_create(&ctx) != ETNA_OK || etna_bswap_create(ctx, &buffers, (etna_set_buffer_cb_t)&fb_set_buffer, (etna_copy_buffer_cb_t)&etna_fb_copy_buffer, &fb) != ETNA_OK || (pipe = etna_new_pipe_context(ctx)) == NULL) { printf("Unable to create etna context\n"); exit(1); } struct pipe_resource *tex_resource = etna_pipe_create_2d(pipe, ETNA_IS_TEXTURE | ETNA_IS_CUBEMAP, FMT_X8R8G8B8, 1, 1, 0); uint32_t tex_data[6] = { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00, 0xffff00ff, 0xffffffff }; for(int layerid=0; layerid<6; ++layerid) etna_pipe_inline_write(pipe, tex_resource, layerid, 0, &tex_data[layerid], sizeof(uint32_t)); /* resources */ struct pipe_resource *rt_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_B8G8R8X8_UNORM, width, height, 0); struct pipe_resource *z_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_Z16_UNORM, width, height, 0); struct pipe_resource *vtx_resource = etna_pipe_create_buffer(pipe, ETNA_IS_VERTEX, VERTEX_BUFFER_SIZE); struct pipe_resource *idx_resource = etna_pipe_create_buffer(pipe, ETNA_IS_INDEX, VERTEX_BUFFER_SIZE); /* bind render target to framebuffer */ etna_fb_bind_resource(&fb, rt_resource); /* Phew, now we got all the memory we need. * Write interleaved attribute vertex stream. * Unlike the GL example we only do this once, not every time glDrawArrays is called, the same would be accomplished * from GL by using a vertex buffer object. */ GLfloat *vVertices; GLfloat *vNormals; GLfloat *vTexCoords; GLushort *vIndices; int numVertices = 0; int numIndices = esGenSphere(20, 1.0f, &vVertices, &vNormals, &vTexCoords, &vIndices, &numVertices); float *vtx_logical = etna_pipe_get_resource_ptr(pipe, vtx_resource, 0, 0); for(int vert=0; vert<numVertices; ++vert) { int dest_idx = vert * (3 + 3 + 2); for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+0] = vVertices[vert*3 + comp]; /* 0 */ for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+3] = vNormals[vert*3 + comp]; /* 1 */ for(int comp=0; comp<2; ++comp) vtx_logical[dest_idx+comp+6] = vTexCoords[vert*2 + comp]; /* 2 */ } memcpy(idx_resource->levels[0].logical, vIndices, numIndices*sizeof(GLushort)); /* compile 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 } });
int main(int argc, char **argv) { int rv; int width = 256; int height = 256; fb_info fb; rv = fb_open(0, &fb); if(rv!=0) { exit(1); } width = fb.fb_var.xres; height = fb.fb_var.yres; rv = viv_open(); if(rv!=0) { fprintf(stderr, "Error opening device\n"); exit(1); } printf("Succesfully opened device\n"); etna_ctx *ctx = 0; struct pipe_context *pipe = 0; etna_bswap_buffers *buffers = 0; if(etna_create(&ctx) != ETNA_OK || etna_bswap_create(ctx, &buffers, (etna_set_buffer_cb_t)&fb_set_buffer, (etna_copy_buffer_cb_t)&etna_fb_copy_buffer, &fb) != ETNA_OK || (pipe = etna_new_pipe_context(ctx)) == NULL) { printf("Unable to create etna context\n"); exit(1); } dds_texture *dds = 0; if(argc<2 || !dds_load(argv[1], &dds)) { printf("Error loading texture\n"); exit(1); } uint32_t tex_format = 0; uint32_t tex_base_width = dds->slices[0][0].width; uint32_t tex_base_height = dds->slices[0][0].height; switch(dds->fmt) { case FMT_A8R8G8B8: tex_format = PIPE_FORMAT_B8G8R8A8_UNORM; break; case FMT_X8R8G8B8: tex_format = PIPE_FORMAT_B8G8R8X8_UNORM; break; case FMT_DXT1: tex_format = PIPE_FORMAT_DXT1_RGB; break; case FMT_DXT3: tex_format = PIPE_FORMAT_DXT3_RGBA; break; case FMT_DXT5: tex_format = PIPE_FORMAT_DXT5_RGBA; break; case FMT_ETC1: tex_format = PIPE_FORMAT_ETC1_RGB8; break; default: printf("Unknown texture format\n"); exit(1); } struct pipe_resource *tex_resource = etna_pipe_create_2d(pipe, ETNA_IS_TEXTURE, tex_format, tex_base_width, tex_base_height, dds->num_mipmaps - 1); printf("Loading compressed texture (format %i, %ix%i)\n", dds->fmt, tex_base_width, tex_base_height); for(int ix=0; ix<dds->num_mipmaps; ++ix) { printf("%08x: Uploading mipmap %i (%ix%i)\n", dds->slices[0][ix].offset, ix, dds->slices[0][ix].width, dds->slices[0][ix].height); etna_pipe_inline_write(pipe, tex_resource, 0, ix, dds->slices[0][ix].data, dds->slices[0][ix].size); } /* resources */ struct pipe_resource *rt_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_B8G8R8X8_UNORM, width, height, 0); struct pipe_resource *z_resource = etna_pipe_create_2d(pipe, ETNA_IS_RENDER_TARGET, PIPE_FORMAT_Z16_UNORM, width, height, 0); struct pipe_resource *vtx_resource = etna_pipe_create_buffer(pipe, ETNA_IS_VERTEX, VERTEX_BUFFER_SIZE); /* bind render target to framebuffer */ etna_fb_bind_resource(&fb, rt_resource); /* Phew, now we got all the memory we need. * Write interleaved attribute vertex stream. * Unlike the GL example we only do this once, not every time glDrawArrays is called, the same would be accomplished * from GL by using a vertex buffer object. */ float *vtx_logical = etna_pipe_get_resource_ptr(pipe, vtx_resource, 0, 0); assert(vtx_logical); for(int vert=0; vert<NUM_VERTICES; ++vert) { int dest_idx = vert * (3 + 3 + 2); for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+0] = vVertices[vert*3 + comp]; /* 0 */ for(int comp=0; comp<3; ++comp) vtx_logical[dest_idx+comp+3] = vNormals[vert*3 + comp]; /* 1 */ for(int comp=0; comp<2; ++comp) vtx_logical[dest_idx+comp+6] = vTexCoords[vert*2 + comp]; /* 2 */ } /* compile 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 } });