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); }
/** * 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); }
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); }