struct cso_context *cso_create_context( struct pipe_context *pipe ) { struct cso_context *ctx = CALLOC_STRUCT(cso_context); if (ctx == NULL) goto out; assert(PIPE_MAX_SAMPLERS == PIPE_MAX_VERTEX_SAMPLERS); ctx->cache = cso_cache_create(); if (ctx->cache == NULL) goto out; cso_cache_set_sanitize_callback(ctx->cache, sanitize_hash, ctx); ctx->pipe = pipe; /* Enable for testing: */ if (0) cso_set_maximum_cache_size( ctx->cache, 4 ); return ctx; out: cso_destroy_context( ctx ); return NULL; }
void vg_destroy_context(struct vg_context *ctx) { struct pipe_resource **cbuf = &ctx->mask.cbuf; renderer_destroy(ctx->renderer); shaders_cache_destroy(ctx->sc); shader_destroy(ctx->shader); paint_destroy(ctx->default_paint); if (*cbuf) pipe_resource_reference(cbuf, NULL); if (ctx->mask.union_fs) vg_shader_destroy(ctx, ctx->mask.union_fs); if (ctx->mask.intersect_fs) vg_shader_destroy(ctx, ctx->mask.intersect_fs); if (ctx->mask.subtract_fs) vg_shader_destroy(ctx, ctx->mask.subtract_fs); if (ctx->mask.set_fs) vg_shader_destroy(ctx, ctx->mask.set_fs); cso_destroy_context(ctx->cso_context); cso_hash_delete(ctx->owned_objects[VG_OBJECT_PAINT]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_IMAGE]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_MASK]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_FONT]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_PATH]); api_destroy_dispatch(ctx->dispatch); FREE(ctx); }
void st_context_destroy(struct st_context *st_ctx) { unsigned i; if(st_ctx) { struct st_device *st_dev = st_ctx->st_dev; if(st_ctx->cso) { cso_delete_vertex_shader(st_ctx->cso, st_ctx->vs); cso_delete_fragment_shader(st_ctx->cso, st_ctx->fs); cso_destroy_context(st_ctx->cso); } if(st_ctx->pipe) st_ctx->pipe->destroy(st_ctx->pipe); for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); pipe_texture_reference(&st_ctx->default_texture, NULL); FREE(st_ctx); st_device_reference(&st_dev, NULL); } }
void st_destroy_context( struct st_context *st ) { struct pipe_context *pipe = st->pipe; struct cso_context *cso = st->cso_context; GLcontext *ctx = st->ctx; GLuint i; /* need to unbind and destroy CSO objects before anything else */ cso_release_all(st->cso_context); st_reference_fragprog(st, &st->fp, NULL); st_reference_vertprog(st, &st->vp, NULL); /* release framebuffer surfaces */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { pipe_surface_reference(&st->state.framebuffer.cbufs[i], NULL); } pipe_surface_reference(&st->state.framebuffer.zsbuf, NULL); _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); _vbo_DestroyContext(st->ctx); _mesa_free_context_data(ctx); st_destroy_context_priv(st); cso_destroy_context(cso); pipe->destroy( pipe ); free(ctx); }
int main() { struct program *program = calloc(1, sizeof(struct program)); struct pipe_loader_device **devs = NULL; const int max_devices = 32; int idev, ndev; /* find & list graphic devices */ ndev = pipe_loader_probe(&program->dev, max_devices); devs = &program->dev; for (idev = 0; idev < ndev; idev++) { printf("driver name: %s; type: %d\n", devs[idev]->driver_name, devs[idev]->type); } /* init a pipe screen */ program->screen = pipe_loader_create_screen(devs[0], PIPE_SEARCH_DIR); /* create the pipe driver context and cso context */ program->pipe = program->screen->context_create(program->screen, NULL); program->cso = cso_create_context(program->pipe); /* destroy */ cso_destroy_context(program->cso); program->pipe->destroy(program->pipe); program->screen->destroy(program->screen); return 0; }
XA_EXPORT void xa_context_destroy(struct xa_context *r) { struct pipe_resource **vsbuf = &r->vs_const_buffer; struct pipe_resource **fsbuf = &r->fs_const_buffer; if (*vsbuf) pipe_resource_reference(vsbuf, NULL); if (*fsbuf) pipe_resource_reference(fsbuf, NULL); if (r->shaders) { xa_shaders_destroy(r->shaders); r->shaders = NULL; } xa_ctx_sampler_views_destroy(r); if (r->cso) { cso_release_all(r->cso); cso_destroy_context(r->cso); r->cso = NULL; } r->pipe->destroy(r->pipe); }
void vg_destroy_context(struct vg_context *ctx) { struct pipe_resource **cbuf = &ctx->mask.cbuf; struct pipe_resource **vsbuf = &ctx->vs_const_buffer; util_destroy_blit(ctx->blit); renderer_destroy(ctx->renderer); shaders_cache_destroy(ctx->sc); shader_destroy(ctx->shader); paint_destroy(ctx->default_paint); if (*cbuf) pipe_resource_reference(cbuf, NULL); if (*vsbuf) pipe_resource_reference(vsbuf, NULL); if (ctx->clear.fs) { cso_delete_fragment_shader(ctx->cso_context, ctx->clear.fs); ctx->clear.fs = NULL; } if (ctx->plain_vs) { vg_shader_destroy(ctx, ctx->plain_vs); ctx->plain_vs = NULL; } if (ctx->clear_vs) { vg_shader_destroy(ctx, ctx->clear_vs); ctx->clear_vs = NULL; } if (ctx->texture_vs) { vg_shader_destroy(ctx, ctx->texture_vs); ctx->texture_vs = NULL; } if (ctx->pass_through_depth_fs) vg_shader_destroy(ctx, ctx->pass_through_depth_fs); if (ctx->mask.union_fs) vg_shader_destroy(ctx, ctx->mask.union_fs); if (ctx->mask.intersect_fs) vg_shader_destroy(ctx, ctx->mask.intersect_fs); if (ctx->mask.subtract_fs) vg_shader_destroy(ctx, ctx->mask.subtract_fs); if (ctx->mask.set_fs) vg_shader_destroy(ctx, ctx->mask.set_fs); cso_release_all(ctx->cso_context); cso_destroy_context(ctx->cso_context); cso_hash_delete(ctx->owned_objects[VG_OBJECT_PAINT]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_IMAGE]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_MASK]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_FONT]); cso_hash_delete(ctx->owned_objects[VG_OBJECT_PATH]); api_destroy_dispatch(ctx->dispatch); FREE(ctx); }
void util_test_constant_buffer(struct pipe_context *ctx, struct pipe_resource *constbuf) { struct cso_context *cso; struct pipe_resource *cb; void *fs, *vs; bool pass = true; static const float zero[] = {0, 0, 0, 0}; cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); pipe_set_constant_buffer(ctx, PIPE_SHADER_FRAGMENT, 0, constbuf); /* Fragment shader. */ { static const char *text = /* I don't like ureg... */ "FRAG\n" "DCL CONST[0][0]\n" "DCL OUT[0], COLOR\n" "MOV OUT[0], CONST[0][0]\n" "END\n"; struct tgsi_token tokens[1000]; struct pipe_shader_state state; if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { puts("Can't compile a fragment shader."); util_report_result(FAIL); return; } pipe_shader_state_from_tgsi(&state, tokens); fs = ctx->create_fs_state(ctx, &state); cso_set_fragment_shader_handle(cso, fs); } /* Vertex shader. */ vs = util_set_passthrough_vertex_shader(cso, ctx, false); util_draw_fullscreen_quad(cso); /* Probe pixels. */ pass = pass && util_probe_rect_rgba(ctx, cb, 0, 0, cb->width0, cb->height0, zero); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_resource_reference(&cb, NULL); util_report_result(pass); }
static void null_sampler_view(struct pipe_context *ctx, unsigned tgsi_tex_target) { struct cso_context *cso; struct pipe_resource *cb; void *fs, *vs; bool pass = true; /* 2 expected colors: */ static const float expected_tex[] = {0, 0, 0, 1, 0, 0, 0, 0}; static const float expected_buf[] = {0, 0, 0, 0}; const float *expected = tgsi_tex_target == TGSI_TEXTURE_BUFFER ? expected_buf : expected_tex; unsigned num_expected = tgsi_tex_target == TGSI_TEXTURE_BUFFER ? 1 : 2; if (tgsi_tex_target == TGSI_TEXTURE_BUFFER && !ctx->screen->get_param(ctx->screen, PIPE_CAP_TEXTURE_BUFFER_OBJECTS)) { util_report_result_helper(SKIP, "%s: %s", __func__, tgsi_texture_names[tgsi_tex_target]); return; } cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM, 0); util_set_common_states_and_clear(cso, ctx, cb); ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, NULL); /* Fragment shader. */ fs = util_make_fragment_tex_shader(ctx, tgsi_tex_target, TGSI_INTERPOLATE_LINEAR, TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, false, false); cso_set_fragment_shader_handle(cso, fs); /* Vertex shader. */ vs = util_set_passthrough_vertex_shader(cso, ctx, false); util_draw_fullscreen_quad(cso); /* Probe pixels. */ pass = pass && util_probe_rect_rgba_multi(ctx, cb, 0, 0, cb->width0, cb->height0, expected, num_expected); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_resource_reference(&cb, NULL); util_report_result_helper(pass, "%s: %s", __func__, tgsi_texture_names[tgsi_tex_target]); }
/** * Test TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION. * * The viewport state is set as usual, but it should have no effect. * Clipping should also be disabled. * * POSITION.xyz should already be multiplied by 1/w and POSITION.w should * contain 1/w. By setting w=0, we can test that POSITION.xyz isn't * multiplied by 1/w (otherwise nothing would be rendered). * * TODO: Whether the value of POSITION.w is correctly interpreted as 1/w * during perspective interpolation is not tested. */ static void tgsi_vs_window_space_position(struct pipe_context *ctx) { struct cso_context *cso; struct pipe_resource *cb; void *fs, *vs; bool pass = true; static const float red[] = {1, 0, 0, 1}; if (!ctx->screen->get_param(ctx->screen, PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION)) { util_report_result(SKIP); return; } cso = cso_create_context(ctx); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM); util_set_common_states_and_clear(cso, ctx, cb); /* Fragment shader. */ fs = util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC, TGSI_INTERPOLATE_LINEAR, TRUE); cso_set_fragment_shader_handle(cso, fs); /* Vertex shader. */ vs = util_set_passthrough_vertex_shader(cso, ctx, true); /* Draw. */ { static float vertices[] = { 0, 0, 0, 0, 1, 0, 0, 1, 0, 256, 0, 0, 1, 0, 0, 1, 256, 256, 0, 0, 1, 0, 0, 1, 256, 0, 0, 0, 1, 0, 0, 1, }; util_set_interleaved_vertex_elements(cso, 2); util_draw_user_vertex_buffer(cso, vertices, PIPE_PRIM_QUADS, 4, 2); } /* Probe pixels. */ pass = pass && util_probe_rect_rgba(ctx, cb, 0, 0, cb->width0, cb->height0, red); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_resource_reference(&cb, NULL); util_report_result(pass); }
struct cso_context *cso_create_context( struct pipe_context *pipe ) { struct cso_context *ctx = CALLOC_STRUCT(cso_context); if (!ctx) goto out; ctx->cache = cso_cache_create(); if (ctx->cache == NULL) goto out; cso_cache_set_sanitize_callback(ctx->cache, sanitize_hash, ctx); ctx->pipe = pipe; ctx->sample_mask = ~0; ctx->aux_vertex_buffer_index = 0; /* 0 for now */ cso_init_vbuf(ctx); /* Enable for testing: */ if (0) cso_set_maximum_cache_size( ctx->cache, 4 ); if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { ctx->has_geometry_shader = TRUE; } if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { ctx->has_tessellation = TRUE; } if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { int supported_irs = pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_COMPUTE, PIPE_SHADER_CAP_SUPPORTED_IRS); if (supported_irs & (1 << PIPE_SHADER_IR_TGSI)) { ctx->has_compute_shader = TRUE; } } if (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) { ctx->has_streamout = TRUE; } return ctx; out: cso_destroy_context( ctx ); return NULL; }
void st_destroy_context( struct st_context *st ) { struct pipe_context *pipe = st->pipe; struct cso_context *cso = st->cso_context; struct gl_context *ctx = st->ctx; GLuint i; _mesa_HashWalk(ctx->Shared->TexObjects, destroy_tex_sampler_cb, st); /* need to unbind and destroy CSO objects before anything else */ cso_release_all(st->cso_context); st_reference_fragprog(st, &st->fp, NULL); st_reference_geomprog(st, &st->gp, NULL); st_reference_vertprog(st, &st->vp, NULL); /* release framebuffer surfaces */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { pipe_surface_reference(&st->state.framebuffer.cbufs[i], NULL); } pipe_surface_reference(&st->state.framebuffer.zsbuf, NULL); pipe->set_index_buffer(pipe, NULL); for (i = 0; i < PIPE_SHADER_TYPES; i++) { pipe->set_constant_buffer(pipe, i, 0, NULL); } _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); _vbo_DestroyContext(st->ctx); st_destroy_program_variants(st); _mesa_free_context_data(ctx); /* This will free the st_context too, so 'st' must not be accessed * afterwards. */ st_destroy_context_priv(st); st = NULL; cso_destroy_context(cso); pipe->destroy( pipe ); free(ctx); }
static void close_prog(struct program *p) { /* unset all state */ cso_release_all(p->cso); p->pipe->delete_vs_state(p->pipe, p->vs); p->pipe->delete_fs_state(p->pipe, p->fs); pipe_surface_reference(&p->framebuffer.cbufs[0], NULL); pipe_resource_reference(&p->target, NULL); pipe_resource_reference(&p->vbuf, NULL); cso_destroy_context(p->cso); p->pipe->destroy(p->pipe); p->screen->destroy(p->screen); pipe_loader_release(&p->dev, 1); FREE(p); }
void renderer_destroy(struct xorg_renderer *r) { struct pipe_constant_buffer *vsbuf = &r->vs_const_buffer; struct pipe_constant_buffer *fsbuf = &r->fs_const_buffer; if (vsbuf && vsbuf->buffer) pipe_buffer_reference(&vsbuf->buffer, NULL); if (fsbuf && fsbuf->buffer) pipe_buffer_reference(&fsbuf->buffer, NULL); if (r->shaders) { xorg_shaders_destroy(r->shaders); r->shaders = NULL; } if (r->cso) { cso_release_all(r->cso); cso_destroy_context(r->cso); r->cso = NULL; } }
struct cso_context *cso_create_context( struct pipe_context *pipe ) { struct cso_context *ctx = CALLOC_STRUCT(cso_context); if (ctx == NULL) goto out; ctx->cache = cso_cache_create(); if (ctx->cache == NULL) goto out; cso_cache_set_sanitize_callback(ctx->cache, sanitize_hash, ctx); ctx->pipe = pipe; ctx->sample_mask_saved = ~0; ctx->aux_vertex_buffer_index = 0; /* 0 for now */ cso_init_vbuf(ctx); /* Enable for testing: */ if (0) cso_set_maximum_cache_size( ctx->cache, 4 ); if (pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { ctx->has_geometry_shader = TRUE; } if (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) { ctx->has_streamout = TRUE; } return ctx; out: cso_destroy_context( ctx ); return NULL; }
void xa_context_destroy(struct xa_context *r) { struct pipe_resource **vsbuf = &r->vs_const_buffer; struct pipe_resource **fsbuf = &r->fs_const_buffer; if (*vsbuf) pipe_resource_reference(vsbuf, NULL); if (*fsbuf) pipe_resource_reference(fsbuf, NULL); if (r->shaders) { xa_shaders_destroy(r->shaders); r->shaders = NULL; } if (r->cso) { cso_release_all(r->cso); cso_destroy_context(r->cso); r->cso = NULL; } }
static void close_prog(struct program *p) { /* unset bound textures as well */ cso_set_fragment_sampler_views(p->cso, 0, NULL); /* unset all state */ cso_release_all(p->cso); p->pipe->delete_vs_state(p->pipe, p->vs); p->pipe->delete_fs_state(p->pipe, p->fs); pipe_surface_reference(&p->framebuffer.cbufs[0], NULL); pipe_sampler_view_reference(&p->view, NULL); pipe_resource_reference(&p->target, NULL); pipe_resource_reference(&p->tex, NULL); pipe_resource_reference(&p->vbuf, NULL); cso_destroy_context(p->cso); p->pipe->destroy(p->pipe); p->screen->destroy(p->screen); FREE(p); }
static void st_destroy_context_priv(struct st_context *st) { uint shader, i; st_destroy_atoms( st ); st_destroy_draw( st ); st_destroy_clear(st); st_destroy_bitmap(st); st_destroy_drawpix(st); st_destroy_drawtex(st); st_destroy_perfmon(st); st_destroy_pbo_upload(st); for (shader = 0; shader < ARRAY_SIZE(st->state.sampler_views); shader++) { for (i = 0; i < ARRAY_SIZE(st->state.sampler_views[0]); i++) { pipe_sampler_view_release(st->pipe, &st->state.sampler_views[shader][i]); } } if (st->default_texture) { st->ctx->Driver.DeleteTexture(st->ctx, st->default_texture); st->default_texture = NULL; } u_upload_destroy(st->uploader); if (st->indexbuf_uploader) { u_upload_destroy(st->indexbuf_uploader); } if (st->constbuf_uploader) { u_upload_destroy(st->constbuf_uploader); } cso_destroy_context(st->cso_context); free( st ); }
void st_destroy_context( struct st_context *st ) { struct pipe_context *pipe = st->pipe; struct cso_context *cso = st->cso_context; GLcontext *ctx = st->ctx; /* need to unbind and destroy CSO objects before anything else */ cso_release_all(st->cso_context); st_reference_fragprog(st, &st->fp, NULL); st_reference_vertprog(st, &st->vp, NULL); _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); _mesa_free_context_data(ctx); st_destroy_context_priv(st); cso_destroy_context(cso); pipe->destroy( pipe ); free(ctx); }
static void null_fragment_shader(struct pipe_context *ctx) { struct cso_context *cso; struct pipe_resource *cb; void *vs; struct pipe_rasterizer_state rs = {0}; struct pipe_query *query; union pipe_query_result qresult; cso = cso_create_context(ctx); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM); util_set_common_states_and_clear(cso, ctx, cb); /* No rasterization. */ rs.rasterizer_discard = 1; cso_set_rasterizer(cso, &rs); vs = util_set_passthrough_vertex_shader(cso, ctx, false); query = ctx->create_query(ctx, PIPE_QUERY_PRIMITIVES_GENERATED, 0); ctx->begin_query(ctx, query); util_draw_fullscreen_quad(cso); ctx->end_query(ctx, query); ctx->get_query_result(ctx, query, true, &qresult); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->destroy_query(ctx, query); pipe_resource_reference(&cb, NULL); /* Check PRIMITIVES_GENERATED. */ util_report_result(qresult.u64 == 2); }
static void test_sync_file_fences(struct pipe_context *ctx) { struct pipe_screen *screen = ctx->screen; bool pass = true; enum pipe_fd_type fd_type = PIPE_FD_TYPE_NATIVE_SYNC; if (!screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD)) return; struct cso_context *cso = cso_create_context(ctx, 0); struct pipe_resource *buf = pipe_buffer_create(screen, 0, PIPE_USAGE_DEFAULT, 1024 * 1024); struct pipe_resource *tex = util_create_texture2d(screen, 4096, 1024, PIPE_FORMAT_R8_UNORM, 0); struct pipe_fence_handle *buf_fence = NULL, *tex_fence = NULL; /* Run 2 clears, get fencess. */ uint32_t value = 0; ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value)); ctx->flush(ctx, &buf_fence, PIPE_FLUSH_FENCE_FD); struct pipe_box box; u_box_2d(0, 0, tex->width0, tex->height0, &box); ctx->clear_texture(ctx, tex, 0, &box, &value); ctx->flush(ctx, &tex_fence, PIPE_FLUSH_FENCE_FD); pass = pass && buf_fence && tex_fence; /* Export fences. */ int buf_fd = screen->fence_get_fd(screen, buf_fence); int tex_fd = screen->fence_get_fd(screen, tex_fence); pass = pass && buf_fd >= 0 && tex_fd >= 0; /* Merge fences. */ int merged_fd = sync_merge("test", buf_fd, tex_fd); pass = pass && merged_fd >= 0; /* (Re)import all fences. */ struct pipe_fence_handle *re_buf_fence = NULL, *re_tex_fence = NULL; struct pipe_fence_handle *merged_fence = NULL; ctx->create_fence_fd(ctx, &re_buf_fence, buf_fd, fd_type); ctx->create_fence_fd(ctx, &re_tex_fence, tex_fd, fd_type); ctx->create_fence_fd(ctx, &merged_fence, merged_fd, fd_type); pass = pass && re_buf_fence && re_tex_fence && merged_fence; /* Run another clear after waiting for everything. */ struct pipe_fence_handle *final_fence = NULL; ctx->fence_server_sync(ctx, merged_fence); value = 0xff; ctx->clear_buffer(ctx, buf, 0, buf->width0, &value, sizeof(value)); ctx->flush(ctx, &final_fence, PIPE_FLUSH_FENCE_FD); pass = pass && final_fence; /* Wait for the last fence. */ int final_fd = screen->fence_get_fd(screen, final_fence); pass = pass && final_fd >= 0; pass = pass && sync_wait(final_fd, -1) == 0; /* Check that all fences are signalled. */ pass = pass && sync_wait(buf_fd, 0) == 0; pass = pass && sync_wait(tex_fd, 0) == 0; pass = pass && sync_wait(merged_fd, 0) == 0; pass = pass && screen->fence_finish(screen, NULL, buf_fence, 0); pass = pass && screen->fence_finish(screen, NULL, tex_fence, 0); pass = pass && screen->fence_finish(screen, NULL, re_buf_fence, 0); pass = pass && screen->fence_finish(screen, NULL, re_tex_fence, 0); pass = pass && screen->fence_finish(screen, NULL, merged_fence, 0); pass = pass && screen->fence_finish(screen, NULL, final_fence, 0); /* Cleanup. */ #ifndef PIPE_OS_WINDOWS if (buf_fd >= 0) close(buf_fd); if (tex_fd >= 0) close(tex_fd); if (merged_fd >= 0) close(merged_fd); if (final_fd >= 0) close(final_fd); #endif screen->fence_reference(screen, &buf_fence, NULL); screen->fence_reference(screen, &tex_fence, NULL); screen->fence_reference(screen, &re_buf_fence, NULL); screen->fence_reference(screen, &re_tex_fence, NULL); screen->fence_reference(screen, &merged_fence, NULL); screen->fence_reference(screen, &final_fence, NULL); cso_destroy_context(cso); pipe_resource_reference(&buf, NULL); pipe_resource_reference(&tex, NULL); util_report_result(pass); }
static void test_texture_barrier(struct pipe_context *ctx, bool use_fbfetch, unsigned num_samples) { struct cso_context *cso; struct pipe_resource *cb; struct pipe_sampler_view *view = NULL; char name[256]; const char *text; assert(num_samples >= 1 && num_samples <= 8); util_snprintf(name, sizeof(name), "%s: %s, %u samples", __func__, use_fbfetch ? "FBFETCH" : "sampler", MAX2(num_samples, 1)); if (!ctx->screen->get_param(ctx->screen, PIPE_CAP_TEXTURE_BARRIER)) { util_report_result_helper(SKIP, name); return; } if (use_fbfetch && !ctx->screen->get_param(ctx->screen, PIPE_CAP_TGSI_FS_FBFETCH)) { util_report_result_helper(SKIP, name); return; } cso = cso_create_context(ctx, 0); cb = util_create_texture2d(ctx->screen, 256, 256, PIPE_FORMAT_R8G8B8A8_UNORM, num_samples); util_set_common_states_and_clear(cso, ctx, cb); /* Clear each sample to a different value. */ if (num_samples > 1) { void *fs = util_make_fragment_passthrough_shader(ctx, TGSI_SEMANTIC_GENERIC, TGSI_INTERPOLATE_LINEAR, TRUE); cso_set_fragment_shader_handle(cso, fs); /* Vertex shader. */ void *vs = util_set_passthrough_vertex_shader(cso, ctx, false); for (unsigned i = 0; i < num_samples / 2; i++) { float value; /* 2 consecutive samples should have the same color to test MSAA * compression properly. */ if (num_samples == 2) { value = 0.1; } else { /* The average value must be 0.1 */ static const float values[] = { 0.0, 0.2, 0.05, 0.15 }; value = values[i]; } ctx->set_sample_mask(ctx, 0x3 << (i * 2)); util_draw_fullscreen_quad_fill(cso, value, value, value, value); } ctx->set_sample_mask(ctx, ~0); cso_set_vertex_shader_handle(cso, NULL); cso_set_fragment_shader_handle(cso, NULL); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); } if (use_fbfetch) { /* Fragment shader. */ text = "FRAG\n" "DCL OUT[0], COLOR[0]\n" "DCL TEMP[0]\n" "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" "FBFETCH TEMP[0], OUT[0]\n" "ADD OUT[0], TEMP[0], IMM[0]\n" "END\n"; } else { struct pipe_sampler_view templ = {{0}}; templ.format = cb->format; templ.target = cb->target; templ.swizzle_r = PIPE_SWIZZLE_X; templ.swizzle_g = PIPE_SWIZZLE_Y; templ.swizzle_b = PIPE_SWIZZLE_Z; templ.swizzle_a = PIPE_SWIZZLE_W; view = ctx->create_sampler_view(ctx, cb, &templ); ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &view); /* Fragment shader. */ if (num_samples > 1) { text = "FRAG\n" "DCL SV[0], POSITION\n" "DCL SV[1], SAMPLEID\n" "DCL SAMP[0]\n" "DCL SVIEW[0], 2D_MSAA, FLOAT\n" "DCL OUT[0], COLOR[0]\n" "DCL TEMP[0]\n" "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" "F2I TEMP[0].xy, SV[0].xyyy\n" "MOV TEMP[0].w, SV[1].xxxx\n" "TXF TEMP[0], TEMP[0], SAMP[0], 2D_MSAA\n" "ADD OUT[0], TEMP[0], IMM[0]\n" "END\n"; } else { text = "FRAG\n" "DCL SV[0], POSITION\n" "DCL SAMP[0]\n" "DCL SVIEW[0], 2D, FLOAT\n" "DCL OUT[0], COLOR[0]\n" "DCL TEMP[0]\n" "IMM[0] FLT32 { 0.1, 0.2, 0.3, 0.4}\n" "IMM[1] INT32 { 0, 0, 0, 0}\n" "F2I TEMP[0].xy, SV[0].xyyy\n" "MOV TEMP[0].zw, IMM[1]\n" "TXF TEMP[0], TEMP[0], SAMP[0], 2D\n" "ADD OUT[0], TEMP[0], IMM[0]\n" "END\n"; } } struct tgsi_token tokens[1000]; struct pipe_shader_state state; if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) { assert(0); util_report_result_helper(FAIL, name); return; } pipe_shader_state_from_tgsi(&state, tokens); void *fs = ctx->create_fs_state(ctx, &state); cso_set_fragment_shader_handle(cso, fs); /* Vertex shader. */ void *vs = util_set_passthrough_vertex_shader(cso, ctx, false); if (num_samples > 1 && !use_fbfetch) ctx->set_min_samples(ctx, num_samples); for (int i = 0; i < 2; i++) { ctx->texture_barrier(ctx, use_fbfetch ? PIPE_TEXTURE_BARRIER_FRAMEBUFFER : PIPE_TEXTURE_BARRIER_SAMPLER); util_draw_fullscreen_quad(cso); } if (num_samples > 1 && !use_fbfetch) ctx->set_min_samples(ctx, 1); /* Probe pixels. * * For single sample: * result = 0.1 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.3, 0.5, 0.7, 0.9) * * For MSAA 4x: * sample0 = 0.0 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.2, 0.4, 0.6, 0.8) * sample1 = sample0 * sample2 = 0.2 (clear) + (0.1, 0.2, 0.3, 0.4) * 2 = (0.4, 0.6, 0.8, 1.0) * sample3 = sample2 * resolved = sum(sample[0:3]) / 4 = (0.3, 0.5, 0.7, 0.9) */ static const float expected[] = {0.3, 0.5, 0.7, 0.9}; bool pass = util_probe_rect_rgba(ctx, cb, 0, 0, cb->width0, cb->height0, expected); /* Cleanup. */ cso_destroy_context(cso); ctx->delete_vs_state(ctx, vs); ctx->delete_fs_state(ctx, fs); pipe_sampler_view_reference(&view, NULL); pipe_resource_reference(&cb, NULL); util_report_result_helper(pass, name); }