static struct pipe_context * etna_screen_context_create( struct pipe_screen *screen, void *priv ) { struct etna_screen *es = etna_screen(screen); struct pipe_context *ctx = etna_new_pipe_context(es->dev, &es->specs, screen, priv); return ctx; }
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 } };
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); } /* textore */ int tex_base_width = 0; int tex_base_height = 0; if(argc<2) { printf("Pass path to smoke.tga on command line\n"); exit(1); } uint8_t *tex_buffer = (uint8_t*)esLoadTGA(argv[1], &tex_base_width, &tex_base_height ); if(!tex_buffer) { printf("Could not load texture\n"); exit(1); } struct pipe_resource *tex_resource = etna_pipe_create_2d(pipe, ETNA_IS_TEXTURE, PIPE_FORMAT_B8G8R8X8_UNORM, tex_base_width, tex_base_height, 0); printf("Uploading texture (%ix%i)\n", tex_base_width, tex_base_height); uint32_t *temp = malloc(tex_base_width * tex_base_height * 4); etna_convert_r8g8b8_to_b8g8r8x8(temp, tex_buffer, tex_base_width * tex_base_height); etna_pipe_inline_write(pipe, tex_resource, 0, 0, temp, tex_base_width * tex_base_height * 4); free(temp); /* render target resources and surfaces */ 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); /* surfaces */ struct pipe_surface *cbuf = pipe->create_surface(pipe, rt_resource, &(struct pipe_surface){ .texture = rt_resource, .format = rt_resource->format, .u.tex.level = 0 });
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); } /* 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); } 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 } });