summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/Makefile1
-rw-r--r--src/gallium/auxiliary/SConscript2
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c665
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c17
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c17
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.h5
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c18
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c34
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_validate.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_conv.c59
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.c6
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr.h4
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c17
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c59
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c36
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c241
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c15
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h17
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c135
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c91
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h69
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_util.c7
-rw-r--r--src/gallium/auxiliary/translate/translate_cache.c4
-rw-r--r--src/gallium/auxiliary/util/dbghelp.h1265
-rw-r--r--src/gallium/auxiliary/util/u_blit.c9
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c128
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h16
-rw-r--r--src/gallium/auxiliary/util/u_debug.c80
-rw-r--r--src/gallium/auxiliary/util/u_debug.h37
-rw-r--r--src/gallium/auxiliary/util/u_debug_refcnt.c12
-rw-r--r--src/gallium/auxiliary/util/u_debug_symbol.c95
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c14
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.h5
-rw-r--r--src/gallium/auxiliary/util/u_dump_state.c1
-rw-r--r--src/gallium/auxiliary/util/u_format.h42
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c4
-rw-r--r--src/gallium/auxiliary/util/u_index_modify.c18
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h19
-rw-r--r--src/gallium/auxiliary/util/u_math.h14
-rw-r--r--src/gallium/auxiliary/util/u_resource.c2
-rw-r--r--src/gallium/auxiliary/util/u_tile.c81
-rw-r--r--src/gallium/auxiliary/util/u_tile.h24
-rw-r--r--src/gallium/auxiliary/util/u_transfer.c7
-rw-r--r--src/gallium/auxiliary/util/u_transfer.h12
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c13
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c601
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.h121
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c3
-rw-r--r--src/gallium/auxiliary/vl/vl_idct.c4
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c2
-rw-r--r--src/gallium/auxiliary/vl/vl_vertex_buffers.c6
64 files changed, 3542 insertions, 656 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 6cf1ddd43fe..e40f546929d 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -143,6 +143,7 @@ C_SOURCES = \
util/u_transfer.c \
util/u_resource.c \
util/u_upload_mgr.c \
+ util/u_vbuf_mgr.c \
vl/vl_bitstream_parser.c \
vl/vl_mpeg12_mc_renderer.c \
vl/vl_compositor.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index e6806d9a723..11024d41923 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -190,11 +190,11 @@ source = [
'util/u_tile.c',
'util/u_transfer.c',
'util/u_upload_mgr.c',
+ 'util/u_vbuf_mgr.c',
'vl/vl_bitstream_parser.c',
'vl/vl_mpeg12_mc_renderer.c',
'vl/vl_compositor.c',
'vl/vl_csc.c',
- 'target-helpers/wrap_screen.c',
]
if env['llvm']:
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 58b022d531d..fdd40fca126 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -47,41 +47,45 @@
#include "cso_cache/cso_hash.h"
#include "cso_context.h"
-struct cso_context {
- struct pipe_context *pipe;
- struct cso_cache *cache;
+/**
+ * Info related to samplers and sampler views.
+ * We have one of these for fragment samplers and another for vertex samplers.
+ */
+struct sampler_info
+{
struct {
void *samplers[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
-
- void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
- unsigned nr_vertex_samplers;
} hw;
void *samplers[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
- void *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
- unsigned nr_vertex_samplers;
-
- unsigned nr_samplers_saved;
void *samplers_saved[PIPE_MAX_SAMPLERS];
+ unsigned nr_samplers_saved;
+
+ struct pipe_sampler_view *views[PIPE_MAX_SAMPLERS];
+ unsigned nr_views;
+
+ struct pipe_sampler_view *views_saved[PIPE_MAX_SAMPLERS];
+ unsigned nr_views_saved;
+};
+
- unsigned nr_vertex_samplers_saved;
- void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];
- uint nr_fragment_sampler_views;
- struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+struct cso_context {
+ struct pipe_context *pipe;
+ struct cso_cache *cache;
- uint nr_vertex_sampler_views;
- struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+ struct sampler_info fragment_samplers;
+ struct sampler_info vertex_samplers;
- uint nr_fragment_sampler_views_saved;
- struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS];
+ uint nr_vertex_buffers;
+ struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
- uint nr_vertex_sampler_views_saved;
- struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS];
+ uint nr_vertex_buffers_saved;
+ struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS];
/** Current and saved state.
* The saved state is used as a 1-deep stack.
@@ -252,6 +256,8 @@ struct cso_context *cso_create_context( struct pipe_context *pipe )
if (ctx == NULL)
goto out;
+ assert(PIPE_MAX_SAMPLERS == PIPE_MAX_VERTEX_SAMPLERS);
+
ctx->cache = cso_cache_create();
if (ctx->cache == NULL)
goto out;
@@ -278,7 +284,8 @@ out:
void cso_release_all( struct cso_context *ctx )
{
unsigned i;
-
+ struct sampler_info *info;
+
if (ctx->pipe) {
ctx->pipe->bind_blend_state( ctx->pipe, NULL );
ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL );
@@ -294,19 +301,30 @@ void cso_release_all( struct cso_context *ctx )
ctx->pipe->set_vertex_sampler_views(ctx->pipe, 0, NULL);
}
+ /* free fragment samplers, views */
+ info = &ctx->fragment_samplers;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
- pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL);
+ pipe_sampler_view_reference(&info->views[i], NULL);
+ pipe_sampler_view_reference(&info->views_saved[i], NULL);
}
- for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL);
- pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL);
+ /* free vertex samplers, views */
+ info = &ctx->vertex_samplers;
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ pipe_sampler_view_reference(&info->views[i], NULL);
+ pipe_sampler_view_reference(&info->views_saved[i], NULL);
}
util_unreference_framebuffer_state(&ctx->fb);
util_unreference_framebuffer_state(&ctx->fb_saved);
+ util_copy_vertex_buffers(ctx->vertex_buffers,
+ &ctx->nr_vertex_buffers,
+ NULL, 0);
+ util_copy_vertex_buffers(ctx->vertex_buffers_saved,
+ &ctx->nr_vertex_buffers_saved,
+ NULL, 0);
+
if (ctx->cache) {
cso_cache_delete( ctx->cache );
ctx->cache = NULL;
@@ -395,233 +413,6 @@ void cso_restore_blend(struct cso_context *ctx)
-enum pipe_error cso_single_sampler(struct cso_context *ctx,
- unsigned idx,
- const struct pipe_sampler_state *templ)
-{
- void *handle = NULL;
-
- if (templ != NULL) {
- unsigned key_size = sizeof(struct pipe_sampler_state);
- unsigned hash_key = cso_construct_key((void*)templ, key_size);
- struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
- hash_key, CSO_SAMPLER,
- (void*)templ, key_size);
-
- if (cso_hash_iter_is_null(iter)) {
- struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
- if (!cso)
- return PIPE_ERROR_OUT_OF_MEMORY;
-
- memcpy(&cso->state, templ, sizeof(*templ));
- cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
- cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
- cso->context = ctx->pipe;
-
- iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
- if (cso_hash_iter_is_null(iter)) {
- FREE(cso);
- return PIPE_ERROR_OUT_OF_MEMORY;
- }
-
- handle = cso->data;
- }
- else {
- handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data;
- }
- }
-
- ctx->samplers[idx] = handle;
- return PIPE_OK;
-}
-
-enum pipe_error
-cso_single_vertex_sampler(struct cso_context *ctx,
- unsigned idx,
- const struct pipe_sampler_state *templ)
-{
- void *handle = NULL;
-
- if (templ != NULL) {
- unsigned key_size = sizeof(struct pipe_sampler_state);
- unsigned hash_key = cso_construct_key((void*)templ, key_size);
- struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
- hash_key, CSO_SAMPLER,
- (void*)templ, key_size);
-
- if (cso_hash_iter_is_null(iter)) {
- struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
- if (!cso)
- return PIPE_ERROR_OUT_OF_MEMORY;
-
- memcpy(&cso->state, templ, sizeof(*templ));
- cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
- cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
- cso->context = ctx->pipe;
-
- iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
- if (cso_hash_iter_is_null(iter)) {
- FREE(cso);
- return PIPE_ERROR_OUT_OF_MEMORY;
- }
-
- handle = cso->data;
- }
- else {
- handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data;
- }
- }
-
- ctx->vertex_samplers[idx] = handle;
- return PIPE_OK;
-}
-
-void cso_single_sampler_done( struct cso_context *ctx )
-{
- unsigned i;
-
- /* find highest non-null sampler */
- for (i = PIPE_MAX_SAMPLERS; i > 0; i--) {
- if (ctx->samplers[i - 1] != NULL)
- break;
- }
-
- ctx->nr_samplers = i;
-
- if (ctx->hw.nr_samplers != ctx->nr_samplers ||
- memcmp(ctx->hw.samplers,
- ctx->samplers,
- ctx->nr_samplers * sizeof(void *)) != 0)
- {
- memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *));
- ctx->hw.nr_samplers = ctx->nr_samplers;
-
- ctx->pipe->bind_fragment_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers);
- }
-}
-
-void
-cso_single_vertex_sampler_done(struct cso_context *ctx)
-{
- unsigned i;
-
- /* find highest non-null sampler */
- for (i = PIPE_MAX_VERTEX_SAMPLERS; i > 0; i--) {
- if (ctx->vertex_samplers[i - 1] != NULL)
- break;
- }
-
- ctx->nr_vertex_samplers = i;
-
- if (ctx->hw.nr_vertex_samplers != ctx->nr_vertex_samplers ||
- memcmp(ctx->hw.vertex_samplers,
- ctx->vertex_samplers,
- ctx->nr_vertex_samplers * sizeof(void *)) != 0)
- {
- memcpy(ctx->hw.vertex_samplers,
- ctx->vertex_samplers,
- ctx->nr_vertex_samplers * sizeof(void *));
- ctx->hw.nr_vertex_samplers = ctx->nr_vertex_samplers;
-
- ctx->pipe->bind_vertex_sampler_states(ctx->pipe,
- ctx->nr_vertex_samplers,
- ctx->vertex_samplers);
- }
-}
-
-/*
- * If the function encouters any errors it will return the
- * last one. Done to always try to set as many samplers
- * as possible.
- */
-enum pipe_error cso_set_samplers( struct cso_context *ctx,
- unsigned nr,
- const struct pipe_sampler_state **templates )
-{
- unsigned i;
- enum pipe_error temp, error = PIPE_OK;
-
- /* TODO: fastpath
- */
-
- for (i = 0; i < nr; i++) {
- temp = cso_single_sampler( ctx, i, templates[i] );
- if (temp != PIPE_OK)
- error = temp;
- }
-
- for ( ; i < ctx->nr_samplers; i++) {
- temp = cso_single_sampler( ctx, i, NULL );
- if (temp != PIPE_OK)
- error = temp;
- }
-
- cso_single_sampler_done( ctx );
-
- return error;
-}
-
-void cso_save_samplers(struct cso_context *ctx)
-{
- ctx->nr_samplers_saved = ctx->nr_samplers;
- memcpy(ctx->samplers_saved, ctx->samplers, sizeof(ctx->samplers));
-}
-
-void cso_restore_samplers(struct cso_context *ctx)
-{
- ctx->nr_samplers = ctx->nr_samplers_saved;
- memcpy(ctx->samplers, ctx->samplers_saved, sizeof(ctx->samplers));
- cso_single_sampler_done( ctx );
-}
-
-/*
- * If the function encouters any errors it will return the
- * last one. Done to always try to set as many samplers
- * as possible.
- */
-enum pipe_error cso_set_vertex_samplers(struct cso_context *ctx,
- unsigned nr,
- const struct pipe_sampler_state **templates)
-{
- unsigned i;
- enum pipe_error temp, error = PIPE_OK;
-
- /* TODO: fastpath
- */
-
- for (i = 0; i < nr; i++) {
- temp = cso_single_vertex_sampler( ctx, i, templates[i] );
- if (temp != PIPE_OK)
- error = temp;
- }
-
- for ( ; i < ctx->nr_samplers; i++) {
- temp = cso_single_vertex_sampler( ctx, i, NULL );
- if (temp != PIPE_OK)
- error = temp;
- }
-
- cso_single_vertex_sampler_done( ctx );
-
- return error;
-}
-
-void
-cso_save_vertex_samplers(struct cso_context *ctx)
-{
- ctx->nr_vertex_samplers_saved = ctx->nr_vertex_samplers;
- memcpy(ctx->vertex_samplers_saved, ctx->vertex_samplers, sizeof(ctx->vertex_samplers));
-}
-
-void
-cso_restore_vertex_samplers(struct cso_context *ctx)
-{
- ctx->nr_vertex_samplers = ctx->nr_vertex_samplers_saved;
- memcpy(ctx->vertex_samplers, ctx->vertex_samplers_saved, sizeof(ctx->vertex_samplers));
- cso_single_vertex_sampler_done(ctx);
-}
-
-
enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{
@@ -1143,121 +934,361 @@ void cso_restore_vertex_elements(struct cso_context *ctx)
ctx->velements_saved = NULL;
}
-/* fragment sampler view state */
+/* vertex buffers */
-void
-cso_set_fragment_sampler_views(struct cso_context *cso,
- uint count,
- struct pipe_sampler_view **views)
+void cso_set_vertex_buffers(struct cso_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
- uint i;
-
- for (i = 0; i < count; i++) {
- pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]);
+ if (count != ctx->nr_vertex_buffers ||
+ memcmp(buffers, ctx->vertex_buffers,
+ sizeof(struct pipe_vertex_buffer) * count) != 0) {
+ util_copy_vertex_buffers(ctx->vertex_buffers, &ctx->nr_vertex_buffers,
+ buffers, count);
+ ctx->pipe->set_vertex_buffers(ctx->pipe, count, buffers);
}
- for (; i < cso->nr_fragment_sampler_views; i++) {
- pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+}
+
+void cso_save_vertex_buffers(struct cso_context *ctx)
+{
+ util_copy_vertex_buffers(ctx->vertex_buffers_saved,
+ &ctx->nr_vertex_buffers_saved,
+ ctx->vertex_buffers,
+ ctx->nr_vertex_buffers);
+}
+
+void cso_restore_vertex_buffers(struct cso_context *ctx)
+{
+ util_copy_vertex_buffers(ctx->vertex_buffers,
+ &ctx->nr_vertex_buffers,
+ ctx->vertex_buffers_saved,
+ ctx->nr_vertex_buffers_saved);
+ ctx->pipe->set_vertex_buffers(ctx->pipe, ctx->nr_vertex_buffers,
+ ctx->vertex_buffers);
+}
+
+
+/**************** fragment/vertex sampler view state *************************/
+
+static enum pipe_error
+single_sampler(struct cso_context *ctx,
+ struct sampler_info *info,
+ unsigned idx,
+ const struct pipe_sampler_state *templ)
+{
+ void *handle = NULL;
+
+ if (templ != NULL) {
+ unsigned key_size = sizeof(struct pipe_sampler_state);
+ unsigned hash_key = cso_construct_key((void*)templ, key_size);
+ struct cso_hash_iter iter =
+ cso_find_state_template(ctx->cache,
+ hash_key, CSO_SAMPLER,
+ (void *) templ, key_size);
+
+ if (cso_hash_iter_is_null(iter)) {
+ struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
+ if (!cso)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ memcpy(&cso->state, templ, sizeof(*templ));
+ cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state);
+ cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state;
+ cso->context = ctx->pipe;
+
+ iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso);
+ if (cso_hash_iter_is_null(iter)) {
+ FREE(cso);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle = cso->data;
+ }
+ else {
+ handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data;
+ }
}
- cso->pipe->set_fragment_sampler_views(cso->pipe,
- MAX2(count, cso->nr_fragment_sampler_views),
- cso->fragment_sampler_views);
+ info->samplers[idx] = handle;
- cso->nr_fragment_sampler_views = count;
+ return PIPE_OK;
}
-void
-cso_save_fragment_sampler_views(struct cso_context *cso)
+enum pipe_error
+cso_single_sampler(struct cso_context *ctx,
+ unsigned idx,
+ const struct pipe_sampler_state *templ)
{
- uint i;
+ return single_sampler(ctx, &ctx->fragment_samplers, idx, templ);
+}
+
+enum pipe_error
+cso_single_vertex_sampler(struct cso_context *ctx,
+ unsigned idx,
+ const struct pipe_sampler_state *templ)
+{
+ return single_sampler(ctx, &ctx->vertex_samplers, idx, templ);
+}
+
- cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views;
- for (i = 0; i < cso->nr_fragment_sampler_views; i++) {
- assert(!cso->fragment_sampler_views_saved[i]);
+static void
+single_sampler_done(struct cso_context *ctx,
+ struct sampler_info *info)
+{
+ unsigned i;
- pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i],
- cso->fragment_sampler_views[i]);
+ /* find highest non-null sampler */
+ for (i = PIPE_MAX_SAMPLERS; i > 0; i--) {
+ if (info->samplers[i - 1] != NULL)
+ break;
+ }
+
+ info->nr_samplers = i;
+
+ if (info->hw.nr_samplers != info->nr_samplers ||
+ memcmp(info->hw.samplers,
+ info->samplers,
+ info->nr_samplers * sizeof(void *)) != 0)
+ {
+ memcpy(info->hw.samplers,
+ info->samplers,
+ info->nr_samplers * sizeof(void *));
+ info->hw.nr_samplers = info->nr_samplers;
+
+ if (info == &ctx->fragment_samplers) {
+ ctx->pipe->bind_fragment_sampler_states(ctx->pipe,
+ info->nr_samplers,
+ info->samplers);
+ }
+ else if (info == &ctx->vertex_samplers) {
+ ctx->pipe->bind_vertex_sampler_states(ctx->pipe,
+ info->nr_samplers,
+ info->samplers);
+ }
+ else {
+ assert(0);
+ }
}
}
void
-cso_restore_fragment_sampler_views(struct cso_context *cso)
+cso_single_sampler_done( struct cso_context *ctx )
{
- uint i;
+ single_sampler_done(ctx, &ctx->fragment_samplers);
+}
+
+void
+cso_single_vertex_sampler_done(struct cso_context *ctx)
+{
+ single_sampler_done(ctx, &ctx->vertex_samplers);
+}
- for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) {
- pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]);
- pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL);
+
+/*
+ * If the function encouters any errors it will return the
+ * last one. Done to always try to set as many samplers
+ * as possible.
+ */
+static enum pipe_error
+set_samplers(struct cso_context *ctx,
+ struct sampler_info *info,
+ unsigned nr,
+ const struct pipe_sampler_state **templates)
+{
+ unsigned i;
+ enum pipe_error temp, error = PIPE_OK;
+
+ /* TODO: fastpath
+ */
+
+ for (i = 0; i < nr; i++) {
+ temp = single_sampler(ctx, info, i, templates[i]);
+ if (temp != PIPE_OK)
+ error = temp;
}
- for (; i < cso->nr_fragment_sampler_views; i++) {
- pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+
+ for ( ; i < info->nr_samplers; i++) {
+ temp = single_sampler(ctx, info, i, NULL);
+ if (temp != PIPE_OK)
+ error = temp;
}
- cso->pipe->set_fragment_sampler_views(cso->pipe,
- MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved),
- cso->fragment_sampler_views);
+ single_sampler_done(ctx, info);
+
+ return error;
+}
+
+enum pipe_error
+cso_set_samplers(struct cso_context *ctx,
+ unsigned nr,
+ const struct pipe_sampler_state **templates)
+{
+ return set_samplers(ctx, &ctx->fragment_samplers, nr, templates);
+}
- cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved;
- cso->nr_fragment_sampler_views_saved = 0;
+enum pipe_error
+cso_set_vertex_samplers(struct cso_context *ctx,
+ unsigned nr,
+ const struct pipe_sampler_state **templates)
+{
+ return set_samplers(ctx, &ctx->vertex_samplers, nr, templates);
}
-/* vertex sampler view state */
+
+static void
+save_samplers(struct cso_context *ctx, struct sampler_info *info)
+{
+ info->nr_samplers_saved = info->nr_samplers;
+ memcpy(info->samplers_saved, info->samplers, sizeof(info->samplers));
+}
void
-cso_set_vertex_sampler_views(struct cso_context *cso,
- uint count,
- struct pipe_sampler_view **views)
+cso_save_samplers(struct cso_context *ctx)
+{
+ save_samplers(ctx, &ctx->fragment_samplers);
+}
+
+void
+cso_save_vertex_samplers(struct cso_context *ctx)
+{
+ save_samplers(ctx, &ctx->vertex_samplers);
+}
+
+
+
+static void
+restore_samplers(struct cso_context *ctx, struct sampler_info *info)
+{
+ info->nr_samplers = info->nr_samplers_saved;
+ memcpy(info->samplers, info->samplers_saved, sizeof(info->samplers));
+ single_sampler_done(ctx, info);
+}
+
+void
+cso_restore_samplers(struct cso_context *ctx)
+{
+ restore_samplers(ctx, &ctx->fragment_samplers);
+}
+
+void
+cso_restore_vertex_samplers(struct cso_context *ctx)
+{
+ restore_samplers(ctx, &ctx->vertex_samplers);
+}
+
+
+
+static void
+set_sampler_views(struct cso_context *ctx,
+ struct sampler_info *info,
+ void (*set_views)(struct pipe_context *,
+ unsigned num_views,
+ struct pipe_sampler_view **),
+ uint count,
+ struct pipe_sampler_view **views)
{
uint i;
+ /* reference new views */
for (i = 0; i < count; i++) {
- pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]);
+ pipe_sampler_view_reference(&info->views[i], views[i]);
}
- for (; i < cso->nr_vertex_sampler_views; i++) {
- pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+ /* unref extra old views, if any */
+ for (; i < info->nr_views; i++) {
+ pipe_sampler_view_reference(&info->views[i], NULL);
}
- cso->pipe->set_vertex_sampler_views(cso->pipe,
- MAX2(count, cso->nr_vertex_sampler_views),
- cso->vertex_sampler_views);
+ info->nr_views = count;
- cso->nr_vertex_sampler_views = count;
+ /* bind the new sampler views */
+ set_views(ctx->pipe, count, info->views);
}
void
-cso_save_vertex_sampler_views(struct cso_context *cso)
+cso_set_fragment_sampler_views(struct cso_context *ctx,
+ uint count,
+ struct pipe_sampler_view **views)
{
- uint i;
+ set_sampler_views(ctx, &ctx->fragment_samplers,
+ ctx->pipe->set_fragment_sampler_views,
+ count, views);
+}
- cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views;
+void
+cso_set_vertex_sampler_views(struct cso_context *ctx,
+ uint count,
+ struct pipe_sampler_view **views)
+{
+ set_sampler_views(ctx, &ctx->vertex_samplers,
+ ctx->pipe->set_vertex_sampler_views,
+ count, views);
+}
- for (i = 0; i < cso->nr_vertex_sampler_views; i++) {
- assert(!cso->vertex_sampler_views_saved[i]);
- pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i],
- cso->vertex_sampler_views[i]);
+
+static void
+save_sampler_views(struct cso_context *ctx,
+ struct sampler_info *info)
+{
+ uint i;
+
+ info->nr_views_saved = info->nr_views;
+
+ for (i = 0; i < info->nr_views; i++) {
+ assert(!info->views_saved[i]);
+ pipe_sampler_view_reference(&info->views_saved[i], info->views[i]);
}
}
void
-cso_restore_vertex_sampler_views(struct cso_context *cso)
+cso_save_fragment_sampler_views(struct cso_context *ctx)
+{
+ save_sampler_views(ctx, &ctx->fragment_samplers);
+}
+
+void
+cso_save_vertex_sampler_views(struct cso_context *ctx)
+{
+ save_sampler_views(ctx, &ctx->vertex_samplers);
+}
+
+
+static void
+restore_sampler_views(struct cso_context *ctx,
+ struct sampler_info *info,
+ void (*set_views)(struct pipe_context *,
+ unsigned num_views,
+ struct pipe_sampler_view **))
{
uint i;
- for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) {
- pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]);
- pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL);
+ for (i = 0; i < info->nr_views_saved; i++) {
+ pipe_sampler_view_reference(&info->views[i], info->views_saved[i]);
+ pipe_sampler_view_reference(&info->views_saved[i], NULL);
}
- for (; i < cso->nr_vertex_sampler_views; i++) {
- pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+ for (; i < info->nr_views; i++) {
+ pipe_sampler_view_reference(&info->views[i], NULL);
}
- cso->pipe->set_vertex_sampler_views(cso->pipe,
- MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved),
- cso->vertex_sampler_views);
+ /* bind the old/saved sampler views */
+ set_views(ctx->pipe, info->nr_views_saved, info->views);
+
+ info->nr_views = info->nr_views_saved;
+ info->nr_views_saved = 0;
+}
+
+void
+cso_restore_fragment_sampler_views(struct cso_context *ctx)
+{
+ restore_sampler_views(ctx, &ctx->fragment_samplers,
+ ctx->pipe->set_fragment_sampler_views);
+}
- cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved;
- cso->nr_vertex_sampler_views_saved = 0;
+void
+cso_restore_vertex_sampler_views(struct cso_context *ctx)
+{
+ restore_sampler_views(ctx, &ctx->vertex_samplers,
+ ctx->pipe->set_vertex_sampler_views);
}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index f0b07f73765..00edc9f8dd4 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -110,6 +110,13 @@ void cso_save_vertex_elements(struct cso_context *ctx);
void cso_restore_vertex_elements(struct cso_context *ctx);
+void cso_set_vertex_buffers(struct cso_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers);
+void cso_save_vertex_buffers(struct cso_context *ctx);
+void cso_restore_vertex_buffers(struct cso_context *ctx);
+
+
/* These aren't really sensible -- most of the time the api provides
* object semantics for shaders anyway, and the cases where it doesn't
* (eg mesa's internall-generated texenv programs), it will be up to
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index e045313b94f..95d96719873 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -88,8 +88,14 @@ draw_create_gallivm(struct pipe_context *pipe, struct gallivm_state *gallivm)
goto fail;
#if HAVE_LLVM
- if (draw_get_option_use_llvm() && gallivm) {
- draw->llvm = draw_llvm_create(draw, gallivm);
+ if (draw_get_option_use_llvm()) {
+ if (!gallivm) {
+ gallivm = gallivm_create();
+ draw->own_gallivm = gallivm;
+ }
+
+ if (gallivm)
+ draw->llvm = draw_llvm_create(draw, gallivm);
}
#endif
@@ -180,8 +186,11 @@ void draw_destroy( struct draw_context *draw )
draw_vs_destroy( draw );
draw_gs_destroy( draw );
#ifdef HAVE_LLVM
- if(draw->llvm)
+ if (draw->llvm)
draw_llvm_destroy( draw->llvm );
+
+ if (draw->own_gallivm)
+ gallivm_destroy(draw->own_gallivm);
#endif
FREE( draw );
@@ -401,7 +410,7 @@ void
draw_wide_line_threshold(struct draw_context *draw, float threshold)
{
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
- draw->pipeline.wide_line_threshold = threshold;
+ draw->pipeline.wide_line_threshold = roundf(threshold);
}
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 0c51aa85b37..a5217c1d4ec 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -214,13 +214,12 @@ static LLVMTypeRef
create_jit_vertex_buffer_type(struct gallivm_state *gallivm)
{
LLVMTargetDataRef target = gallivm->target;
- LLVMTypeRef elem_types[4];
+ LLVMTypeRef elem_types[3];
LLVMTypeRef vb_type;
elem_types[0] =
- elem_types[1] =
- elem_types[2] = LLVMInt32TypeInContext(gallivm->context);
- elem_types[3] = LLVMPointerType(LLVMOpaqueTypeInContext(gallivm->context), 0); /* vs_constants */
+ elem_types[1] = LLVMInt32TypeInContext(gallivm->context);
+ elem_types[2] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
vb_type = LLVMStructTypeInContext(gallivm->context, elem_types,
Elements(elem_types), 0);
@@ -229,10 +228,8 @@ create_jit_vertex_buffer_type(struct gallivm_state *gallivm)
LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride,
target, vb_type, 0);
- LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, max_index,
- target, vb_type, 1);
LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer_offset,
- target, vb_type, 2);
+ target, vb_type, 1);
LP_CHECK_STRUCT_SIZE(struct pipe_vertex_buffer, target, vb_type);
@@ -513,9 +510,7 @@ generate_fetch(struct gallivm_state *gallivm,
LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr,
&indices, 1, "");
LLVMValueRef vb_stride = draw_jit_vbuffer_stride(gallivm, vbuf);
- LLVMValueRef vb_max_index = draw_jit_vbuffer_max_index(gallivm, vbuf);
LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, vbuf);
- LLVMValueRef cond;
LLVMValueRef stride;
if (velem->instance_divisor) {
@@ -525,10 +520,6 @@ generate_fetch(struct gallivm_state *gallivm,
"instance_divisor");
}
- /* limit index to min(index, vb_max_index) */
- cond = LLVMBuildICmp(builder, LLVMIntULE, index, vb_max_index, "");
- index = LLVMBuildSelect(builder, cond, index, vb_max_index, "");
-
stride = LLVMBuildMul(builder, vb_stride, index, "");
vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer");
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
index 9f038f1f04d..e8623e7bcdc 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -133,11 +133,8 @@ struct draw_jit_context
#define draw_jit_vbuffer_stride(_gallivm, _ptr) \
lp_build_struct_get(_gallivm, _ptr, 0, "stride")
-#define draw_jit_vbuffer_max_index(_gallivm, _ptr) \
- lp_build_struct_get(_gallivm, _ptr, 1, "max_index")
-
#define draw_jit_vbuffer_offset(_gallivm, _ptr) \
- lp_build_struct_get(_gallivm, _ptr, 2, "buffer_offset")
+ lp_build_struct_get(_gallivm, _ptr, 1, "buffer_offset")
typedef int
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 6206197dae9..f1b0171f520 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -64,8 +64,8 @@ boolean draw_pipeline_init( struct draw_context *draw )
return FALSE;
/* these defaults are oriented toward the needs of softpipe */
- draw->pipeline.wide_point_threshold = 1000000.0; /* infinity */
- draw->pipeline.wide_line_threshold = 1.0;
+ draw->pipeline.wide_point_threshold = 1000000.0f; /* infinity */
+ draw->pipeline.wide_line_threshold = 1.0f;
draw->pipeline.wide_point_sprites = FALSE;
draw->pipeline.line_stipple = TRUE;
draw->pipeline.point_sprite = TRUE;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 0851b9acc0d..32af29ae144 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -55,9 +55,16 @@
/**
+ * Size for the alpha texture used for antialiasing
+ */
+#define TEXTURE_SIZE_LOG2 5 /* 32 x 32 */
+
+/**
* Max texture level for the alpha texture used for antialiasing
+ *
+ * Don't use the 1x1 and 2x2 mipmap levels.
*/
-#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */
+#define MAX_TEXTURE_LEVEL (TEXTURE_SIZE_LOG2 - 2)
/**
@@ -403,8 +410,8 @@ aaline_create_texture(struct aaline_stage *aaline)
texTemp.target = PIPE_TEXTURE_2D;
texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */
texTemp.last_level = MAX_TEXTURE_LEVEL;
- texTemp.width0 = 1 << MAX_TEXTURE_LEVEL;
- texTemp.height0 = 1 << MAX_TEXTURE_LEVEL;
+ texTemp.width0 = 1 << TEXTURE_SIZE_LOG2;
+ texTemp.height0 = 1 << TEXTURE_SIZE_LOG2;
texTemp.depth0 = 1;
texTemp.array_size = 1;
texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -461,7 +468,7 @@ aaline_create_texture(struct aaline_stage *aaline)
d = 200; /* tuneable */
}
else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) {
- d = 0;
+ d = 35; /* edge texel */
}
else {
d = 255;
@@ -498,8 +505,7 @@ aaline_create_sampler(struct aaline_stage *aaline)
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
sampler.normalized_coords = 1;
sampler.min_lod = 0.0f;
- /* avoid using the 1x1 and 2x2 mipmap levels */
- sampler.max_lod = MAX_TEXTURE_LEVEL - 2;
+ sampler.max_lod = MAX_TEXTURE_LEVEL;
aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
if (aaline->sampler_cso == NULL)
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index f5515c1df76..ea62c9739fd 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -27,8 +27,9 @@
/**
* Polygon stipple stage: implement polygon stipple with texture map and
- * fragment program. The fragment program samples the texture and does
- * a fragment kill for the stipple-failing fragments.
+ * fragment program. The fragment program samples the texture using the
+ * fragment window coordinate register and does a fragment kill for the
+ * stipple-failing fragments.
*
* Authors: Brian Paul
*/
@@ -114,7 +115,8 @@ struct pstip_stage
/**
* Subclass of tgsi_transform_context, used for transforming the
- * user's fragment shader to add the special AA instructions.
+ * user's fragment shader to add the extra texture sample and fragment kill
+ * instructions.
*/
struct pstip_transform_context {
struct tgsi_transform_context base;
@@ -658,16 +660,16 @@ pstip_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *fs)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
- struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader);
+ struct pstip_fragment_shader *pstipfs = CALLOC_STRUCT(pstip_fragment_shader);
- if (aafs) {
- aafs->state = *fs;
+ if (pstipfs) {
+ pstipfs->state = *fs;
/* pass-through */
- aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs);
+ pstipfs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs);
}
- return aafs;
+ return pstipfs;
}
@@ -675,12 +677,12 @@ static void
pstip_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
- struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
+ struct pstip_fragment_shader *pstipfs = (struct pstip_fragment_shader *) fs;
/* save current */
- pstip->fs = aafs;
+ pstip->fs = pstipfs;
/* pass-through */
pstip->driver_bind_fs_state(pstip->pipe,
- (aafs ? aafs->driver_fs : NULL));
+ (pstipfs ? pstipfs->driver_fs : NULL));
}
@@ -688,14 +690,14 @@ static void
pstip_delete_fs_state(struct pipe_context *pipe, void *fs)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
- struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
+ struct pstip_fragment_shader *pstipfs = (struct pstip_fragment_shader *) fs;
/* pass-through */
- pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs);
+ pstip->driver_delete_fs_state(pstip->pipe, pstipfs->driver_fs);
- if (aafs->pstip_fs)
- pstip->driver_delete_fs_state(pstip->pipe, aafs->pstip_fs);
+ if (pstipfs->pstip_fs)
+ pstip->driver_delete_fs_state(pstip->pipe, pstipfs->pstip_fs);
- FREE(aafs);
+ FREE(pstipfs);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c
index c575a8ac7ca..27afba5af3d 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_validate.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c
@@ -29,6 +29,7 @@
*/
#include "util/u_memory.h"
+#include "util/u_math.h"
#include "pipe/p_defines.h"
#include "draw_private.h"
#include "draw_pipe.h"
@@ -86,7 +87,7 @@ draw_need_pipeline(const struct draw_context *draw,
return TRUE;
/* wide lines */
- if (rasterizer->line_width > draw->pipeline.wide_line_threshold)
+ if (roundf(rasterizer->line_width) > draw->pipeline.wide_line_threshold)
return TRUE;
/* AA lines */
@@ -169,7 +170,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
stage->next = next;
/* drawing wide lines? */
- wide_lines = (rast->line_width > draw->pipeline.wide_line_threshold
+ wide_lines = (roundf(rast->line_width) > draw->pipeline.wide_line_threshold
&& !rast->line_smooth);
/* drawing large/sprite points (but not AA points)? */
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 06ed4d60ef2..db2e3c5410d 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -286,6 +286,7 @@ struct draw_context
#ifdef HAVE_LLVM
struct draw_llvm *llvm;
+ struct gallivm_state *own_gallivm;
#endif
struct pipe_sampler_view *sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 4078b2a07d0..c3d7e871f7a 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -459,10 +459,9 @@ draw_vbo(struct draw_context *draw,
}
debug_printf("Buffers:\n");
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
- debug_printf(" %u: stride=%u maxindex=%u offset=%u ptr=%p\n",
+ debug_printf(" %u: stride=%u offset=%u ptr=%p\n",
i,
draw->pt.vertex_buffer[i].stride,
- draw->pt.vertex_buffer[i].max_index,
draw->pt.vertex_buffer[i].buffer_offset,
draw->pt.user.vbuffer[i]);
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index ae12ee24bdc..4fa3b265e10 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -139,7 +139,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
((char *)draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.vertex_buffer[i].max_index);
+ draw->pt.user.max_index);
}
translate->run_elts( translate,
@@ -166,7 +166,7 @@ void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
((char *)draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.vertex_buffer[i].max_index);
+ draw->pt.user.max_index);
}
translate->run( translate,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index e706b7796f8..51043102a61 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -186,7 +186,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
((char *)draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.vertex_buffer[i].max_index);
+ draw->pt.user.max_index);
}
*max_vertices = (draw->render->max_vertex_buffer_bytes /
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index c98fb3d5205..1e926fb028e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -169,7 +169,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
((const ubyte *) draw->pt.user.vbuffer[i] +
draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride,
- draw->pt.vertex_buffer[i].max_index );
+ draw->pt.user.max_index );
}
*max_vertices = (draw->render->max_vertex_buffer_bytes /
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
index c43ee8ac638..c261d761161 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
@@ -231,44 +231,53 @@ lp_build_unsigned_norm_to_float(struct gallivm_state *gallivm,
assert(dst_type.floating);
- /* Special-case int8->float, though most cases could be handled
- * this way:
- */
- if (src_width == 8) {
- scale = 1.0/255.0;
+ mantissa = lp_mantissa(dst_type);
+
+ if (src_width <= (mantissa + 1)) {
+ /*
+ * The source width matches fits what can be represented in floating
+ * point (i.e., mantissa + 1 bits). So do a straight multiplication
+ * followed by casting. No further rounding is necessary.
+ */
+
+ scale = 1.0/(double)((1ULL << src_width) - 1);
res = LLVMBuildSIToFP(builder, src, vec_type, "");
res = LLVMBuildFMul(builder, res,
lp_build_const_vec(gallivm, dst_type, scale), "");
return res;
}
+ else {
+ /*
+ * The source width exceeds what can be represented in floating
+ * point. So truncate the incoming values.
+ */
- mantissa = lp_mantissa(dst_type);
-
- n = MIN2(mantissa, src_width);
+ n = MIN2(mantissa, src_width);
- ubound = ((unsigned long long)1 << n);
- mask = ubound - 1;
- scale = (double)ubound/mask;
- bias = (double)((unsigned long long)1 << (mantissa - n));
+ ubound = ((unsigned long long)1 << n);
+ mask = ubound - 1;
+ scale = (double)ubound/mask;
+ bias = (double)((unsigned long long)1 << (mantissa - n));
- res = src;
+ res = src;
- if(src_width > mantissa) {
- int shift = src_width - mantissa;
- res = LLVMBuildLShr(builder, res,
- lp_build_const_int_vec(gallivm, dst_type, shift), "");
- }
+ if (src_width > mantissa) {
+ int shift = src_width - mantissa;
+ res = LLVMBuildLShr(builder, res,
+ lp_build_const_int_vec(gallivm, dst_type, shift), "");
+ }
- bias_ = lp_build_const_vec(gallivm, dst_type, bias);
+ bias_ = lp_build_const_vec(gallivm, dst_type, bias);
- res = LLVMBuildOr(builder,
- res,
- LLVMBuildBitCast(builder, bias_, int_vec_type, ""), "");
+ res = LLVMBuildOr(builder,
+ res,
+ LLVMBuildBitCast(builder, bias_, int_vec_type, ""), "");
- res = LLVMBuildBitCast(builder, res, vec_type, "");
+ res = LLVMBuildBitCast(builder, res, vec_type, "");
- res = LLVMBuildFSub(builder, res, bias_, "");
- res = LLVMBuildFMul(builder, res, lp_build_const_vec(gallivm, dst_type, scale), "");
+ res = LLVMBuildFSub(builder, res, bias_, "");
+ res = LLVMBuildFMul(builder, res, lp_build_const_vec(gallivm, dst_type, scale), "");
+ }
return res;
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index 7504cb5cf2f..45addee8fab 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -222,11 +222,12 @@ free_gallivm_state(struct gallivm_state *gallivm)
static boolean
init_gallivm_state(struct gallivm_state *gallivm)
{
- assert(gallivm_initialized);
assert(!gallivm->context);
assert(!gallivm->module);
assert(!gallivm->provider);
+ lp_build_init();
+
gallivm->context = LLVMContextCreate();
if (!gallivm->context)
goto fail;
@@ -387,6 +388,9 @@ gallivm_garbage_collect(struct gallivm_state *gallivm)
void
lp_build_init(void)
{
+ if (gallivm_initialized)
+ return;
+
#ifdef DEBUG
gallivm_debug = debug_get_option_gallivm_debug();
#endif
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
index 2ef02160f23..960068c494d 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
@@ -82,6 +82,10 @@ struct pb_manager
*/
void
(*flush)( struct pb_manager *mgr );
+
+ boolean
+ (*is_buffer_busy)( struct pb_manager *mgr,
+ struct pb_buffer *buf );
};
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
index a6eb4039621..25accefa8d6 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
@@ -227,8 +227,6 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf,
pb_size size,
const struct pb_desc *desc)
{
- void *map;
-
if(buf->base.base.size < size)
return 0;
@@ -242,13 +240,18 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf,
if(!pb_check_usage(desc->usage, buf->base.base.usage))
return 0;
- map = pb_map(buf->buffer, PB_USAGE_DONTBLOCK, NULL);
- if (!map) {
- return -1;
+ if (buf->mgr->provider->is_buffer_busy) {
+ if (buf->mgr->provider->is_buffer_busy(buf->mgr->provider, buf->buffer))
+ return -1;
+ } else {
+ void *ptr = pb_map(buf->buffer, PB_USAGE_DONTBLOCK, NULL);
+
+ if (!ptr)
+ return -1;
+
+ pb_unmap(buf->buffer);
}
- pb_unmap(buf->buffer);
-
return 1;
}
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index 75b0f6a68ea..b03dd3a0cf8 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -2132,7 +2132,8 @@ struct x86_reg x86_fn_arg( struct x86_function *p,
return x86_make_disp(x86_make_reg(file_REG32, reg_SP),
p->stack_offset + arg * 4); /* ??? */
default:
- abort();
+ assert(0 && "Unexpected x86 target ABI in x86_fn_arg");
+ return x86_make_reg(file_REG32, reg_CX); /* not used / silence warning */
}
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 16a205f2068..d2cb98e84af 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -26,6 +26,7 @@
**************************************************************************/
#include "util/u_debug.h"
+#include "pipe/p_format.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi_build.h"
#include "tgsi_parse.h"
@@ -226,6 +227,45 @@ tgsi_build_declaration_semantic(
return ds;
}
+
+static struct tgsi_declaration_resource
+tgsi_default_declaration_resource(void)
+{
+ struct tgsi_declaration_resource declaration_resource;
+
+ declaration_resource.Resource = TGSI_TEXTURE_UNKNOWN;
+ declaration_resource.ReturnTypeX = PIPE_TYPE_UNORM;
+ declaration_resource.ReturnTypeY = PIPE_TYPE_UNORM;
+ declaration_resource.ReturnTypeZ = PIPE_TYPE_UNORM;
+ declaration_resource.ReturnTypeW = PIPE_TYPE_UNORM;
+
+ return declaration_resource;
+}
+
+static struct tgsi_declaration_resource
+tgsi_build_declaration_resource(unsigned texture,
+ unsigned return_type_x,
+ unsigned return_type_y,
+ unsigned return_type_z,
+ unsigned return_type_w,
+ struct tgsi_declaration *declaration,
+ struct tgsi_header *header)
+{
+ struct tgsi_declaration_resource declaration_resource;
+
+ declaration_resource = tgsi_default_declaration_resource();
+ declaration_resource.Resource = texture;
+ declaration_resource.ReturnTypeX = return_type_x;
+ declaration_resource.ReturnTypeY = return_type_y;
+ declaration_resource.ReturnTypeZ = return_type_z;
+ declaration_resource.ReturnTypeW = return_type_w;
+
+ declaration_grow(declaration, header);
+
+ return declaration_resource;
+}
+
+
struct tgsi_full_declaration
tgsi_default_full_declaration( void )
{
@@ -235,6 +275,7 @@ tgsi_default_full_declaration( void )
full_declaration.Range = tgsi_default_declaration_range();
full_declaration.Semantic = tgsi_default_declaration_semantic();
full_declaration.ImmediateData.u = NULL;
+ full_declaration.Resource = tgsi_default_declaration_resource();
return full_declaration;
}
@@ -324,6 +365,24 @@ tgsi_build_full_declaration(
}
}
+ if (full_decl->Declaration.File == TGSI_FILE_RESOURCE) {
+ struct tgsi_declaration_resource *dr;
+
+ if (maxsize <= size) {
+ return 0;
+ }
+ dr = (struct tgsi_declaration_resource *)&tokens[size];
+ size++;
+
+ *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource,
+ full_decl->Resource.ReturnTypeX,
+ full_decl->Resource.ReturnTypeY,
+ full_decl->Resource.ReturnTypeZ,
+ full_decl->Resource.ReturnTypeW,
+ declaration,
+ header);
+ }
+
return size;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 82cd8eaa969..c12662076b1 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -104,7 +104,8 @@ tgsi_file_names[TGSI_FILE_COUNT] =
"PRED",
"SV",
"IMMX",
- "TEMPX"
+ "TEMPX",
+ "RES"
};
static const char *interpolate_names[] =
@@ -157,7 +158,9 @@ tgsi_texture_names[TGSI_TEXTURE_COUNT] =
"RECT",
"SHADOW1D",
"SHADOW2D",
- "SHADOWRECT"
+ "SHADOWRECT",
+ "1DARRAY",
+ "2DARRAY"
};
const char *tgsi_property_names[TGSI_PROPERTY_COUNT] =
@@ -170,6 +173,15 @@ const char *tgsi_property_names[TGSI_PROPERTY_COUNT] =
"FS_COLOR0_WRITES_ALL_CBUFS",
};
+static const char *tgsi_type_names[] =
+{
+ "UNORM",
+ "SNORM",
+ "SINT",
+ "UINT",
+ "FLOAT"
+};
+
const char *tgsi_primitive_names[PIPE_PRIM_MAX] =
{
"POINTS",
@@ -393,6 +405,26 @@ iter_declaration(
}
}
+ if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
+ TXT(", ");
+ ENM(decl->Resource.Resource, tgsi_texture_names);
+ TXT(", ");
+ if ((decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeY) &&
+ (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeZ) &&
+ (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeW)) {
+ ENM(decl->Resource.ReturnTypeX, tgsi_type_names);
+ } else {
+ ENM(decl->Resource.ReturnTypeX, tgsi_type_names);
+ TXT(", ");
+ ENM(decl->Resource.ReturnTypeY, tgsi_type_names);
+ TXT(", ");
+ ENM(decl->Resource.ReturnTypeZ, tgsi_type_names);
+ TXT(", ");
+ ENM(decl->Resource.ReturnTypeW, tgsi_type_names);
+ }
+
+ }
+
if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT &&
decl->Declaration.File == TGSI_FILE_INPUT)
{
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 35b27423513..cbb090b2803 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1750,6 +1750,36 @@ exec_tex(struct tgsi_exec_machine *mach,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
+ case TGSI_TEXTURE_1D_ARRAY:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ }
+
+ fetch_texel(mach->Samplers[unit],
+ &r[0], &r[1], &r[2], lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ break;
+
+ case TGSI_TEXTURE_2D_ARRAY:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ }
+
+ fetch_texel(mach->Samplers[unit],
+ &r[0], &r[1], &r[2], lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ break;
+
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
FETCH(&r[0], 0, CHAN_X);
@@ -1843,6 +1873,164 @@ exec_txd(struct tgsi_exec_machine *mach,
}
+
+static void
+exec_sample(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ uint modifier)
+{
+ const uint resource_unit = inst->Src[1].Register.Index;
+ const uint sampler_unit = inst->Src[2].Register.Index;
+ union tgsi_exec_channel r[4];
+ const union tgsi_exec_channel *lod = &ZeroVec;
+ enum tgsi_sampler_control control;
+ uint chan;
+
+ if (modifier != TEX_MODIFIER_NONE) {
+ if (modifier == TEX_MODIFIER_LOD_BIAS)
+ FETCH(&r[3], 3, CHAN_X);
+ else /*TEX_MODIFIER_LOD*/
+ FETCH(&r[3], 0, CHAN_W);
+
+ if (modifier != TEX_MODIFIER_PROJECTED) {
+ lod = &r[3];
+ }
+ }
+
+ if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
+ control = tgsi_sampler_lod_explicit;
+ } else {
+ control = tgsi_sampler_lod_bias;
+ }
+
+ switch (mach->Resources[resource_unit].Resource) {
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ FETCH(&r[0], 0, CHAN_X);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ }
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &ZeroVec, &ZeroVec, lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ break;
+
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ micro_div(&r[2], &r[2], &r[3]);
+ }
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &r[1], &r[2], lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ break;
+
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ micro_div(&r[2], &r[2], &r[3]);
+ }
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &r[1], &r[2], lod,
+ control,
+ &r[0], &r[1], &r[2], &r[3]);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_sample_d(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ const uint resource_unit = inst->Src[1].Register.Index;
+ const uint sampler_unit = inst->Src[2].Register.Index;
+ union tgsi_exec_channel r[4];
+ uint chan;
+ /*
+ * XXX: This is fake SAMPLE_D -- the derivatives are not taken into account, yet.
+ */
+
+ switch (mach->Resources[resource_unit].Resource) {
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+
+ FETCH(&r[0], 0, CHAN_X);
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */
+ tgsi_sampler_lod_bias,
+ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ break;
+
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &r[1], &r[2], &ZeroVec, /* inputs */
+ tgsi_sampler_lod_bias,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ break;
+
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &r[1], &r[2], &ZeroVec,
+ tgsi_sampler_lod_bias,
+ &r[0], &r[1], &r[2], &r[3]);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+
/**
* Evaluate a constant-valued coefficient at the position of the
* current quad.
@@ -1914,6 +2102,11 @@ static void
exec_declaration(struct tgsi_exec_machine *mach,
const struct tgsi_full_declaration *decl)
{
+ if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
+ mach->Resources[decl->Range.First] = decl->Resource;
+ return;
+ }
+
if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
if (decl->Declaration.File == TGSI_FILE_INPUT) {
uint first, last, mask;
@@ -3688,6 +3881,54 @@ exec_instruction(
exec_endswitch(mach);
break;
+ case TGSI_OPCODE_LOAD:
+ assert(0);
+ break;
+
+ case TGSI_OPCODE_LOAD_MS:
+ assert(0);
+ break;
+
+ case TGSI_OPCODE_SAMPLE:
+ exec_sample(mach, inst, TEX_MODIFIER_NONE);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_B:
+ exec_sample(mach, inst, TEX_MODIFIER_LOD_BIAS);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_C:
+ exec_sample(mach, inst, TEX_MODIFIER_NONE);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_C_LZ:
+ exec_sample(mach, inst, TEX_MODIFIER_LOD_BIAS);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_D:
+ exec_sample_d(mach, inst);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_L:
+ exec_sample(mach, inst, TEX_MODIFIER_EXPLICIT_LOD);
+ break;
+
+ case TGSI_OPCODE_GATHER4:
+ assert(0);
+ break;
+
+ case TGSI_OPCODE_RESINFO:
+ assert(0);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_POS:
+ assert(0);
+ break;
+
+ case TGSI_OPCODE_SAMPLE_INFO:
+ assert(0);
+ break;
+
default:
assert( 0 );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 6c204c73714..4a423b5bb4e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -308,6 +308,7 @@ struct tgsi_exec_machine
struct tgsi_full_declaration *Declarations;
uint NumDeclarations;
+ struct tgsi_declaration_resource Resources[PIPE_MAX_SHADER_RESOURCES];
};
struct tgsi_exec_machine *
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index e59e964ffa7..14ed56a1f6a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -175,7 +175,20 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 0, 1, 0, 0, 0, 0, "SWITCH", TGSI_OPCODE_SWITCH },
{ 0, 1, 0, 0, 0, 0, "CASE", TGSI_OPCODE_CASE },
{ 0, 0, 0, 0, 0, 0, "DEFAULT", TGSI_OPCODE_DEFAULT },
- { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH }
+ { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH },
+
+ { 1, 2, 0, 0, 0, 0, "LOAD", TGSI_OPCODE_LOAD },
+ { 1, 2, 0, 0, 0, 0, "LOAD_MS", TGSI_OPCODE_LOAD_MS },
+ { 1, 3, 0, 0, 0, 0, "SAMPLE", TGSI_OPCODE_SAMPLE },
+ { 1, 4, 0, 0, 0, 0, "SAMPLE_B", TGSI_OPCODE_SAMPLE_B },
+ { 1, 4, 0, 0, 0, 0, "SAMPLE_C", TGSI_OPCODE_SAMPLE_C },
+ { 1, 4, 0, 0, 0, 0, "SAMPLE_C_LZ", TGSI_OPCODE_SAMPLE_C_LZ },
+ { 1, 5, 0, 0, 0, 0, "SAMPLE_D", TGSI_OPCODE_SAMPLE_D },
+ { 1, 3, 0, 0, 0, 0, "SAMPLE_L", TGSI_OPCODE_SAMPLE_L },
+ { 1, 3, 0, 0, 0, 0, "GATHER4", TGSI_OPCODE_GATHER4 },
+ { 1, 2, 0, 0, 0, 0, "RESINFO", TGSI_OPCODE_RESINFO },
+ { 1, 2, 0, 0, 0, 0, "SAMPLE_POS", TGSI_OPCODE_SAMPLE_POS },
+ { 1, 2, 0, 0, 0, 0, "SAMPLE_INFO", TGSI_OPCODE_SAMPLE_INFO },
};
const struct tgsi_opcode_info *
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
index b3123ed016d..b5d4504425b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -168,6 +168,19 @@ OP01(CASE)
OP00(DEFAULT)
OP00(ENDSWITCH)
+OP12(LOAD)
+OP12(LOAD_MS)
+OP13(SAMPLE)
+OP14(SAMPLE_B)
+OP14(SAMPLE_C)
+OP14(SAMPLE_C_LZ)
+OP15(SAMPLE_D)
+OP13(SAMPLE_L)
+OP13(GATHER4)
+OP12(RESINFO)
+OP13(SAMPLE_POS)
+OP12(SAMPLE_INFO)
+
#undef OP00
#undef OP01
@@ -180,6 +193,10 @@ OP00(ENDSWITCH)
#undef OP14
#endif
+#ifdef OP15
+#undef OP15
+#endif
+
#undef OP00_LBL
#undef OP01_LBL
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 1891203abe1..fb36f9de32d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -128,6 +128,10 @@ tgsi_parse_token(
}
}
+ if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
+ next_token(ctx, &decl->Resource);
+ }
+
break;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 2aafa2a6e83..b7a3c9bc0e6 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -69,6 +69,7 @@ struct tgsi_full_declaration
struct tgsi_declaration_dimension Dim;
struct tgsi_declaration_semantic Semantic;
struct tgsi_immediate_array_data ImmediateData;
+ struct tgsi_declaration_resource Resource;
};
struct tgsi_full_immediate
@@ -84,7 +85,7 @@ struct tgsi_full_property
};
#define TGSI_FULL_MAX_DST_REGISTERS 2
-#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
+#define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */
struct tgsi_full_instruction
{
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index acbff103efe..509c5346837 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -258,7 +258,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"PRED",
"SV",
"IMMX",
- "TEMPX"
+ "TEMPX",
+ "RES"
};
static boolean
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index 3f2cda860e0..92ba8b8f033 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -1514,6 +1514,7 @@ emit_tex( struct x86_function *func,
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_1D_ARRAY:
count = 2;
break;
case TGSI_TEXTURE_SHADOW1D:
@@ -1521,6 +1522,7 @@ emit_tex( struct x86_function *func,
case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
+ case TGSI_TEXTURE_2D_ARRAY:
count = 3;
break;
default:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 819b0725a1f..1eac762e6e5 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -283,7 +283,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"PRED",
"SV",
"IMMX",
- "TEMPX"
+ "TEMPX",
+ "RES"
};
static boolean
@@ -828,6 +829,15 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] =
"SHADOWRECT"
};
+static const char *type_names[] =
+{
+ "UNORM",
+ "SNORM",
+ "SINT",
+ "UINT",
+ "FLOAT"
+};
+
static boolean
match_inst_mnemonic(const char **pcur,
const struct tgsi_opcode_info *info)
@@ -1104,42 +1114,113 @@ static boolean parse_declaration( struct translate_ctx *ctx )
cur = ctx->cur;
eat_opt_white( &cur );
if (*cur == ',' && !is_vs_input) {
- uint i;
+ uint i, j;
cur++;
eat_opt_white( &cur );
- for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
- if (str_match_no_case( &cur, semantic_names[i] )) {
- const char *cur2 = cur;
- uint index;
-
- if (is_digit_alpha_underscore( cur ))
- continue;
- eat_opt_white( &cur2 );
- if (*cur2 == '[') {
- cur2++;
- eat_opt_white( &cur2 );
- if (!parse_uint( &cur2, &index )) {
- report_error( ctx, "Expected literal integer" );
+ if (file == TGSI_FILE_RESOURCE) {
+ for (i = 0; i < TGSI_TEXTURE_COUNT; i++) {
+ if (str_match_no_case(&cur, texture_names[i])) {
+ if (!is_digit_alpha_underscore(cur)) {
+ decl.Resource.Resource = i;
+ break;
+ }
+ }
+ }
+ if (i == TGSI_TEXTURE_COUNT) {
+ report_error(ctx, "Expected texture target");
+ return FALSE;
+ }
+ eat_opt_white( &cur );
+ if (*cur != ',') {
+ report_error( ctx, "Expected `,'" );
+ return FALSE;
+ }
+ ++cur;
+ eat_opt_white( &cur );
+ for (j = 0; j < 4; ++j) {
+ for (i = 0; i < PIPE_TYPE_COUNT; ++i) {
+ if (str_match_no_case(&cur, type_names[i])) {
+ if (!is_digit_alpha_underscore(cur)) {
+ switch (j) {
+ case 0:
+ decl.Resource.ReturnTypeX = i;
+ break;
+ case 1:
+ decl.Resource.ReturnTypeY = i;
+ break;
+ case 2:
+ decl.Resource.ReturnTypeZ = i;
+ break;
+ case 3:
+ decl.Resource.ReturnTypeW = i;
+ break;
+ default:
+ assert(0);
+ }
+ break;
+ }
+ }
+ }
+ if (i == PIPE_TYPE_COUNT) {
+ if (j == 0 || j > 2) {
+ report_error(ctx, "Expected type name");
return FALSE;
}
+ break;
+ } else {
+ const char *cur2 = cur;
eat_opt_white( &cur2 );
- if (*cur2 != ']') {
- report_error( ctx, "Expected `]'" );
- return FALSE;
+ if (*cur2 == ',') {
+ cur2++;
+ eat_opt_white( &cur2 );
+ cur = cur2;
+ continue;
+ } else
+ break;
+ }
+ }
+ if (j < 4) {
+ decl.Resource.ReturnTypeY =
+ decl.Resource.ReturnTypeZ =
+ decl.Resource.ReturnTypeW =
+ decl.Resource.ReturnTypeX;
+ }
+ ctx->cur = cur;
+ } else {
+ for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) {
+ if (str_match_no_case( &cur, semantic_names[i] )) {
+ const char *cur2 = cur;
+ uint index;
+
+ if (is_digit_alpha_underscore( cur ))
+ continue;
+ eat_opt_white( &cur2 );
+ if (*cur2 == '[') {
+ cur2++;
+ eat_opt_white( &cur2 );
+ if (!parse_uint( &cur2, &index )) {
+ report_error( ctx, "Expected literal integer" );
+ return FALSE;
+ }
+ eat_opt_white( &cur2 );
+ if (*cur2 != ']') {
+ report_error( ctx, "Expected `]'" );
+ return FALSE;
+ }
+ cur2++;
+
+ decl.Semantic.Index = index;
+
+ cur = cur2;
}
- cur2++;
- decl.Semantic.Index = index;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.Name = i;
- cur = cur2;
+ ctx->cur = cur;
+ break;
}
-
- decl.Declaration.Semantic = 1;
- decl.Semantic.Name = i;
-
- ctx->cur = cur;
- break;
}
}
} else if (is_imm_array) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 02de12d77d5..4564ab81f99 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2009 VMware, Inc.
+ * Copyright 2009-2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -47,6 +47,7 @@ union tgsi_any_token {
struct tgsi_declaration_range decl_range;
struct tgsi_declaration_dimension decl_dim;
struct tgsi_declaration_semantic decl_semantic;
+ struct tgsi_declaration_resource decl_resource;
struct tgsi_immediate imm;
union tgsi_immediate_data imm_data;
struct tgsi_instruction insn;
@@ -137,6 +138,16 @@ struct ureg_program
struct ureg_src sampler[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
+ struct {
+ unsigned index;
+ unsigned target;
+ unsigned return_type_x;
+ unsigned return_type_y;
+ unsigned return_type_z;
+ unsigned return_type_w;
+ } resource[PIPE_MAX_SHADER_RESOURCES];
+ unsigned nr_resources;
+
unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps;
@@ -578,6 +589,41 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
return ureg->sampler[0];
}
+/*
+ * Allocate a new shader resource.
+ */
+struct ureg_src
+ureg_DECL_resource(struct ureg_program *ureg,
+ unsigned index,
+ unsigned target,
+ unsigned return_type_x,
+ unsigned return_type_y,
+ unsigned return_type_z,
+ unsigned return_type_w)
+{
+ struct ureg_src reg = ureg_src_register(TGSI_FILE_RESOURCE, index);
+ uint i;
+
+ for (i = 0; i < ureg->nr_resources; i++) {
+ if (ureg->resource[i].index == index) {
+ return reg;
+ }
+ }
+
+ if (i < PIPE_MAX_SHADER_RESOURCES) {
+ ureg->resource[i].index = index;
+ ureg->resource[i].target = target;
+ ureg->resource[i].return_type_x = return_type_x;
+ ureg->resource[i].return_type_y = return_type_y;
+ ureg->resource[i].return_type_z = return_type_z;
+ ureg->resource[i].return_type_w = return_type_w;
+ ureg->nr_resources++;
+ return reg;
+ }
+
+ assert(0);
+ return reg;
+}
static int
match_or_expand_immediate( const unsigned *v,
@@ -821,9 +867,10 @@ ureg_emit_dst( struct ureg_program *ureg,
assert(dst.File != TGSI_FILE_CONSTANT);
assert(dst.File != TGSI_FILE_INPUT);
assert(dst.File != TGSI_FILE_SAMPLER);
+ assert(dst.File != TGSI_FILE_RESOURCE);
assert(dst.File != TGSI_FILE_IMMEDIATE);
assert(dst.File < TGSI_FILE_COUNT);
-
+
out[n].value = 0;
out[n].dst.File = dst.File;
out[n].dst.WriteMask = dst.WriteMask;
@@ -1206,6 +1253,36 @@ emit_decl_range2D(struct ureg_program *ureg,
}
static void
+emit_decl_resource(struct ureg_program *ureg,
+ unsigned index,
+ unsigned target,
+ unsigned return_type_x,
+ unsigned return_type_y,
+ unsigned return_type_z,
+ unsigned return_type_w )
+{
+ union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 3;
+ out[0].decl.File = TGSI_FILE_RESOURCE;
+ out[0].decl.UsageMask = 0xf;
+ out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+
+ out[1].value = 0;
+ out[1].decl_range.First = index;
+ out[1].decl_range.Last = index;
+
+ out[2].value = 0;
+ out[2].decl_resource.Resource = target;
+ out[2].decl_resource.ReturnTypeX = return_type_x;
+ out[2].decl_resource.ReturnTypeY = return_type_y;
+ out[2].decl_resource.ReturnTypeZ = return_type_z;
+ out[2].decl_resource.ReturnTypeW = return_type_w;
+}
+
+static void
emit_immediate( struct ureg_program *ureg,
const unsigned *v,
unsigned type )
@@ -1341,6 +1418,16 @@ static void emit_decls( struct ureg_program *ureg )
ureg->sampler[i].Index, 1 );
}
+ for (i = 0; i < ureg->nr_resources; i++) {
+ emit_decl_resource(ureg,
+ ureg->resource[i].index,
+ ureg->resource[i].target,
+ ureg->resource[i].return_type_x,
+ ureg->resource[i].return_type_y,
+ ureg->resource[i].return_type_z,
+ ureg->resource[i].return_type_w);
+ }
+
if (ureg->const_decls.nr_constant_ranges) {
for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) {
emit_decl_range(ureg,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 807128a5e52..b8d193f3f89 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -270,6 +270,15 @@ struct ureg_src
ureg_DECL_sampler( struct ureg_program *,
unsigned index );
+struct ureg_src
+ureg_DECL_resource(struct ureg_program *,
+ unsigned index,
+ unsigned target,
+ unsigned return_type_x,
+ unsigned return_type_y,
+ unsigned return_type_z,
+ unsigned return_type_w );
+
static INLINE struct ureg_src
ureg_imm4f( struct ureg_program *ureg,
@@ -733,6 +742,66 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
}
+#define OP14( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src0, \
+ struct ureg_src src1, \
+ struct ureg_src src2, \
+ struct ureg_src src3 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 4).insn_token; \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_emit_src( ureg, src2 ); \
+ ureg_emit_src( ureg, src3 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+
+#define OP15( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src0, \
+ struct ureg_src src1, \
+ struct ureg_src src2, \
+ struct ureg_src src3, \
+ struct ureg_src src4 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn(ureg, \
+ opcode, \
+ dst.Saturate, \
+ dst.Predicate, \
+ dst.PredNegate, \
+ dst.PredSwizzleX, \
+ dst.PredSwizzleY, \
+ dst.PredSwizzleZ, \
+ dst.PredSwizzleW, \
+ 1, \
+ 5).insn_token; \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_emit_src( ureg, src2 ); \
+ ureg_emit_src( ureg, src3 ); \
+ ureg_emit_src( ureg, src4 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+
/* Use a template include to generate a correctly-typed ureg_OP()
* function for each TGSI opcode:
*/
diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c
index 08e7e89bd67..aa9a886d4a9 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_util.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_util.c
@@ -280,7 +280,12 @@ tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
case TGSI_TEXTURE_CUBE:
read_mask = TGSI_WRITEMASK_XYZ;
break;
-
+ case TGSI_TEXTURE_1D_ARRAY:
+ read_mask = TGSI_WRITEMASK_XY;
+ break;
+ case TGSI_TEXTURE_2D_ARRAY:
+ read_mask = TGSI_WRITEMASK_XYZ;
+ break;
default:
assert(0);
read_mask = 0;
diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c
index d8069a149cf..3f1ecb630f2 100644
--- a/src/gallium/auxiliary/translate/translate_cache.c
+++ b/src/gallium/auxiliary/translate/translate_cache.c
@@ -40,6 +40,10 @@ struct translate_cache {
struct translate_cache * translate_cache_create( void )
{
struct translate_cache *cache = MALLOC_STRUCT(translate_cache);
+ if (cache == NULL) {
+ return NULL;
+ }
+
cache->hash = cso_hash_create();
return cache;
}
diff --git a/src/gallium/auxiliary/util/dbghelp.h b/src/gallium/auxiliary/util/dbghelp.h
new file mode 100644
index 00000000000..bc7c53cf9f2
--- /dev/null
+++ b/src/gallium/auxiliary/util/dbghelp.h
@@ -0,0 +1,1265 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#ifndef _DBGHELP_
+#define _DBGHELP_
+
+#ifdef _WIN64
+#ifndef _IMAGEHLP64
+#define _IMAGEHLP64
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IMAGEAPI DECLSPEC_IMPORT WINAPI
+#define DBHLP_DEPRECIATED __declspec(deprecated)
+
+#define DBHLPAPI IMAGEAPI
+
+#define IMAGE_SEPARATION (64*1024)
+
+ typedef struct _LOADED_IMAGE {
+ PSTR ModuleName;
+ HANDLE hFile;
+ PUCHAR MappedAddress;
+#ifdef _IMAGEHLP64
+ PIMAGE_NT_HEADERS64 FileHeader;
+#else
+ PIMAGE_NT_HEADERS32 FileHeader;
+#endif
+ PIMAGE_SECTION_HEADER LastRvaSection;
+ ULONG NumberOfSections;
+ PIMAGE_SECTION_HEADER Sections;
+ ULONG Characteristics;
+ BOOLEAN fSystemImage;
+ BOOLEAN fDOSImage;
+ LIST_ENTRY Links;
+ ULONG SizeOfImage;
+ } LOADED_IMAGE,*PLOADED_IMAGE;
+
+#define MAX_SYM_NAME 2000
+
+ typedef BOOL (CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(HANDLE FileHandle,PSTR FileName,PVOID CallerData);
+ typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACK)(PSTR filename,PVOID context);
+ typedef BOOL (CALLBACK *PFIND_EXE_FILE_CALLBACK)(HANDLE FileHandle,PSTR FileName,PVOID CallerData);
+
+ typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(LPCSTR,LPCSTR,PVOID,DWORD,DWORD,LPSTR);
+ typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID);
+ typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID);
+ typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR,ULONG64);
+ typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action,ULONG64 data,ULONG64 context);
+ typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)();
+ typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(LPCSTR);
+
+ HANDLE IMAGEAPI FindDebugInfoFile(PSTR FileName,PSTR SymbolPath,PSTR DebugFilePath);
+ HANDLE IMAGEAPI FindDebugInfoFileEx(PSTR FileName,PSTR SymbolPath,PSTR DebugFilePath,PFIND_DEBUG_FILE_CALLBACK Callback,PVOID CallerData);
+ BOOL IMAGEAPI SymFindFileInPath(HANDLE hprocess,LPSTR SearchPath,LPSTR FileName,PVOID id,DWORD two,DWORD three,DWORD flags,LPSTR FoundFile,PFINDFILEINPATHCALLBACK callback,PVOID context);
+ HANDLE IMAGEAPI FindExecutableImage(PSTR FileName,PSTR SymbolPath,PSTR ImageFilePath);
+ HANDLE IMAGEAPI FindExecutableImageEx(PSTR FileName,PSTR SymbolPath,PSTR ImageFilePath,PFIND_EXE_FILE_CALLBACK Callback,PVOID CallerData);
+ PIMAGE_NT_HEADERS IMAGEAPI ImageNtHeader(PVOID Base);
+ PVOID IMAGEAPI ImageDirectoryEntryToDataEx(PVOID Base,BOOLEAN MappedAsImage,USHORT DirectoryEntry,PULONG Size,PIMAGE_SECTION_HEADER *FoundHeader);
+ PVOID IMAGEAPI ImageDirectoryEntryToData(PVOID Base,BOOLEAN MappedAsImage,USHORT DirectoryEntry,PULONG Size);
+ PIMAGE_SECTION_HEADER IMAGEAPI ImageRvaToSection(PIMAGE_NT_HEADERS NtHeaders,PVOID Base,ULONG Rva);
+ PVOID IMAGEAPI ImageRvaToVa(PIMAGE_NT_HEADERS NtHeaders,PVOID Base,ULONG Rva,PIMAGE_SECTION_HEADER *LastRvaSection);
+
+#define SSRVOPT_CALLBACK 0x0001
+#define SSRVOPT_DWORD 0x0002
+#define SSRVOPT_DWORDPTR 0x0004
+#define SSRVOPT_GUIDPTR 0x0008
+#define SSRVOPT_OLDGUIDPTR 0x0010
+#define SSRVOPT_UNATTENDED 0x0020
+#define SSRVOPT_NOCOPY 0x0040
+#define SSRVOPT_PARENTWIN 0x0080
+#define SSRVOPT_PARAMTYPE 0x0100
+#define SSRVOPT_SECURE 0x0200
+#define SSRVOPT_TRACE 0x0400
+#define SSRVOPT_SETCONTEXT 0x0800
+#define SSRVOPT_PROXY 0x1000
+#define SSRVOPT_DOWNSTREAM_STORE 0x2000
+#define SSRVOPT_RESET ((ULONG_PTR)-1)
+
+#define SSRVACTION_TRACE 1
+#define SSRVACTION_QUERYCANCEL 2
+#define SSRVACTION_EVENT 3
+
+#ifndef _WIN64
+
+ typedef struct _IMAGE_DEBUG_INFORMATION {
+ LIST_ENTRY List;
+ DWORD ReservedSize;
+ PVOID ReservedMappedBase;
+ USHORT ReservedMachine;
+ USHORT ReservedCharacteristics;
+ DWORD ReservedCheckSum;
+ DWORD ImageBase;
+ DWORD SizeOfImage;
+ DWORD ReservedNumberOfSections;
+ PIMAGE_SECTION_HEADER ReservedSections;
+ DWORD ReservedExportedNamesSize;
+ PSTR ReservedExportedNames;
+ DWORD ReservedNumberOfFunctionTableEntries;
+ PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
+ DWORD ReservedLowestFunctionStartingAddress;
+ DWORD ReservedHighestFunctionEndingAddress;
+ DWORD ReservedNumberOfFpoTableEntries;
+ PFPO_DATA ReservedFpoTableEntries;
+ DWORD SizeOfCoffSymbols;
+ PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
+ DWORD ReservedSizeOfCodeViewSymbols;
+ PVOID ReservedCodeViewSymbols;
+ PSTR ImageFilePath;
+ PSTR ImageFileName;
+ PSTR ReservedDebugFilePath;
+ DWORD ReservedTimeDateStamp;
+ BOOL ReservedRomImage;
+ PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
+ DWORD ReservedNumberOfDebugDirectories;
+ DWORD ReservedOriginalFunctionTableBaseAddress;
+ DWORD Reserved[2 ];
+ } IMAGE_DEBUG_INFORMATION,*PIMAGE_DEBUG_INFORMATION;
+
+ PIMAGE_DEBUG_INFORMATION IMAGEAPI MapDebugInformation(HANDLE FileHandle,PSTR FileName,PSTR SymbolPath,DWORD ImageBase);
+ BOOL IMAGEAPI UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION DebugInfo);
+#endif
+
+ typedef BOOL (CALLBACK *PENUMDIRTREE_CALLBACK)(LPCSTR FilePath,PVOID CallerData);
+
+ BOOL IMAGEAPI SearchTreeForFile(PSTR RootPath,PSTR InputPathName,PSTR OutputPathBuffer);
+ BOOL IMAGEAPI EnumDirTree(HANDLE hProcess,PSTR RootPath,PSTR InputPathName,PSTR OutputPathBuffer,PENUMDIRTREE_CALLBACK Callback,PVOID CallbackData);
+ BOOL IMAGEAPI MakeSureDirectoryPathExists(PCSTR DirPath);
+
+#define UNDNAME_COMPLETE (0x0000)
+#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001)
+#define UNDNAME_NO_MS_KEYWORDS (0x0002)
+#define UNDNAME_NO_FUNCTION_RETURNS (0x0004)
+#define UNDNAME_NO_ALLOCATION_MODEL (0x0008)
+#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010)
+#define UNDNAME_NO_MS_THISTYPE (0x0020)
+#define UNDNAME_NO_CV_THISTYPE (0x0040)
+#define UNDNAME_NO_THISTYPE (0x0060)
+#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080)
+#define UNDNAME_NO_THROW_SIGNATURES (0x0100)
+#define UNDNAME_NO_MEMBER_TYPE (0x0200)
+#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400)
+#define UNDNAME_32_BIT_DECODE (0x0800)
+#define UNDNAME_NAME_ONLY (0x1000)
+#define UNDNAME_NO_ARGUMENTS (0x2000)
+#define UNDNAME_NO_SPECIAL_SYMS (0x4000)
+
+ DWORD IMAGEAPI WINAPI UnDecorateSymbolName(PCSTR DecoratedName,PSTR UnDecoratedName,DWORD UndecoratedLength,DWORD Flags);
+
+#define DBHHEADER_DEBUGDIRS 0x1
+
+ typedef struct _MODLOAD_DATA {
+ DWORD ssize;
+ DWORD ssig;
+ PVOID data;
+ DWORD size;
+ DWORD flags;
+ } MODLOAD_DATA,*PMODLOAD_DATA;
+
+ typedef enum {
+ AddrMode1616,AddrMode1632,AddrModeReal,AddrModeFlat
+ } ADDRESS_MODE;
+
+ typedef struct _tagADDRESS64 {
+ DWORD64 Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+ } ADDRESS64,*LPADDRESS64;
+
+#ifdef _IMAGEHLP64
+#define ADDRESS ADDRESS64
+#define LPADDRESS LPADDRESS64
+#else
+ typedef struct _tagADDRESS {
+ DWORD Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+ } ADDRESS,*LPADDRESS;
+
+ static __inline void Address32To64(LPADDRESS a32,LPADDRESS64 a64) {
+ a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset;
+ a64->Segment = a32->Segment;
+ a64->Mode = a32->Mode;
+ }
+
+ static __inline void Address64To32(LPADDRESS64 a64,LPADDRESS a32) {
+ a32->Offset = (ULONG)a64->Offset;
+ a32->Segment = a64->Segment;
+ a32->Mode = a64->Mode;
+ }
+#endif
+
+ typedef struct _KDHELP64 {
+ DWORD64 Thread;
+ DWORD ThCallbackStack;
+ DWORD ThCallbackBStore;
+ DWORD NextCallback;
+ DWORD FramePointer;
+ DWORD64 KiCallUserMode;
+ DWORD64 KeUserCallbackDispatcher;
+ DWORD64 SystemRangeStart;
+ DWORD64 Reserved[8];
+ } KDHELP64,*PKDHELP64;
+
+#ifdef _IMAGEHLP64
+#define KDHELP KDHELP64
+#define PKDHELP PKDHELP64
+#else
+ typedef struct _KDHELP {
+ DWORD Thread;
+ DWORD ThCallbackStack;
+ DWORD NextCallback;
+ DWORD FramePointer;
+ DWORD KiCallUserMode;
+ DWORD KeUserCallbackDispatcher;
+ DWORD SystemRangeStart;
+ DWORD ThCallbackBStore;
+ DWORD Reserved[8];
+ } KDHELP,*PKDHELP;
+
+ static __inline void KdHelp32To64(PKDHELP p32,PKDHELP64 p64) {
+ p64->Thread = p32->Thread;
+ p64->ThCallbackStack = p32->ThCallbackStack;
+ p64->NextCallback = p32->NextCallback;
+ p64->FramePointer = p32->FramePointer;
+ p64->KiCallUserMode = p32->KiCallUserMode;
+ p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher;
+ p64->SystemRangeStart = p32->SystemRangeStart;
+ }
+#endif
+
+ typedef struct _tagSTACKFRAME64 {
+ ADDRESS64 AddrPC;
+ ADDRESS64 AddrReturn;
+ ADDRESS64 AddrFrame;
+ ADDRESS64 AddrStack;
+ ADDRESS64 AddrBStore;
+ PVOID FuncTableEntry;
+ DWORD64 Params[4];
+ BOOL Far;
+ BOOL Virtual;
+ DWORD64 Reserved[3];
+ KDHELP64 KdHelp;
+ } STACKFRAME64,*LPSTACKFRAME64;
+
+#ifdef _IMAGEHLP64
+#define STACKFRAME STACKFRAME64
+#define LPSTACKFRAME LPSTACKFRAME64
+#else
+ typedef struct _tagSTACKFRAME {
+ ADDRESS AddrPC;
+ ADDRESS AddrReturn;
+ ADDRESS AddrFrame;
+ ADDRESS AddrStack;
+ PVOID FuncTableEntry;
+ DWORD Params[4];
+ BOOL Far;
+ BOOL Virtual;
+ DWORD Reserved[3];
+ KDHELP KdHelp;
+ ADDRESS AddrBStore;
+ } STACKFRAME,*LPSTACKFRAME;
+#endif
+
+ typedef BOOL (WINAPI *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,DWORD64 qwBaseAddress,PVOID lpBuffer,DWORD nSize,LPDWORD lpNumberOfBytesRead);
+ typedef PVOID (WINAPI *PFUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE hProcess,DWORD64 AddrBase);
+ typedef DWORD64 (WINAPI *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,DWORD64 Address);
+ typedef DWORD64 (WINAPI *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,HANDLE hThread,LPADDRESS64 lpaddr);
+
+ BOOL IMAGEAPI StackWalk64(DWORD MachineType,HANDLE hProcess,HANDLE hThread,LPSTACKFRAME64 StackFrame,PVOID ContextRecord,PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
+
+#ifdef _IMAGEHLP64
+#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64
+#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64
+#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64
+#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64
+#define StackWalk StackWalk64
+#else
+ typedef BOOL (WINAPI *PREAD_PROCESS_MEMORY_ROUTINE)(HANDLE hProcess,DWORD lpBaseAddress,PVOID lpBuffer,DWORD nSize,PDWORD lpNumberOfBytesRead);
+ typedef PVOID (WINAPI *PFUNCTION_TABLE_ACCESS_ROUTINE)(HANDLE hProcess,DWORD AddrBase);
+ typedef DWORD (WINAPI *PGET_MODULE_BASE_ROUTINE)(HANDLE hProcess,DWORD Address);
+ typedef DWORD (WINAPI *PTRANSLATE_ADDRESS_ROUTINE)(HANDLE hProcess,HANDLE hThread,LPADDRESS lpaddr);
+
+ BOOL IMAGEAPI StackWalk(DWORD MachineType,HANDLE hProcess,HANDLE hThread,LPSTACKFRAME StackFrame,PVOID ContextRecord,PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
+#endif
+
+#define API_VERSION_NUMBER 9
+
+ typedef struct API_VERSION {
+ USHORT MajorVersion;
+ USHORT MinorVersion;
+ USHORT Revision;
+ USHORT Reserved;
+ } API_VERSION,*LPAPI_VERSION;
+
+ LPAPI_VERSION IMAGEAPI ImagehlpApiVersion(VOID);
+ LPAPI_VERSION IMAGEAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion);
+ DWORD IMAGEAPI GetTimestampForLoadedLibrary(HMODULE Module);
+
+ typedef BOOL (CALLBACK *PSYM_ENUMMODULES_CALLBACK64)(PSTR ModuleName,DWORD64 BaseOfDll,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)(PSTR SymbolName,DWORD64 SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)(PWSTR SymbolName,DWORD64 SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PENUMLOADED_MODULES_CALLBACK64)(PSTR ModuleName,DWORD64 ModuleBase,ULONG ModuleSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)(HANDLE hProcess,ULONG ActionCode,ULONG64 CallbackData,ULONG64 UserContext);
+ typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(HANDLE hProcess,DWORD AddrBase,PVOID UserContext);
+ typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(HANDLE hProcess,ULONG64 AddrBase,ULONG64 UserContext);
+
+#ifdef _IMAGEHLP64
+#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W
+#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64
+#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64
+#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64
+#else
+ typedef BOOL (CALLBACK *PSYM_ENUMMODULES_CALLBACK)(PSTR ModuleName,ULONG BaseOfDll,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)(PSTR SymbolName,ULONG SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)(PWSTR SymbolName,ULONG SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PENUMLOADED_MODULES_CALLBACK)(PSTR ModuleName,ULONG ModuleBase,ULONG ModuleSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(HANDLE hProcess,ULONG ActionCode,PVOID CallbackData,PVOID UserContext);
+#endif
+
+#define SYMFLAG_VALUEPRESENT 0x00000001
+#define SYMFLAG_REGISTER 0x00000008
+#define SYMFLAG_REGREL 0x00000010
+#define SYMFLAG_FRAMEREL 0x00000020
+#define SYMFLAG_PARAMETER 0x00000040
+#define SYMFLAG_LOCAL 0x00000080
+#define SYMFLAG_CONSTANT 0x00000100
+#define SYMFLAG_EXPORT 0x00000200
+#define SYMFLAG_FORWARDER 0x00000400
+#define SYMFLAG_FUNCTION 0x00000800
+#define SYMFLAG_VIRTUAL 0x00001000
+#define SYMFLAG_THUNK 0x00002000
+#define SYMFLAG_TLSREL 0x00004000
+
+ typedef enum {
+ SymNone = 0,SymCoff,SymCv,SymPdb,SymExport,SymDeferred,SymSym,SymDia,SymVirtual,NumSymTypes
+ } SYM_TYPE;
+
+ typedef struct _IMAGEHLP_SYMBOL64 {
+ DWORD SizeOfStruct;
+ DWORD64 Address;
+ DWORD Size;
+ DWORD Flags;
+ DWORD MaxNameLength;
+ CHAR Name[1];
+ } IMAGEHLP_SYMBOL64,*PIMAGEHLP_SYMBOL64;
+
+ typedef struct _IMAGEHLP_SYMBOL64_PACKAGE {
+ IMAGEHLP_SYMBOL64 sym;
+ CHAR name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOL64_PACKAGE,*PIMAGEHLP_SYMBOL64_PACKAGE;
+
+#ifdef _IMAGEHLP64
+
+#define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64
+#define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64
+#define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE
+#define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE
+#else
+
+ typedef struct _IMAGEHLP_SYMBOL {
+ DWORD SizeOfStruct;
+ DWORD Address;
+ DWORD Size;
+ DWORD Flags;
+ DWORD MaxNameLength;
+ CHAR Name[1];
+ } IMAGEHLP_SYMBOL,*PIMAGEHLP_SYMBOL;
+
+ typedef struct _IMAGEHLP_SYMBOL_PACKAGE {
+ IMAGEHLP_SYMBOL sym;
+ CHAR name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOL_PACKAGE,*PIMAGEHLP_SYMBOL_PACKAGE;
+#endif
+
+ typedef struct _IMAGEHLP_MODULE64 {
+ DWORD SizeOfStruct;
+ DWORD64 BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ CHAR ModuleName[32];
+ CHAR ImageName[256];
+ CHAR LoadedImageName[256];
+ CHAR LoadedPdbName[256];
+ DWORD CVSig;
+ CHAR CVData[MAX_PATH*3];
+ DWORD PdbSig;
+ GUID PdbSig70;
+ DWORD PdbAge;
+ BOOL PdbUnmatched;
+ BOOL DbgUnmatched;
+ BOOL LineNumbers;
+ BOOL GlobalSymbols;
+ BOOL TypeInfo;
+ } IMAGEHLP_MODULE64,*PIMAGEHLP_MODULE64;
+
+ typedef struct _IMAGEHLP_MODULE64W {
+ DWORD SizeOfStruct;
+ DWORD64 BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ WCHAR ModuleName[32];
+ WCHAR ImageName[256];
+ WCHAR LoadedImageName[256];
+ WCHAR LoadedPdbName[256];
+ DWORD CVSig;
+ WCHAR CVData[MAX_PATH*3];
+ DWORD PdbSig;
+ GUID PdbSig70;
+ DWORD PdbAge;
+ BOOL PdbUnmatched;
+ BOOL DbgUnmatched;
+ BOOL LineNumbers;
+ BOOL GlobalSymbols;
+ BOOL TypeInfo;
+ } IMAGEHLP_MODULEW64,*PIMAGEHLP_MODULEW64;
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_MODULE IMAGEHLP_MODULE64
+#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64
+#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64
+#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64
+#else
+ typedef struct _IMAGEHLP_MODULE {
+ DWORD SizeOfStruct;
+ DWORD BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ CHAR ModuleName[32];
+ CHAR ImageName[256];
+ CHAR LoadedImageName[256];
+ } IMAGEHLP_MODULE,*PIMAGEHLP_MODULE;
+
+ typedef struct _IMAGEHLP_MODULEW {
+ DWORD SizeOfStruct;
+ DWORD BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ WCHAR ModuleName[32];
+ WCHAR ImageName[256];
+ WCHAR LoadedImageName[256];
+ } IMAGEHLP_MODULEW,*PIMAGEHLP_MODULEW;
+#endif
+
+ typedef struct _IMAGEHLP_LINE64 {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD LineNumber;
+ PCHAR FileName;
+ DWORD64 Address;
+ } IMAGEHLP_LINE64,*PIMAGEHLP_LINE64;
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_LINE IMAGEHLP_LINE64
+#define PIMAGEHLP_LINE PIMAGEHLP_LINE64
+#else
+ typedef struct _IMAGEHLP_LINE {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD LineNumber;
+ PCHAR FileName;
+ DWORD Address;
+ } IMAGEHLP_LINE,*PIMAGEHLP_LINE;
+#endif
+
+ typedef struct _SOURCEFILE {
+ DWORD64 ModBase;
+ PCHAR FileName;
+ } SOURCEFILE,*PSOURCEFILE;
+
+#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001
+#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002
+#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003
+#define CBA_SYMBOLS_UNLOADED 0x00000004
+#define CBA_DUPLICATE_SYMBOL 0x00000005
+#define CBA_READ_MEMORY 0x00000006
+#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007
+#define CBA_SET_OPTIONS 0x00000008
+#define CBA_EVENT 0x00000010
+#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020
+#define CBA_DEBUG_INFO 0x10000000
+
+ typedef struct _IMAGEHLP_CBA_READ_MEMORY {
+ DWORD64 addr;
+ PVOID buf;
+ DWORD bytes;
+ DWORD *bytesread;
+ } IMAGEHLP_CBA_READ_MEMORY,*PIMAGEHLP_CBA_READ_MEMORY;
+
+ enum {
+ sevInfo = 0,sevProblem,sevAttn,sevFatal,sevMax
+ };
+
+ typedef struct _IMAGEHLP_CBA_EVENT {
+ DWORD severity;
+ DWORD code;
+ PCHAR desc;
+ PVOID object;
+ } IMAGEHLP_CBA_EVENT,*PIMAGEHLP_CBA_EVENT;
+
+ typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
+ DWORD SizeOfStruct;
+ DWORD64 BaseOfImage;
+ DWORD CheckSum;
+ DWORD TimeDateStamp;
+ CHAR FileName[MAX_PATH];
+ BOOLEAN Reparse;
+ HANDLE hFile;
+ DWORD Flags;
+ } IMAGEHLP_DEFERRED_SYMBOL_LOAD64,*PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
+
+#define DSLFLAG_MISMATCHED_PDB 0x1
+#define DSLFLAG_MISMATCHED_DBG 0x2
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#else
+ typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
+ DWORD SizeOfStruct;
+ DWORD BaseOfImage;
+ DWORD CheckSum;
+ DWORD TimeDateStamp;
+ CHAR FileName[MAX_PATH];
+ BOOLEAN Reparse;
+ HANDLE hFile;
+ } IMAGEHLP_DEFERRED_SYMBOL_LOAD,*PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
+#endif
+
+ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
+ DWORD SizeOfStruct;
+ DWORD NumberOfDups;
+ PIMAGEHLP_SYMBOL64 Symbol;
+ DWORD SelectedSymbol;
+ } IMAGEHLP_DUPLICATE_SYMBOL64,*PIMAGEHLP_DUPLICATE_SYMBOL64;
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64
+#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64
+#else
+ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
+ DWORD SizeOfStruct;
+ DWORD NumberOfDups;
+ PIMAGEHLP_SYMBOL Symbol;
+ DWORD SelectedSymbol;
+ } IMAGEHLP_DUPLICATE_SYMBOL,*PIMAGEHLP_DUPLICATE_SYMBOL;
+#endif
+
+ BOOL IMAGEAPI SymSetParentWindow(HWND hwnd);
+ PCHAR IMAGEAPI SymSetHomeDirectory(PCSTR dir);
+ PCHAR IMAGEAPI SymGetHomeDirectory(DWORD type,PSTR dir,size_t size);
+
+ enum {
+ hdBase = 0,hdSym,hdSrc,hdMax
+ };
+
+#define SYMOPT_CASE_INSENSITIVE 0x00000001
+#define SYMOPT_UNDNAME 0x00000002
+#define SYMOPT_DEFERRED_LOADS 0x00000004
+#define SYMOPT_NO_CPP 0x00000008
+#define SYMOPT_LOAD_LINES 0x00000010
+#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
+#define SYMOPT_LOAD_ANYTHING 0x00000040
+#define SYMOPT_IGNORE_CVREC 0x00000080
+#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
+#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
+#define SYMOPT_EXACT_SYMBOLS 0x00000400
+#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
+#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
+#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
+#define SYMOPT_PUBLICS_ONLY 0x00004000
+#define SYMOPT_NO_PUBLICS 0x00008000
+#define SYMOPT_AUTO_PUBLICS 0x00010000
+#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
+#define SYMOPT_SECURE 0x00040000
+#define SYMOPT_NO_PROMPTS 0x00080000
+
+#define SYMOPT_DEBUG 0x80000000
+
+ DWORD IMAGEAPI SymSetOptions(DWORD SymOptions);
+ DWORD IMAGEAPI SymGetOptions(VOID);
+ BOOL IMAGEAPI SymCleanup(HANDLE hProcess);
+ BOOL IMAGEAPI SymMatchString(LPSTR string,LPSTR expression,BOOL fCase);
+
+ typedef BOOL (CALLBACK *PSYM_ENUMSOURCFILES_CALLBACK)(PSOURCEFILE pSourceFile,PVOID UserContext);
+
+ BOOL IMAGEAPI SymEnumSourceFiles(HANDLE hProcess,ULONG64 ModBase,LPSTR Mask,PSYM_ENUMSOURCFILES_CALLBACK cbSrcFiles,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumerateModules64(HANDLE hProcess,PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,PVOID UserContext);
+
+#ifdef _IMAGEHLP64
+#define SymEnumerateModules SymEnumerateModules64
+#else
+ BOOL IMAGEAPI SymEnumerateModules(HANDLE hProcess,PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,PVOID UserContext);
+#endif
+
+ BOOL IMAGEAPI SymEnumerateSymbols64(HANDLE hProcess,DWORD64 BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumerateSymbolsW64(HANDLE hProcess,DWORD64 BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback,PVOID UserContext);
+
+#ifdef _IMAGEHLP64
+#define SymEnumerateSymbols SymEnumerateSymbols64
+#define SymEnumerateSymbolsW SymEnumerateSymbolsW64
+#else
+ BOOL IMAGEAPI SymEnumerateSymbols(HANDLE hProcess,DWORD BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumerateSymbolsW(HANDLE hProcess,DWORD BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback,PVOID UserContext);
+#endif
+
+ BOOL IMAGEAPI EnumerateLoadedModules64(HANDLE hProcess,PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,PVOID UserContext);
+#ifdef _IMAGEHLP64
+#define EnumerateLoadedModules EnumerateLoadedModules64
+#else
+ BOOL IMAGEAPI EnumerateLoadedModules(HANDLE hProcess,PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,PVOID UserContext);
+#endif
+
+ PVOID IMAGEAPI SymFunctionTableAccess64(HANDLE hProcess,DWORD64 AddrBase);
+
+#ifdef _IMAGEHLP64
+#define SymFunctionTableAccess SymFunctionTableAccess64
+#else
+ PVOID IMAGEAPI SymFunctionTableAccess(HANDLE hProcess,DWORD AddrBase);
+#endif
+
+ BOOL IMAGEAPI SymGetModuleInfo64(HANDLE hProcess,DWORD64 qwAddr,PIMAGEHLP_MODULE64 ModuleInfo);
+ BOOL IMAGEAPI SymGetModuleInfoW64(HANDLE hProcess,DWORD64 qwAddr,PIMAGEHLP_MODULEW64 ModuleInfo);
+
+#ifdef _IMAGEHLP64
+#define SymGetModuleInfo SymGetModuleInfo64
+#define SymGetModuleInfoW SymGetModuleInfoW64
+#else
+ BOOL IMAGEAPI SymGetModuleInfo(HANDLE hProcess,DWORD dwAddr,PIMAGEHLP_MODULE ModuleInfo);
+ BOOL IMAGEAPI SymGetModuleInfoW(HANDLE hProcess,DWORD dwAddr,PIMAGEHLP_MODULEW ModuleInfo);
+#endif
+
+ DWORD64 IMAGEAPI SymGetModuleBase64(HANDLE hProcess,DWORD64 qwAddr);
+
+#ifdef _IMAGEHLP64
+#define SymGetModuleBase SymGetModuleBase64
+#else
+ DWORD IMAGEAPI SymGetModuleBase(HANDLE hProcess,DWORD dwAddr);
+#endif
+
+ BOOL IMAGEAPI SymGetSymNext64(HANDLE hProcess,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymNext SymGetSymNext64
+#else
+ BOOL IMAGEAPI SymGetSymNext(HANDLE hProcess,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ BOOL IMAGEAPI SymGetSymPrev64(HANDLE hProcess,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymPrev SymGetSymPrev64
+#else
+ BOOL IMAGEAPI SymGetSymPrev(HANDLE hProcess,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ typedef struct _SRCCODEINFO {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD64 ModBase;
+ CHAR Obj[MAX_PATH + 1];
+ CHAR FileName[MAX_PATH + 1];
+ DWORD LineNumber;
+ DWORD64 Address;
+ } SRCCODEINFO,*PSRCCODEINFO;
+
+ typedef BOOL (CALLBACK *PSYM_ENUMLINES_CALLBACK)(PSRCCODEINFO LineInfo,PVOID UserContext);
+
+ BOOL IMAGEAPI SymEnumLines(HANDLE hProcess,ULONG64 Base,PCSTR Obj,PCSTR File,PSYM_ENUMLINES_CALLBACK EnumLinesCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymGetLineFromAddr64(HANDLE hProcess,DWORD64 qwAddr,PDWORD pdwDisplacement,PIMAGEHLP_LINE64 Line64);
+
+#ifdef _IMAGEHLP64
+#define SymGetLineFromAddr SymGetLineFromAddr64
+#else
+ BOOL IMAGEAPI SymGetLineFromAddr(HANDLE hProcess,DWORD dwAddr,PDWORD pdwDisplacement,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymGetLineFromName64(HANDLE hProcess,PSTR ModuleName,PSTR FileName,DWORD dwLineNumber,PLONG plDisplacement,PIMAGEHLP_LINE64 Line);
+
+#ifdef _IMAGEHLP64
+#define SymGetLineFromName SymGetLineFromName64
+#else
+ BOOL IMAGEAPI SymGetLineFromName(HANDLE hProcess,PSTR ModuleName,PSTR FileName,DWORD dwLineNumber,PLONG plDisplacement,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymGetLineNext64(HANDLE hProcess,PIMAGEHLP_LINE64 Line);
+
+#ifdef _IMAGEHLP64
+#define SymGetLineNext SymGetLineNext64
+#else
+ BOOL IMAGEAPI SymGetLineNext(HANDLE hProcess,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymGetLinePrev64(HANDLE hProcess,PIMAGEHLP_LINE64 Line);
+
+#ifdef _IMAGEHLP64
+#define SymGetLinePrev SymGetLinePrev64
+#else
+ BOOL IMAGEAPI SymGetLinePrev(HANDLE hProcess,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymMatchFileName(PSTR FileName,PSTR Match,PSTR *FileNameStop,PSTR *MatchStop);
+ BOOL IMAGEAPI SymInitialize(HANDLE hProcess,PSTR UserSearchPath,BOOL fInvadeProcess);
+ BOOL IMAGEAPI SymGetSearchPath(HANDLE hProcess,PSTR SearchPath,DWORD SearchPathLength);
+ BOOL IMAGEAPI SymSetSearchPath(HANDLE hProcess,PSTR SearchPath);
+ DWORD64 IMAGEAPI SymLoadModule64(HANDLE hProcess,HANDLE hFile,PSTR ImageName,PSTR ModuleName,DWORD64 BaseOfDll,DWORD SizeOfDll);
+
+#define SLMFLAG_VIRTUAL 0x1
+
+ DWORD64 IMAGEAPI SymLoadModuleEx(HANDLE hProcess,HANDLE hFile,PSTR ImageName,PSTR ModuleName,DWORD64 BaseOfDll,DWORD DllSize,PMODLOAD_DATA Data,DWORD Flags);
+
+#ifdef _IMAGEHLP64
+#define SymLoadModule SymLoadModule64
+#else
+ DWORD IMAGEAPI SymLoadModule(HANDLE hProcess,HANDLE hFile,PSTR ImageName,PSTR ModuleName,DWORD BaseOfDll,DWORD SizeOfDll);
+#endif
+
+ BOOL IMAGEAPI SymUnloadModule64(HANDLE hProcess,DWORD64 BaseOfDll);
+
+#ifdef _IMAGEHLP64
+#define SymUnloadModule SymUnloadModule64
+#else
+ BOOL IMAGEAPI SymUnloadModule(HANDLE hProcess,DWORD BaseOfDll);
+#endif
+
+ BOOL IMAGEAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym,PSTR UnDecName,DWORD UnDecNameLength);
+
+#ifdef _IMAGEHLP64
+#define SymUnDName SymUnDName64
+#else
+ BOOL IMAGEAPI SymUnDName(PIMAGEHLP_SYMBOL sym,PSTR UnDecName,DWORD UnDecNameLength);
+#endif
+
+ BOOL IMAGEAPI SymRegisterCallback64(HANDLE hProcess,PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,ULONG64 UserContext);
+
+ BOOL IMAGEAPI SymRegisterFunctionEntryCallback64(HANDLE hProcess,PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction,ULONG64 UserContext);
+
+#ifdef _IMAGEHLP64
+#define SymRegisterCallback SymRegisterCallback64
+#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64
+#else
+ BOOL IMAGEAPI SymRegisterCallback(HANDLE hProcess,PSYMBOL_REGISTERED_CALLBACK CallbackFunction,PVOID UserContext);
+ BOOL IMAGEAPI SymRegisterFunctionEntryCallback(HANDLE hProcess,PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction,PVOID UserContext);
+#endif
+
+ typedef struct _IMAGEHLP_SYMBOL_SRC {
+ DWORD sizeofstruct;
+ DWORD type;
+ char file[MAX_PATH];
+ } IMAGEHLP_SYMBOL_SRC,*PIMAGEHLP_SYMBOL_SRC;
+
+ typedef struct _MODULE_TYPE_INFO {
+ USHORT dataLength;
+ USHORT leaf;
+ BYTE data[1];
+ } MODULE_TYPE_INFO,*PMODULE_TYPE_INFO;
+
+ typedef struct _SYMBOL_INFO {
+ ULONG SizeOfStruct;
+ ULONG TypeIndex;
+ ULONG64 Reserved[2];
+ ULONG info;
+ ULONG Size;
+ ULONG64 ModBase;
+ ULONG Flags;
+ ULONG64 Value;
+ ULONG64 Address;
+ ULONG Register;
+ ULONG Scope;
+ ULONG Tag;
+ ULONG NameLen;
+ ULONG MaxNameLen;
+ CHAR Name[1];
+ } SYMBOL_INFO,*PSYMBOL_INFO;
+
+ typedef struct _SYMBOL_INFO_PACKAGE {
+ SYMBOL_INFO si;
+ CHAR name[MAX_SYM_NAME + 1];
+ } SYMBOL_INFO_PACKAGE,*PSYMBOL_INFO_PACKAGE;
+
+ typedef struct _IMAGEHLP_STACK_FRAME
+ {
+ ULONG64 InstructionOffset;
+ ULONG64 ReturnOffset;
+ ULONG64 FrameOffset;
+ ULONG64 StackOffset;
+ ULONG64 BackingStoreOffset;
+ ULONG64 FuncTableEntry;
+ ULONG64 Params[4];
+ ULONG64 Reserved[5];
+ BOOL Virtual;
+ ULONG Reserved2;
+ } IMAGEHLP_STACK_FRAME,*PIMAGEHLP_STACK_FRAME;
+
+ typedef VOID IMAGEHLP_CONTEXT,*PIMAGEHLP_CONTEXT;
+
+ BOOL IMAGEAPI SymSetContext(HANDLE hProcess,PIMAGEHLP_STACK_FRAME StackFrame,PIMAGEHLP_CONTEXT Context);
+ BOOL IMAGEAPI SymFromAddr(HANDLE hProcess,DWORD64 Address,PDWORD64 Displacement,PSYMBOL_INFO Symbol);
+ BOOL IMAGEAPI SymFromToken(HANDLE hProcess,DWORD64 Base,DWORD Token,PSYMBOL_INFO Symbol);
+ BOOL IMAGEAPI SymFromName(HANDLE hProcess,LPSTR Name,PSYMBOL_INFO Symbol);
+
+ typedef BOOL (CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO pSymInfo,ULONG SymbolSize,PVOID UserContext);
+
+ BOOL IMAGEAPI SymEnumSymbols(HANDLE hProcess,ULONG64 BaseOfDll,PCSTR Mask,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumSymbolsForAddr(HANDLE hProcess,DWORD64 Address,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+
+#define SYMENUMFLAG_FULLSRCH 1
+#define SYMENUMFLAG_SPEEDSRCH 2
+
+ typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO {
+ TI_GET_SYMTAG,TI_GET_SYMNAME,TI_GET_LENGTH,TI_GET_TYPE,TI_GET_TYPEID,TI_GET_BASETYPE,TI_GET_ARRAYINDEXTYPEID,TI_FINDCHILDREN,
+ TI_GET_DATAKIND,TI_GET_ADDRESSOFFSET,TI_GET_OFFSET,TI_GET_VALUE,TI_GET_COUNT,TI_GET_CHILDRENCOUNT,TI_GET_BITPOSITION,TI_GET_VIRTUALBASECLASS,
+ TI_GET_VIRTUALTABLESHAPEID,TI_GET_VIRTUALBASEPOINTEROFFSET,TI_GET_CLASSPARENTID,TI_GET_NESTED,TI_GET_SYMINDEX,TI_GET_LEXICALPARENT,
+ TI_GET_ADDRESS,TI_GET_THISADJUST,TI_GET_UDTKIND,TI_IS_EQUIV_TO,TI_GET_CALLING_CONVENTION
+ } IMAGEHLP_SYMBOL_TYPE_INFO;
+
+ typedef struct _TI_FINDCHILDREN_PARAMS {
+ ULONG Count;
+ ULONG Start;
+ ULONG ChildId[1];
+ } TI_FINDCHILDREN_PARAMS;
+
+ BOOL IMAGEAPI SymGetTypeInfo(HANDLE hProcess,DWORD64 ModBase,ULONG TypeId,IMAGEHLP_SYMBOL_TYPE_INFO GetType,PVOID pInfo);
+ BOOL IMAGEAPI SymEnumTypes(HANDLE hProcess,ULONG64 BaseOfDll,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymGetTypeFromName(HANDLE hProcess,ULONG64 BaseOfDll,LPSTR Name,PSYMBOL_INFO Symbol);
+ BOOL IMAGEAPI SymAddSymbol(HANDLE hProcess,ULONG64 BaseOfDll,PCSTR Name,DWORD64 Address,DWORD Size,DWORD Flags);
+ BOOL IMAGEAPI SymDeleteSymbol(HANDLE hProcess,ULONG64 BaseOfDll,PCSTR Name,DWORD64 Address,DWORD Flags);
+
+ typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)(DWORD DataType,PVOID *Data,LPDWORD DataLength,PVOID UserData);
+
+ BOOL WINAPI DbgHelpCreateUserDump(LPSTR FileName,PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,PVOID UserData);
+ BOOL WINAPI DbgHelpCreateUserDumpW(LPWSTR FileName,PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,PVOID UserData);
+ BOOL IMAGEAPI SymGetSymFromAddr64(HANDLE hProcess,DWORD64 qwAddr,PDWORD64 pdwDisplacement,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymFromAddr SymGetSymFromAddr64
+#else
+ BOOL IMAGEAPI SymGetSymFromAddr(HANDLE hProcess,DWORD dwAddr,PDWORD pdwDisplacement,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ BOOL IMAGEAPI SymGetSymFromName64(HANDLE hProcess,PSTR Name,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymFromName SymGetSymFromName64
+#else
+ BOOL IMAGEAPI SymGetSymFromName(HANDLE hProcess,PSTR Name,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ DBHLP_DEPRECIATED BOOL IMAGEAPI FindFileInPath(HANDLE hprocess,LPSTR SearchPath,LPSTR FileName,PVOID id,DWORD two,DWORD three,DWORD flags,LPSTR FilePath);
+ DBHLP_DEPRECIATED BOOL IMAGEAPI FindFileInSearchPath(HANDLE hprocess,LPSTR SearchPath,LPSTR FileName,DWORD one,DWORD two,DWORD three,LPSTR FilePath);
+ DBHLP_DEPRECIATED BOOL IMAGEAPI SymEnumSym(HANDLE hProcess,ULONG64 BaseOfDll,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+
+#define SYMF_OMAP_GENERATED 0x00000001
+#define SYMF_OMAP_MODIFIED 0x00000002
+#define SYMF_REGISTER 0x00000008
+#define SYMF_REGREL 0x00000010
+#define SYMF_FRAMEREL 0x00000020
+#define SYMF_PARAMETER 0x00000040
+#define SYMF_LOCAL 0x00000080
+#define SYMF_CONSTANT 0x00000100
+#define SYMF_EXPORT 0x00000200
+#define SYMF_FORWARDER 0x00000400
+#define SYMF_FUNCTION 0x00000800
+#define SYMF_VIRTUAL 0x00001000
+#define SYMF_THUNK 0x00002000
+#define SYMF_TLSREL 0x00004000
+
+#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1
+#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER
+#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL
+#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL
+#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER
+#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL
+#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT
+#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION
+#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL
+#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK
+#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL
+
+#include <pshpack4.h>
+
+#define MINIDUMP_SIGNATURE ('PMDM')
+#define MINIDUMP_VERSION (42899)
+ typedef DWORD RVA;
+ typedef ULONG64 RVA64;
+
+ typedef struct _MINIDUMP_LOCATION_DESCRIPTOR {
+ ULONG32 DataSize;
+ RVA Rva;
+ } MINIDUMP_LOCATION_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 {
+ ULONG64 DataSize;
+ RVA64 Rva;
+ } MINIDUMP_LOCATION_DESCRIPTOR64;
+
+ typedef struct _MINIDUMP_MEMORY_DESCRIPTOR {
+ ULONG64 StartOfMemoryRange;
+ MINIDUMP_LOCATION_DESCRIPTOR Memory;
+ } MINIDUMP_MEMORY_DESCRIPTOR,*PMINIDUMP_MEMORY_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 {
+ ULONG64 StartOfMemoryRange;
+ ULONG64 DataSize;
+ } MINIDUMP_MEMORY_DESCRIPTOR64,*PMINIDUMP_MEMORY_DESCRIPTOR64;
+
+ typedef struct _MINIDUMP_HEADER {
+ ULONG32 Signature;
+ ULONG32 Version;
+ ULONG32 NumberOfStreams;
+ RVA StreamDirectoryRva;
+ ULONG32 CheckSum;
+ union {
+ ULONG32 Reserved;
+ ULONG32 TimeDateStamp;
+ } DUMMYUNIONNAME;
+ ULONG64 Flags;
+ } MINIDUMP_HEADER,*PMINIDUMP_HEADER;
+
+ typedef struct _MINIDUMP_DIRECTORY {
+ ULONG32 StreamType;
+ MINIDUMP_LOCATION_DESCRIPTOR Location;
+ } MINIDUMP_DIRECTORY,*PMINIDUMP_DIRECTORY;
+
+ typedef struct _MINIDUMP_STRING {
+ ULONG32 Length;
+ WCHAR Buffer [0];
+ } MINIDUMP_STRING,*PMINIDUMP_STRING;
+
+ typedef enum _MINIDUMP_STREAM_TYPE {
+ UnusedStream = 0,ReservedStream0 = 1,ReservedStream1 = 2,ThreadListStream = 3,ModuleListStream = 4,MemoryListStream = 5,
+ ExceptionStream = 6,SystemInfoStream = 7,ThreadExListStream = 8,Memory64ListStream = 9,CommentStreamA = 10,CommentStreamW = 11,
+ HandleDataStream = 12,FunctionTableStream = 13,UnloadedModuleListStream = 14,MiscInfoStream = 15,LastReservedStream = 0xffff
+ } MINIDUMP_STREAM_TYPE;
+
+ typedef union _CPU_INFORMATION {
+ struct {
+ ULONG32 VendorId [3 ];
+ ULONG32 VersionInformation;
+ ULONG32 FeatureInformation;
+ ULONG32 AMDExtendedCpuFeatures;
+ } X86CpuInfo;
+ struct {
+ ULONG64 ProcessorFeatures [2 ];
+ } OtherCpuInfo;
+ } CPU_INFORMATION,*PCPU_INFORMATION;
+
+ typedef struct _MINIDUMP_SYSTEM_INFO {
+ USHORT ProcessorArchitecture;
+ USHORT ProcessorLevel;
+ USHORT ProcessorRevision;
+ union {
+ USHORT Reserved0;
+ struct {
+ UCHAR NumberOfProcessors;
+ UCHAR ProductType;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+ ULONG32 MajorVersion;
+ ULONG32 MinorVersion;
+ ULONG32 BuildNumber;
+ ULONG32 PlatformId;
+ RVA CSDVersionRva;
+ union {
+ ULONG32 Reserved1;
+ struct {
+ USHORT SuiteMask;
+ USHORT Reserved2;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME1;
+ CPU_INFORMATION Cpu;
+ } MINIDUMP_SYSTEM_INFO,*PMINIDUMP_SYSTEM_INFO;
+
+ C_ASSERT (sizeof (((PPROCESS_INFORMATION)0)->dwThreadId)==4);
+
+ typedef struct _MINIDUMP_THREAD {
+ ULONG32 ThreadId;
+ ULONG32 SuspendCount;
+ ULONG32 PriorityClass;
+ ULONG32 Priority;
+ ULONG64 Teb;
+ MINIDUMP_MEMORY_DESCRIPTOR Stack;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ } MINIDUMP_THREAD,*PMINIDUMP_THREAD;
+
+ typedef struct _MINIDUMP_THREAD_LIST {
+ ULONG32 NumberOfThreads;
+ MINIDUMP_THREAD Threads [0];
+ } MINIDUMP_THREAD_LIST,*PMINIDUMP_THREAD_LIST;
+
+ typedef struct _MINIDUMP_THREAD_EX {
+ ULONG32 ThreadId;
+ ULONG32 SuspendCount;
+ ULONG32 PriorityClass;
+ ULONG32 Priority;
+ ULONG64 Teb;
+ MINIDUMP_MEMORY_DESCRIPTOR Stack;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
+ } MINIDUMP_THREAD_EX,*PMINIDUMP_THREAD_EX;
+
+ typedef struct _MINIDUMP_THREAD_EX_LIST {
+ ULONG32 NumberOfThreads;
+ MINIDUMP_THREAD_EX Threads [0];
+ } MINIDUMP_THREAD_EX_LIST,*PMINIDUMP_THREAD_EX_LIST;
+
+ typedef struct _MINIDUMP_EXCEPTION {
+ ULONG32 ExceptionCode;
+ ULONG32 ExceptionFlags;
+ ULONG64 ExceptionRecord;
+ ULONG64 ExceptionAddress;
+ ULONG32 NumberParameters;
+ ULONG32 __unusedAlignment;
+ ULONG64 ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS ];
+ } MINIDUMP_EXCEPTION,*PMINIDUMP_EXCEPTION;
+
+ typedef struct MINIDUMP_EXCEPTION_STREAM {
+ ULONG32 ThreadId;
+ ULONG32 __alignment;
+ MINIDUMP_EXCEPTION ExceptionRecord;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ } MINIDUMP_EXCEPTION_STREAM,*PMINIDUMP_EXCEPTION_STREAM;
+
+ typedef struct _MINIDUMP_MODULE {
+ ULONG64 BaseOfImage;
+ ULONG32 SizeOfImage;
+ ULONG32 CheckSum;
+ ULONG32 TimeDateStamp;
+ RVA ModuleNameRva;
+ VS_FIXEDFILEINFO VersionInfo;
+ MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
+ MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
+ ULONG64 Reserved0;
+ ULONG64 Reserved1;
+ } MINIDUMP_MODULE,*PMINIDUMP_MODULE;
+
+ typedef struct _MINIDUMP_MODULE_LIST {
+ ULONG32 NumberOfModules;
+ MINIDUMP_MODULE Modules [0 ];
+ } MINIDUMP_MODULE_LIST,*PMINIDUMP_MODULE_LIST;
+
+ typedef struct _MINIDUMP_MEMORY_LIST {
+ ULONG32 NumberOfMemoryRanges;
+ MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0];
+ } MINIDUMP_MEMORY_LIST,*PMINIDUMP_MEMORY_LIST;
+
+ typedef struct _MINIDUMP_MEMORY64_LIST {
+ ULONG64 NumberOfMemoryRanges;
+ RVA64 BaseRva;
+ MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0];
+ } MINIDUMP_MEMORY64_LIST,*PMINIDUMP_MEMORY64_LIST;
+
+ typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
+ DWORD ThreadId;
+ PEXCEPTION_POINTERS ExceptionPointers;
+ BOOL ClientPointers;
+ } MINIDUMP_EXCEPTION_INFORMATION,*PMINIDUMP_EXCEPTION_INFORMATION;
+
+ typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 {
+ DWORD ThreadId;
+ ULONG64 ExceptionRecord;
+ ULONG64 ContextRecord;
+ BOOL ClientPointers;
+ } MINIDUMP_EXCEPTION_INFORMATION64,*PMINIDUMP_EXCEPTION_INFORMATION64;
+
+ typedef struct _MINIDUMP_HANDLE_DESCRIPTOR {
+ ULONG64 Handle;
+ RVA TypeNameRva;
+ RVA ObjectNameRva;
+ ULONG32 Attributes;
+ ULONG32 GrantedAccess;
+ ULONG32 HandleCount;
+ ULONG32 PointerCount;
+ } MINIDUMP_HANDLE_DESCRIPTOR,*PMINIDUMP_HANDLE_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_HANDLE_DATA_STREAM {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfDescriptor;
+ ULONG32 NumberOfDescriptors;
+ ULONG32 Reserved;
+ } MINIDUMP_HANDLE_DATA_STREAM,*PMINIDUMP_HANDLE_DATA_STREAM;
+
+ typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
+ ULONG64 MinimumAddress;
+ ULONG64 MaximumAddress;
+ ULONG64 BaseAddress;
+ ULONG32 EntryCount;
+ ULONG32 SizeOfAlignPad;
+ } MINIDUMP_FUNCTION_TABLE_DESCRIPTOR,*PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfDescriptor;
+ ULONG32 SizeOfNativeDescriptor;
+ ULONG32 SizeOfFunctionEntry;
+ ULONG32 NumberOfDescriptors;
+ ULONG32 SizeOfAlignPad;
+ } MINIDUMP_FUNCTION_TABLE_STREAM,*PMINIDUMP_FUNCTION_TABLE_STREAM;
+
+ typedef struct _MINIDUMP_UNLOADED_MODULE {
+ ULONG64 BaseOfImage;
+ ULONG32 SizeOfImage;
+ ULONG32 CheckSum;
+ ULONG32 TimeDateStamp;
+ RVA ModuleNameRva;
+ } MINIDUMP_UNLOADED_MODULE,*PMINIDUMP_UNLOADED_MODULE;
+
+ typedef struct _MINIDUMP_UNLOADED_MODULE_LIST {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfEntry;
+ ULONG32 NumberOfEntries;
+ } MINIDUMP_UNLOADED_MODULE_LIST,*PMINIDUMP_UNLOADED_MODULE_LIST;
+
+#define MINIDUMP_MISC1_PROCESS_ID 0x00000001
+#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002
+
+ typedef struct _MINIDUMP_MISC_INFO {
+ ULONG32 SizeOfInfo;
+ ULONG32 Flags1;
+ ULONG32 ProcessId;
+ ULONG32 ProcessCreateTime;
+ ULONG32 ProcessUserTime;
+ ULONG32 ProcessKernelTime;
+ } MINIDUMP_MISC_INFO,*PMINIDUMP_MISC_INFO;
+
+ typedef struct _MINIDUMP_USER_RECORD {
+ ULONG32 Type;
+ MINIDUMP_LOCATION_DESCRIPTOR Memory;
+ } MINIDUMP_USER_RECORD,*PMINIDUMP_USER_RECORD;
+
+ typedef struct _MINIDUMP_USER_STREAM {
+ ULONG32 Type;
+ ULONG BufferSize;
+ PVOID Buffer;
+ } MINIDUMP_USER_STREAM,*PMINIDUMP_USER_STREAM;
+
+ typedef struct _MINIDUMP_USER_STREAM_INFORMATION {
+ ULONG UserStreamCount;
+ PMINIDUMP_USER_STREAM UserStreamArray;
+ } MINIDUMP_USER_STREAM_INFORMATION,*PMINIDUMP_USER_STREAM_INFORMATION;
+
+ typedef enum _MINIDUMP_CALLBACK_TYPE {
+ ModuleCallback,ThreadCallback,ThreadExCallback,IncludeThreadCallback,IncludeModuleCallback,MemoryCallback
+ } MINIDUMP_CALLBACK_TYPE;
+
+ typedef struct _MINIDUMP_THREAD_CALLBACK {
+ ULONG ThreadId;
+ HANDLE ThreadHandle;
+ CONTEXT Context;
+ ULONG SizeOfContext;
+ ULONG64 StackBase;
+ ULONG64 StackEnd;
+ } MINIDUMP_THREAD_CALLBACK,*PMINIDUMP_THREAD_CALLBACK;
+
+ typedef struct _MINIDUMP_THREAD_EX_CALLBACK {
+ ULONG ThreadId;
+ HANDLE ThreadHandle;
+ CONTEXT Context;
+ ULONG SizeOfContext;
+ ULONG64 StackBase;
+ ULONG64 StackEnd;
+ ULONG64 BackingStoreBase;
+ ULONG64 BackingStoreEnd;
+ } MINIDUMP_THREAD_EX_CALLBACK,*PMINIDUMP_THREAD_EX_CALLBACK;
+
+ typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK {
+ ULONG ThreadId;
+ } MINIDUMP_INCLUDE_THREAD_CALLBACK,*PMINIDUMP_INCLUDE_THREAD_CALLBACK;
+
+ typedef enum _THREAD_WRITE_FLAGS {
+ ThreadWriteThread = 0x0001,ThreadWriteStack = 0x0002,ThreadWriteContext = 0x0004,ThreadWriteBackingStore = 0x0008,
+ ThreadWriteInstructionWindow = 0x0010,ThreadWriteThreadData = 0x0020
+ } THREAD_WRITE_FLAGS;
+
+ typedef struct _MINIDUMP_MODULE_CALLBACK {
+ PWCHAR FullPath;
+ ULONG64 BaseOfImage;
+ ULONG SizeOfImage;
+ ULONG CheckSum;
+ ULONG TimeDateStamp;
+ VS_FIXEDFILEINFO VersionInfo;
+ PVOID CvRecord;
+ ULONG SizeOfCvRecord;
+ PVOID MiscRecord;
+ ULONG SizeOfMiscRecord;
+ } MINIDUMP_MODULE_CALLBACK,*PMINIDUMP_MODULE_CALLBACK;
+
+ typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK {
+ ULONG64 BaseOfImage;
+ } MINIDUMP_INCLUDE_MODULE_CALLBACK,*PMINIDUMP_INCLUDE_MODULE_CALLBACK;
+
+ typedef enum _MODULE_WRITE_FLAGS {
+ ModuleWriteModule = 0x0001,ModuleWriteDataSeg = 0x0002,ModuleWriteMiscRecord = 0x0004,ModuleWriteCvRecord = 0x0008,
+ ModuleReferencedByMemory = 0x0010
+ } MODULE_WRITE_FLAGS;
+
+ typedef struct _MINIDUMP_CALLBACK_INPUT {
+ ULONG ProcessId;
+ HANDLE ProcessHandle;
+ ULONG CallbackType;
+ union {
+ MINIDUMP_THREAD_CALLBACK Thread;
+ MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
+ MINIDUMP_MODULE_CALLBACK Module;
+ MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
+ MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
+ } DUMMYUNIONNAME;
+ } MINIDUMP_CALLBACK_INPUT,*PMINIDUMP_CALLBACK_INPUT;
+
+ typedef struct _MINIDUMP_CALLBACK_OUTPUT {
+ union {
+ ULONG ModuleWriteFlags;
+ ULONG ThreadWriteFlags;
+ struct {
+ ULONG64 MemoryBase;
+ ULONG MemorySize;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+ } MINIDUMP_CALLBACK_OUTPUT,*PMINIDUMP_CALLBACK_OUTPUT;
+
+ typedef enum _MINIDUMP_TYPE {
+ MiniDumpNormal = 0x0000,MiniDumpWithDataSegs = 0x0001,MiniDumpWithFullMemory = 0x0002,MiniDumpWithHandleData = 0x0004,
+ MiniDumpFilterMemory = 0x0008,MiniDumpScanMemory = 0x0010,MiniDumpWithUnloadedModules = 0x0020,MiniDumpWithIndirectlyReferencedMemory = 0x0040,
+ MiniDumpFilterModulePaths = 0x0080,MiniDumpWithProcessThreadData = 0x0100,MiniDumpWithPrivateReadWriteMemory = 0x0200,
+ MiniDumpWithoutOptionalData = 0x0400
+ } MINIDUMP_TYPE;
+
+ typedef BOOL (WINAPI *MINIDUMP_CALLBACK_ROUTINE)(PVOID CallbackParam,CONST PMINIDUMP_CALLBACK_INPUT CallbackInput,PMINIDUMP_CALLBACK_OUTPUT CallbackOutput);
+
+ typedef struct _MINIDUMP_CALLBACK_INFORMATION {
+ MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
+ PVOID CallbackParam;
+ } MINIDUMP_CALLBACK_INFORMATION,*PMINIDUMP_CALLBACK_INFORMATION;
+
+#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva)))
+
+ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess,DWORD ProcessId,HANDLE hFile,MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
+ BOOL WINAPI MiniDumpReadDumpStream(PVOID BaseOfDump,ULONG StreamNumber,PMINIDUMP_DIRECTORY *Dir,PVOID *StreamPointer,ULONG *StreamSize);
+
+#include <poppack.h>
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index c11f7d383db..76bd7ace526 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -199,6 +199,7 @@ get_next_slot( struct blit_state *ctx )
if (!ctx->vbuf) {
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
max_slots * sizeof ctx->vertices);
}
@@ -480,6 +481,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
+ cso_save_vertex_buffers(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
@@ -554,7 +556,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
s1, t1,
z);
- util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, offset,
+ util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
@@ -571,6 +573,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
+ cso_restore_vertex_buffers(ctx->cso);
pipe_sampler_view_reference(&sampler_view, NULL);
}
@@ -672,6 +675,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
+ cso_save_vertex_buffers(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
@@ -722,7 +726,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
s0, t0, s1, t1,
z);
- util_draw_vertex_buffer(ctx->pipe,
+ util_draw_vertex_buffer(ctx->pipe, ctx->cso,
ctx->vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -740,4 +744,5 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
+ cso_restore_vertex_buffers(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 545021d2642..fd1c2b72d04 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -86,7 +86,6 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
void *dsa_keep_depth_write_stencil;
- void *dsa_flush_depth_stencil;
void *velem_state;
@@ -156,10 +155,6 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
- dsa.depth.writemask = 1;
- ctx->dsa_flush_depth_stencil =
- pipe->create_depth_stencil_alpha_state(pipe, &dsa);
-
dsa.depth.enabled = 1;
dsa.depth.writemask = 1;
dsa.depth.func = PIPE_FUNC_ALWAYS;
@@ -225,9 +220,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->vertices[i][0][3] = 1; /*v.w*/
/* create the vertex buffer */
- ctx->vbuf = pipe_buffer_create(ctx->base.pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- sizeof(ctx->vertices));
+ ctx->vbuf = pipe_user_buffer_create(ctx->base.pipe->screen,
+ ctx->vertices,
+ sizeof(ctx->vertices),
+ PIPE_BIND_VERTEX_BUFFER);
return &ctx->base;
}
@@ -245,7 +241,6 @@ void util_blitter_destroy(struct blitter_context *blitter)
ctx->dsa_write_depth_keep_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
- pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_flush_depth_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs);
@@ -272,6 +267,12 @@ void util_blitter_destroy(struct blitter_context *blitter)
static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
{
+ if (ctx->base.running) {
+ _debug_printf("u_blitter: Caught recursion on save. "
+ "This is a driver bug.\n");
+ }
+ ctx->base.running = TRUE;
+
/* make sure these CSOs have been saved */
assert(ctx->base.saved_blend_state != INVALID_PTR &&
ctx->base.saved_dsa_state != INVALID_PTR &&
@@ -302,7 +303,6 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
ctx->base.saved_velem_state = INVALID_PTR;
pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
-
pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
pipe->set_clip_state(pipe, &ctx->base.saved_clip);
@@ -346,6 +346,12 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
}
ctx->base.saved_num_vertex_buffers = ~0;
}
+
+ if (!ctx->base.running) {
+ _debug_printf("u_blitter: Caught recursion on restore. "
+ "This is a driver bug.\n");
+ }
+ ctx->base.running = FALSE;
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
@@ -509,22 +515,6 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
ctx->dst_height = height;
}
-static void blitter_draw_quad(struct blitter_context_priv *ctx)
-{
- struct pipe_context *pipe = ctx->base.pipe;
- struct pipe_box box;
-
- /* write vertices and draw them */
- u_box_1d(0, sizeof(ctx->vertices), &box);
- pipe->transfer_inline_write(pipe, ctx->vbuf, 0,
- PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
- &box, ctx->vertices, sizeof(ctx->vertices), 0);
-
- util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-}
-
static INLINE
void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
int miplevel, boolean normalized)
@@ -649,15 +639,19 @@ static void blitter_draw_rectangle(struct blitter_context *blitter,
}
blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
- blitter_draw_quad(ctx);
+ ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
+ 0, ctx->vbuf->width0);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
}
-void util_blitter_clear(struct blitter_context *blitter,
- unsigned width, unsigned height,
- unsigned num_cbufs,
- unsigned clear_buffers,
- const float *rgba,
- double depth, unsigned stencil)
+static void util_blitter_clear_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil,
+ void *custom_blend, void *custom_dsa)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
@@ -668,26 +662,28 @@ void util_blitter_clear(struct blitter_context *blitter,
blitter_check_saved_CSOs(ctx);
/* bind CSOs */
- if (clear_buffers & PIPE_CLEAR_COLOR)
+ if (custom_blend) {
+ pipe->bind_blend_state(pipe, custom_blend);
+ } else if (clear_buffers & PIPE_CLEAR_COLOR) {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
- else
+ } else {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+ }
- if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
- sr.ref_value[0] = stencil & 0xff;
+ if (custom_dsa) {
+ pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
+ } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
- pipe->set_stencil_ref(pipe, &sr);
- }
- else if (clear_buffers & PIPE_CLEAR_DEPTH) {
+ } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
- }
- else if (clear_buffers & PIPE_CLEAR_STENCIL) {
- sr.ref_value[0] = stencil & 0xff;
+ } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
- pipe->set_stencil_ref(pipe, &sr);
- }
- else
+ } else {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+ }
+
+ sr.ref_value[0] = stencil & 0xff;
+ pipe->set_stencil_ref(pipe, &sr);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
@@ -700,6 +696,27 @@ void util_blitter_clear(struct blitter_context *blitter,
blitter_restore_CSOs(ctx);
}
+void util_blitter_clear(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil)
+{
+ util_blitter_clear_custom(blitter, width, height, num_cbufs,
+ clear_buffers, rgba, depth, stencil,
+ NULL, NULL);
+}
+
+void util_blitter_clear_depth_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ double depth, void *custom_dsa)
+{
+ const float rgba[4] = {0, 0, 0, 0};
+ util_blitter_clear_custom(blitter, width, height, 0,
+ 0, rgba, depth, 0, NULL, custom_dsa);
+}
+
static
boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2)
@@ -737,9 +754,6 @@ void util_blitter_copy_region(struct blitter_context *blitter,
if (dst == src) {
assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
dstx, dstx + width, dsty, dsty + height));
- } else {
- assert(util_is_format_compatible(util_format_description(src->format),
- util_format_description(dst->format)));
}
assert(src->target < PIPE_MAX_TEXTURE_TYPES);
/* XXX should handle 3d regions */
@@ -761,8 +775,10 @@ void util_blitter_copy_region(struct blitter_context *blitter,
dst->nr_samples, bind, 0) ||
!screen->is_format_supported(screen, src->format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
+ ctx->base.running = TRUE;
util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
src, srclevel, srcbox);
+ ctx->base.running = FALSE;
return;
}
@@ -853,7 +869,10 @@ void util_blitter_copy_region(struct blitter_context *blitter,
/* Draw. */
blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
- blitter_draw_quad(ctx);
+ ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
+ 0, ctx->vbuf->width0);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
break;
default:
@@ -1014,12 +1033,3 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
UTIL_BLITTER_ATTRIB_NONE, NULL);
blitter_restore_CSOs(ctx);
}
-
-/* flush a region of a depth stencil surface for r300g */
-void util_blitter_flush_depth_stencil(struct blitter_context *blitter,
- struct pipe_surface *dstsurf)
-{
- struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
- util_blitter_custom_depth_stencil(blitter, dstsurf, NULL,
- ctx->dsa_flush_depth_stencil, 0.0f);
-}
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 922a8580ac1..41470d92bba 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -55,13 +55,13 @@ struct blitter_context
* \param y1 A Y coordinate of the top-left corner.
* \param x2 An X coordinate of the bottom-right corner.
* \param y2 A Y coordinate of the bottom-right corner.
- * \param depth A depth which the rectangle is rendered at.
+ * \param depth A depth which the rectangle is rendered at.
*
* \param type Semantics of the attributes "attrib".
* If type is UTIL_BLITTER_ATTRIB_NONE, ignore them.
* If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes
- * make up a constant RGBA color, and should go to the COLOR0
- * varying slot of a fragment shader.
+ * make up a constant RGBA color, and should go
+ * to the GENERIC0 varying slot of a fragment shader.
* If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and
* {a3, a4} specify top-left and bottom-right texture
* coordinates of the rectangle, respectively, and should go
@@ -79,6 +79,9 @@ struct blitter_context
enum blitter_attrib_type type,
const float attrib[4]);
+ /* Whether the blitter is running. */
+ boolean running;
+
/* Private members, really. */
struct pipe_context *pipe; /**< pipe context */
@@ -141,6 +144,10 @@ void util_blitter_clear(struct blitter_context *blitter,
const float *rgba,
double depth, unsigned stencil);
+void util_blitter_clear_depth_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ double depth, void *custom_dsa);
+
/**
* Copy a block of pixels from one surface to another.
*
@@ -200,9 +207,6 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
-void util_blitter_flush_depth_stencil(struct blitter_context *blitter,
- struct pipe_surface *dstsurf);
-
void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
struct pipe_surface *zsurf,
struct pipe_surface *cbsurf,
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index f4ad545bee7..36ce4b57713 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -44,6 +44,7 @@
#include "util/u_surface.h"
#include <limits.h> /* CHAR_BIT */
+#include <ctype.h> /* isalnum */
void _debug_vprintf(const char *format, va_list ap)
{
@@ -180,6 +181,48 @@ debug_get_num_option(const char *name, long dfault)
return result;
}
+static boolean str_has_option(const char *str, const char *name)
+{
+ /* Empty string. */
+ if (!*str) {
+ return FALSE;
+ }
+
+ /* OPTION=all */
+ if (!util_strcmp(str, "all")) {
+ return TRUE;
+ }
+
+ /* Find 'name' in 'str' surrounded by non-alphanumeric characters. */
+ {
+ const char *start = str;
+ unsigned name_len = strlen(name);
+
+ /* 'start' is the beginning of the currently-parsed word,
+ * we increment 'str' each iteration.
+ * if we find either the end of string or a non-alphanumeric character,
+ * we compare 'start' up to 'str-1' with 'name'. */
+
+ while (1) {
+ if (!*str || !isalnum(*str)) {
+ if (str-start == name_len &&
+ !memcmp(start, name, name_len)) {
+ return TRUE;
+ }
+
+ if (!*str) {
+ return FALSE;
+ }
+
+ start = str+1;
+ }
+
+ str++;
+ }
+ }
+
+ return FALSE;
+}
unsigned long
debug_get_flags_option(const char *name,
@@ -207,7 +250,7 @@ debug_get_flags_option(const char *name,
else {
result = 0;
while( flags->name ) {
- if (!util_strcmp(str, "all") || util_strstr(str, flags->name ))
+ if (str_has_option(str, flags->name))
result |= flags->value;
++flags;
}
@@ -359,6 +402,41 @@ const char *u_prim_name( unsigned prim )
+#ifdef DEBUG
+int fl_indent = 0;
+const char* fl_function[1024];
+
+int debug_funclog_enter(const char* f, const int line, const char* file)
+{
+ int i;
+
+ for (i = 0; i < fl_indent; i++)
+ debug_printf(" ");
+ debug_printf("%s\n", f);
+
+ assert(fl_indent < 1023);
+ fl_function[fl_indent++] = f;
+
+ return 0;
+}
+
+void debug_funclog_exit(const char* f, const int line, const char* file)
+{
+ --fl_indent;
+ assert(fl_indent >= 0);
+ assert(fl_function[fl_indent] == f);
+}
+
+void debug_funclog_enter_exit(const char* f, const int line, const char* file)
+{
+ int i;
+ for (i = 0; i < fl_indent; i++)
+ debug_printf(" ");
+ debug_printf("%s\n", f);
+}
+#endif
+
+
#ifdef DEBUG
/**
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index 1c9624ea3ed..c47c13c64cf 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -280,6 +280,43 @@ debug_dump_flags(const struct debug_named_value *names,
/**
+ * Function enter exit loggers
+ */
+#ifdef DEBUG
+int debug_funclog_enter(const char* f, const int line, const char* file);
+void debug_funclog_exit(const char* f, const int line, const char* file);
+void debug_funclog_enter_exit(const char* f, const int line, const char* file);
+
+#define DEBUG_FUNCLOG_ENTER() \
+ int __debug_decleration_work_around = \
+ debug_funclog_enter(__FUNCTION__, __LINE__, __FILE__)
+#define DEBUG_FUNCLOG_EXIT() \
+ do { \
+ (void)__debug_decleration_work_around; \
+ debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \
+ return; \
+ } while(0)
+#define DEBUG_FUNCLOG_EXIT_RET(ret) \
+ do { \
+ (void)__debug_decleration_work_around; \
+ debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \
+ return ret; \
+ } while(0)
+#define DEBUG_FUNCLOG_ENTER_EXIT() \
+ debug_funclog_enter_exit(__FUNCTION__, __LINE__, __FILE__)
+
+#else
+#define DEBUG_FUNCLOG_ENTER() \
+ int __debug_decleration_work_around
+#define DEBUG_FUNCLOG_EXIT() \
+ do { (void)__debug_decleration_work_around; return; } while(0)
+#define DEBUG_FUNCLOG_EXIT_RET(ret) \
+ do { (void)__debug_decleration_work_around; return ret; } while(0)
+#define DEBUG_FUNCLOG_ENTER_EXIT()
+#endif
+
+
+/**
* Get option.
*
* It is an alias for getenv on Linux.
diff --git a/src/gallium/auxiliary/util/u_debug_refcnt.c b/src/gallium/auxiliary/util/u_debug_refcnt.c
index 40a26c9c697..6f706a35fda 100644
--- a/src/gallium/auxiliary/util/u_debug_refcnt.c
+++ b/src/gallium/auxiliary/util/u_debug_refcnt.c
@@ -43,7 +43,8 @@ int debug_refcnt_state;
struct os_stream* stream;
/* TODO: maybe move this serial machinery to a stand-alone module and expose it? */
-static pipe_mutex serials_mutex;
+pipe_static_mutex(serials_mutex);
+
static struct util_hash_table* serials_hash;
static unsigned serials_last;
@@ -66,6 +67,15 @@ static boolean debug_serial(void* p, unsigned* pserial)
{
unsigned serial;
boolean found = TRUE;
+#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
+ static boolean first = TRUE;
+
+ if (first) {
+ pipe_mutex_init(serials_mutex);
+ first = FALSE;
+ }
+#endif
+
pipe_mutex_lock(serials_mutex);
if(!serials_hash)
serials_hash = util_hash_table_create(hash_ptr, compare_ptr);
diff --git a/src/gallium/auxiliary/util/u_debug_symbol.c b/src/gallium/auxiliary/util/u_debug_symbol.c
index 44d437747a1..bae9be87a26 100644
--- a/src/gallium/auxiliary/util/u_debug_symbol.c
+++ b/src/gallium/auxiliary/util/u_debug_symbol.c
@@ -40,20 +40,43 @@
#include "u_debug_symbol.h"
#include "u_hash_table.h"
-#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
+#if defined(PIPE_OS_WINDOWS) && defined(PIPE_ARCH_X86)
#include <windows.h>
#include <stddef.h>
-#include <imagehlp.h>
-/*
- * TODO: Cleanup code.
- * TODO: Support x86_64
- */
+#include "dbghelp.h"
+
static BOOL bSymInitialized = FALSE;
-static HMODULE hModule_Imagehlp = NULL;
+static HMODULE hModule_Dbghelp = NULL;
+
+
+static
+FARPROC WINAPI __GetProcAddress(LPCSTR lpProcName)
+{
+#ifdef PIPE_CC_GCC
+ if (!hModule_Dbghelp) {
+ /*
+ * bfdhelp.dll is a dbghelp.dll look-alike replacement, which is able to
+ * understand MinGW symbols using BFD library. It is available from
+ * http://people.freedesktop.org/~jrfonseca/bfdhelp/ for now.
+ */
+ hModule_Dbghelp = LoadLibraryA("bfdhelp.dll");
+ }
+#endif
+
+ if (!hModule_Dbghelp) {
+ hModule_Dbghelp = LoadLibraryA("dbghelp.dll");
+ if (!hModule_Dbghelp) {
+ return NULL;
+ }
+ }
+
+ return GetProcAddress(hModule_Dbghelp, lpProcName);
+}
+
typedef BOOL (WINAPI *PFNSYMINITIALIZE)(HANDLE, LPSTR, BOOL);
static PFNSYMINITIALIZE pfnSymInitialize = NULL;
@@ -62,8 +85,7 @@ static
BOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess)
{
if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) GetProcAddress(hModule_Imagehlp, "SymInitialize")))
+ (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) __GetProcAddress("SymInitialize")))
)
return pfnSymInitialize(hProcess, UserSearchPath, fInvadeProcess);
else
@@ -77,57 +99,41 @@ static
DWORD WINAPI j_SymSetOptions(DWORD SymOptions)
{
if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) GetProcAddress(hModule_Imagehlp, "SymSetOptions")))
+ (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) __GetProcAddress("SymSetOptions")))
)
return pfnSymSetOptions(SymOptions);
else
return FALSE;
}
-typedef PGET_MODULE_BASE_ROUTINE PFNSYMGETMODULEBASE;
-static PFNSYMGETMODULEBASE pfnSymGetModuleBase = NULL;
+typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
+static PFNSYMGETSYMFROMADDR pfnSymFromAddr = NULL;
static
-DWORD WINAPI j_SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
+BOOL WINAPI j_SymFromAddr(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol)
{
if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymGetModuleBase || (pfnSymGetModuleBase = (PFNSYMGETMODULEBASE) GetProcAddress(hModule_Imagehlp, "SymGetModuleBase")))
+ (pfnSymFromAddr || (pfnSymFromAddr = (PFNSYMGETSYMFROMADDR) __GetProcAddress("SymFromAddr")))
)
- return pfnSymGetModuleBase(hProcess, dwAddr);
- else
- return 0;
-}
-
-typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_SYMBOL);
-static PFNSYMGETSYMFROMADDR pfnSymGetSymFromAddr = NULL;
-
-static
-BOOL WINAPI j_SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
-{
- if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymGetSymFromAddr || (pfnSymGetSymFromAddr = (PFNSYMGETSYMFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetSymFromAddr")))
- )
- return pfnSymGetSymFromAddr(hProcess, Address, Displacement, Symbol);
+ return pfnSymFromAddr(hProcess, Address, Displacement, Symbol);
else
return FALSE;
}
static INLINE void
-debug_symbol_name_imagehlp(const void *addr, char* buf, unsigned size)
+debug_symbol_name_dbghelp(const void *addr, char* buf, unsigned size)
{
HANDLE hProcess;
BYTE symbolBuffer[1024];
- PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer;
- DWORD dwDisplacement = 0; /* Displacement of the input address, relative to the start of the symbol */
+ PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) symbolBuffer;
+ DWORD64 dwDisplacement = 0; /* Displacement of the input address, relative to the start of the symbol */
hProcess = GetCurrentProcess();
+ memset(pSymbol, 0, sizeof *pSymbol);
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
- pSymbol->MaxNameLength = sizeof(symbolBuffer) - offsetof(IMAGEHLP_SYMBOL, Name);
+ pSymbol->MaxNameLen = sizeof(symbolBuffer) - offsetof(SYMBOL_INFO, Name);
if(!bSymInitialized) {
j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES);
@@ -135,7 +141,7 @@ debug_symbol_name_imagehlp(const void *addr, char* buf, unsigned size)
bSymInitialized = TRUE;
}
- if(!j_SymGetSymFromAddr(hProcess, (DWORD)addr, &dwDisplacement, pSymbol))
+ if(!j_SymFromAddr(hProcess, (DWORD64)(uintptr_t)addr, &dwDisplacement, pSymbol))
buf[0] = 0;
else
{
@@ -165,8 +171,8 @@ debug_symbol_name_glibc(const void *addr, char* buf, unsigned size)
void
debug_symbol_name(const void *addr, char* buf, unsigned size)
{
-#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
- debug_symbol_name_imagehlp(addr, buf, size);
+#if defined(PIPE_OS_WINDOWS) && defined(PIPE_ARCH_X86)
+ debug_symbol_name_dbghelp(addr, buf, size);
if(buf[0])
return;
#endif
@@ -190,7 +196,7 @@ debug_symbol_print(const void *addr)
}
struct util_hash_table* symbols_hash;
-pipe_mutex symbols_mutex;
+pipe_static_mutex(symbols_mutex);
static unsigned hash_ptr(void* p)
{
@@ -211,6 +217,15 @@ const char*
debug_symbol_name_cached(const void *addr)
{
const char* name;
+#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
+ static boolean first = TRUE;
+
+ if (first) {
+ pipe_mutex_init(symbols_mutex);
+ first = FALSE;
+ }
+#endif
+
pipe_mutex_lock(symbols_mutex);
if(!symbols_hash)
symbols_hash = util_hash_table_create(hash_ptr, compare_ptr);
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 0b6dc5880f3..0defd919974 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -31,6 +31,7 @@
#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
#include "util/u_memory.h"
+#include "cso_cache/cso_context.h"
/**
@@ -39,6 +40,7 @@
*/
void
util_draw_vertex_buffer(struct pipe_context *pipe,
+ struct cso_context *cso,
struct pipe_resource *vbuf,
uint offset,
uint prim_type,
@@ -54,8 +56,12 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
vbuffer.buffer = vbuf;
vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */
vbuffer.buffer_offset = offset;
- vbuffer.max_index = num_verts - 1;
- pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+
+ if (cso) {
+ cso_set_vertex_buffers(cso, 1, &vbuffer);
+ } else {
+ pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+ }
/* note: vertex elements already set by caller */
@@ -70,7 +76,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
* Note: this isn't especially efficient.
*/
void
-util_draw_texquad(struct pipe_context *pipe,
+util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
float x0, float y0, float x1, float y1, float z)
{
uint numAttribs = 2, i, j;
@@ -118,7 +124,7 @@ util_draw_texquad(struct pipe_context *pipe,
if (!vbuf)
goto out;
- util_draw_vertex_buffer(pipe, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+ util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
out:
if (vbuf)
diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h
index 52994fe05c3..f1167786f0e 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/src/gallium/auxiliary/util/u_draw_quad.h
@@ -38,17 +38,18 @@ extern "C" {
#endif
struct pipe_resource;
+struct cso_context;
#include "util/u_draw.h"
extern void
-util_draw_vertex_buffer(struct pipe_context *pipe,
+util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
struct pipe_resource *vbuf, uint offset,
uint num_attribs, uint num_verts, uint prim_type);
extern void
-util_draw_texquad(struct pipe_context *pipe,
+util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
float x0, float y0, float x1, float y1, float z);
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index b471d59eebf..5ecf8cbb067 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -681,7 +681,6 @@ util_dump_vertex_buffer(struct os_stream *stream, const struct pipe_vertex_buffe
util_dump_struct_begin(stream, "pipe_vertex_buffer");
util_dump_member(stream, uint, state, stride);
- util_dump_member(stream, uint, state, max_index);
util_dump_member(stream, uint, state, buffer_offset);
util_dump_member(stream, ptr, state, buffer);
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 03b73c0e98f..7659a802a41 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -673,7 +673,8 @@ util_format_has_alpha(enum pipe_format format)
}
/**
- * Return the matching SRGB format, or PIPE_FORMAT_NONE if none.
+ * Given a linear RGB colorspace format, return the corresponding SRGB
+ * format, or PIPE_FORMAT_NONE if none.
*/
static INLINE enum pipe_format
util_format_srgb(enum pipe_format format)
@@ -711,6 +712,45 @@ util_format_srgb(enum pipe_format format)
}
/**
+ * Given an sRGB format, return the corresponding linear colorspace format.
+ * For non sRGB formats, return the format unchanged.
+ */
+static INLINE enum pipe_format
+util_format_linear(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_L8_SRGB:
+ return PIPE_FORMAT_L8_UNORM;
+ case PIPE_FORMAT_L8A8_SRGB:
+ return PIPE_FORMAT_L8A8_UNORM;
+ case PIPE_FORMAT_R8G8B8_SRGB:
+ return PIPE_FORMAT_R8G8B8_UNORM;
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ return PIPE_FORMAT_A8B8G8R8_UNORM;
+ case PIPE_FORMAT_X8B8G8R8_SRGB:
+ return PIPE_FORMAT_X8B8G8R8_UNORM;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ case PIPE_FORMAT_B8G8R8X8_SRGB:
+ return PIPE_FORMAT_B8G8R8X8_UNORM;
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ case PIPE_FORMAT_X8R8G8B8_SRGB:
+ return PIPE_FORMAT_X8R8G8B8_UNORM;
+ case PIPE_FORMAT_DXT1_SRGB:
+ return PIPE_FORMAT_DXT1_RGB;
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return PIPE_FORMAT_DXT1_RGBA;
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return PIPE_FORMAT_DXT3_RGBA;
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return PIPE_FORMAT_DXT5_RGBA;
+ default:
+ return format;
+ }
+}
+
+/**
* Return the number of components stored.
* Formats with block size != 1x1 will always have 1 component (the block).
*/
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index d22ae8b375b..3b6342ad8d1 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1350,6 +1350,7 @@ get_next_slot(struct gen_mipmap_state *ctx)
if (!ctx->vbuf) {
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
max_slots * sizeof ctx->vertices);
}
@@ -1616,7 +1617,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
face,
rcoord);
- util_draw_vertex_buffer(ctx->pipe,
+ util_draw_vertex_buffer(ctx->pipe,
+ ctx->cso,
ctx->vbuf,
offset,
PIPE_PRIM_TRIANGLE_FAN,
diff --git a/src/gallium/auxiliary/util/u_index_modify.c b/src/gallium/auxiliary/util/u_index_modify.c
index f2c9db3caf1..d0a28b5fdfa 100644
--- a/src/gallium/auxiliary/util/u_index_modify.c
+++ b/src/gallium/auxiliary/util/u_index_modify.c
@@ -38,7 +38,10 @@ void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
unsigned short *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts, PIPE_TRANSFER_READ, &src_transfer);
+ in_map = pipe_buffer_map(context, elts,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &src_transfer);
in_map += start;
for (i = 0; i < count; i++) {
@@ -62,6 +65,7 @@ void util_shorten_ubyte_elts(struct pipe_context *context,
new_elts = pipe_buffer_create(context->screen,
PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
2 * count);
out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
@@ -87,7 +91,10 @@ void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
unsigned short *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts, PIPE_TRANSFER_READ, &in_transfer);
+ in_map = pipe_buffer_map(context, elts,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
in_map += start;
for (i = 0; i < count; i++) {
@@ -110,6 +117,7 @@ void util_rebuild_ushort_elts(struct pipe_context *context,
new_elts = pipe_buffer_create(context->screen,
PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
2 * count);
out_map = pipe_buffer_map(context, new_elts,
@@ -135,7 +143,10 @@ void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
unsigned int *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts, PIPE_TRANSFER_READ, &in_transfer);
+ in_map = pipe_buffer_map(context, elts,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
in_map += start;
for (i = 0; i < count; i++) {
@@ -158,6 +169,7 @@ void util_rebuild_uint_elts(struct pipe_context *context,
new_elts = pipe_buffer_create(context->screen,
PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
2 * count);
out_map = pipe_buffer_map(context, new_elts,
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index b4870bce981..98889fb70ac 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -160,6 +160,21 @@ pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
pipe_surface_reset(ctx, ps, pt, level, layer, flags);
}
+/* Return true if the surfaces are equal. */
+static INLINE boolean
+pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2)
+{
+ return s1->texture == s2->texture &&
+ s1->format == s2->format &&
+ (s1->texture->target != PIPE_BUFFER ||
+ (s1->u.buf.first_element == s2->u.buf.first_element &&
+ s1->u.buf.last_element == s2->u.buf.last_element)) &&
+ (s1->texture->target == PIPE_BUFFER ||
+ (s1->u.tex.level == s2->u.tex.level &&
+ s1->u.tex.first_layer == s2->u.tex.first_layer &&
+ s1->u.tex.last_layer == s2->u.tex.last_layer));
+}
+
/*
* Convenience wrappers for screen buffer functions.
*/
@@ -167,6 +182,7 @@ pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
static INLINE struct pipe_resource *
pipe_buffer_create( struct pipe_screen *screen,
unsigned bind,
+ unsigned usage,
unsigned size )
{
struct pipe_resource buffer;
@@ -174,7 +190,7 @@ pipe_buffer_create( struct pipe_screen *screen,
buffer.target = PIPE_BUFFER;
buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
buffer.bind = bind;
- buffer.usage = PIPE_USAGE_DEFAULT;
+ buffer.usage = usage;
buffer.flags = 0;
buffer.width0 = size;
buffer.height0 = 1;
@@ -220,6 +236,7 @@ pipe_buffer_map_range(struct pipe_context *pipe,
map = pipe->transfer_map( pipe, *transfer );
if (map == NULL) {
pipe->transfer_destroy( pipe, *transfer );
+ *transfer = NULL;
return NULL;
}
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index 37294b7203f..30555f92a6d 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -176,7 +176,7 @@ static INLINE float logf( float f )
#define isfinite(x) _finite((double)(x))
#define isnan(x) _isnan((double)(x))
-#endif
+#endif /* _MSC_VER < 1400 && !defined(__cplusplus) */
static INLINE double log2( double x )
{
@@ -184,6 +184,18 @@ static INLINE double log2( double x )
return log( x ) * invln2;
}
+static INLINE double
+round(double x)
+{
+ return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5);
+}
+
+static INLINE float
+roundf(float x)
+{
+ return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
+}
+
#endif /* _MSC_VER */
diff --git a/src/gallium/auxiliary/util/u_resource.c b/src/gallium/auxiliary/util/u_resource.c
index 443c9f8067e..ea6896b430f 100644
--- a/src/gallium/auxiliary/util/u_resource.c
+++ b/src/gallium/auxiliary/util/u_resource.c
@@ -35,7 +35,7 @@ unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
- enum pipe_transfer_usage usage,
+ unsigned usage,
const struct pipe_box *box)
{
struct u_resource *ur = u_resource(resource);
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 44cadbfcdd0..e3c7085ba92 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -367,47 +367,19 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
float *p)
{
- unsigned dst_stride = w * 4;
- void *packed;
- enum pipe_format format = pt->resource->format;
-
- if (u_clip_tile(x, y, &w, &h, &pt->box))
- return;
-
- packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
-
- if (!packed)
- return;
-
- if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV)
- assert((x & 1) == 0);
-
- pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
-
- pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
-
- FREE(packed);
+ pipe_get_tile_rgba_format(pipe, pt, x, y, w, h, pt->resource->format, p);
}
void
-pipe_get_tile_swizzle(struct pipe_context *pipe,
- struct pipe_transfer *pt,
- uint x,
- uint y,
- uint w,
- uint h,
- uint swizzle_r,
- uint swizzle_g,
- uint swizzle_b,
- uint swizzle_a,
- enum pipe_format format,
- float *p)
+pipe_get_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ float *p)
{
unsigned dst_stride = w * 4;
void *packed;
- uint iy;
- float rgba01[6];
if (u_clip_tile(x, y, &w, &h, &pt->box)) {
return;
@@ -427,35 +399,6 @@ pipe_get_tile_swizzle(struct pipe_context *pipe,
pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
FREE(packed);
-
- if (swizzle_r == PIPE_SWIZZLE_RED &&
- swizzle_g == PIPE_SWIZZLE_GREEN &&
- swizzle_b == PIPE_SWIZZLE_BLUE &&
- swizzle_a == PIPE_SWIZZLE_ALPHA) {
- /* no-op, skip */
- return;
- }
-
- rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
- rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
-
- for (iy = 0; iy < h; iy++) {
- float *row = p;
- uint ix;
-
- for (ix = 0; ix < w; ix++) {
- rgba01[PIPE_SWIZZLE_RED] = row[0];
- rgba01[PIPE_SWIZZLE_GREEN] = row[1];
- rgba01[PIPE_SWIZZLE_BLUE] = row[2];
- rgba01[PIPE_SWIZZLE_ALPHA] = row[3];
-
- *row++ = rgba01[swizzle_r];
- *row++ = rgba01[swizzle_g];
- *row++ = rgba01[swizzle_b];
- *row++ = rgba01[swizzle_a];
- }
- p += dst_stride;
- }
}
@@ -465,9 +408,19 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
const float *p)
{
+ pipe_put_tile_rgba_format(pipe, pt, x, y, w, h, pt->resource->format, p);
+}
+
+
+void
+pipe_put_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ const float *p)
+{
unsigned src_stride = w * 4;
void *packed;
- enum pipe_format format = pt->resource->format;
if (u_clip_tile(x, y, &w, &h, &pt->box))
return;
diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h
index 558351d0ce5..0ba274308fe 100644
--- a/src/gallium/auxiliary/util/u_tile.h
+++ b/src/gallium/auxiliary/util/u_tile.h
@@ -80,18 +80,11 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
float *p);
void
-pipe_get_tile_swizzle(struct pipe_context *pipe,
- struct pipe_transfer *pt,
- uint x,
- uint y,
- uint w,
- uint h,
- uint swizzle_r,
- uint swizzle_g,
- uint swizzle_b,
- uint swizzle_a,
- enum pipe_format format,
- float *p);
+pipe_get_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ float *p);
void
pipe_put_tile_rgba(struct pipe_context *pipe,
@@ -99,6 +92,13 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
const float *p);
+void
+pipe_put_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ const float *p);
+
void
pipe_get_tile_z(struct pipe_context *pipe,
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index e2828cfd99e..b6c63d9642f 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -112,3 +112,10 @@ void u_default_transfer_destroy(struct pipe_context *pipe,
FREE(transfer);
}
+void u_default_redefine_user_buffer(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned offset,
+ unsigned size)
+{
+ resource->width0 = MAX2(resource->width0, offset + size);
+}
diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
index 3412e13c3cc..8cf9c418b04 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -93,7 +93,7 @@ struct u_resource_vtbl {
struct u_resource {
struct pipe_resource b;
- struct u_resource_vtbl *vtbl;
+ const struct u_resource_vtbl *vtbl;
};
@@ -136,11 +136,9 @@ void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
unsigned stride,
unsigned layer_stride);
-
-
-
-
-
-
+void u_default_redefine_user_buffer(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned offset,
+ unsigned size);
#endif
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index 3b3d5b418fe..dcf800a1e8e 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -85,7 +85,12 @@ void u_upload_flush( struct u_upload_mgr *upload )
{
/* Unmap and unreference the upload buffer. */
if (upload->transfer) {
+ if (upload->size) {
+ pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
+ 0, upload->size);
+ }
pipe_transfer_unmap(upload->pipe, upload->transfer);
+ pipe_transfer_destroy(upload->pipe, upload->transfer);
upload->transfer = NULL;
}
pipe_resource_reference( &upload->buffer, NULL );
@@ -116,13 +121,17 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
upload->buffer = pipe_buffer_create( upload->pipe->screen,
upload->bind,
+ PIPE_USAGE_STREAM,
size );
if (upload->buffer == NULL)
goto fail;
/* Map the new buffer. */
- upload->map = pipe_buffer_map(upload->pipe, upload->buffer,
- PIPE_TRANSFER_WRITE, &upload->transfer);
+ upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
+ 0, size,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_FLUSH_EXPLICIT,
+ &upload->transfer);
upload->size = size;
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
new file mode 100644
index 00000000000..dec8dd717e8
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -0,0 +1,601 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Marek Olšák <[email protected]>
+ * All Rights Reserved.
+ *
+ * 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 AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#include "util/u_vbuf_mgr.h"
+
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_upload_mgr.h"
+#include "translate/translate.h"
+#include "translate/translate_cache.h"
+
+/* Hardware vertex fetcher limitations can be described by this structure. */
+struct u_vbuf_caps {
+ /* Vertex format CAPs. */
+ /* TRUE if hardware supports it. */
+ unsigned format_fixed32:1; /* PIPE_FORMAT_*32*_FIXED */
+ unsigned format_float16:1; /* PIPE_FORMAT_*16*_FLOAT */
+ unsigned format_float64:1; /* PIPE_FORMAT_*64*_FLOAT */
+ unsigned format_norm32:1; /* PIPE_FORMAT_*32*NORM */
+ unsigned format_scaled32:1; /* PIPE_FORMAT_*32*SCALED */
+
+ /* Whether vertex fetches don't have to be dword-aligned. */
+ /* TRUE if hardware supports it. */
+ unsigned fetch_dword_unaligned:1;
+};
+
+struct u_vbuf_mgr_elements {
+ unsigned count;
+ struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
+
+ /* If (velem[i].src_format != real_format[i]), the vertex buffer
+ * referenced by the vertex element cannot be used for rendering and
+ * its vertex data must be translated to real_format[i]. */
+ enum pipe_format native_format[PIPE_MAX_ATTRIBS];
+ unsigned native_format_size[PIPE_MAX_ATTRIBS];
+
+ /* This might mean two things:
+ * - src_format != native_format, as discussed above.
+ * - src_offset % 4 != 0 (if the caps don't allow such an offset). */
+ boolean incompatible_layout;
+};
+
+struct u_vbuf_mgr_priv {
+ struct u_vbuf_mgr b;
+ struct u_vbuf_caps caps;
+ struct pipe_context *pipe;
+
+ struct translate_cache *translate_cache;
+ unsigned translate_vb_slot;
+
+ struct u_vbuf_mgr_elements *ve;
+ void *saved_ve, *fallback_ve;
+ boolean ve_binding_lock;
+
+ boolean any_user_vbs;
+ boolean incompatible_vb_layout;
+};
+
+static void u_vbuf_mgr_init_format_caps(struct u_vbuf_mgr_priv *mgr)
+{
+ struct pipe_screen *screen = mgr->pipe->screen;
+
+ mgr->caps.format_fixed32 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_float16 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_float64 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_norm32 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_scaled32 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+}
+
+struct u_vbuf_mgr *
+u_vbuf_mgr_create(struct pipe_context *pipe,
+ unsigned upload_buffer_size,
+ unsigned upload_buffer_alignment,
+ unsigned upload_buffer_bind,
+ enum u_fetch_alignment fetch_alignment)
+{
+ struct u_vbuf_mgr_priv *mgr = CALLOC_STRUCT(u_vbuf_mgr_priv);
+
+ mgr->pipe = pipe;
+ mgr->translate_cache = translate_cache_create();
+
+ mgr->b.uploader = u_upload_create(pipe, upload_buffer_size,
+ upload_buffer_alignment,
+ upload_buffer_bind);
+
+ mgr->caps.fetch_dword_unaligned =
+ fetch_alignment == U_VERTEX_FETCH_BYTE_ALIGNED;
+
+ u_vbuf_mgr_init_format_caps(mgr);
+
+ return &mgr->b;
+}
+
+void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgrb)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ unsigned i;
+
+ for (i = 0; i < mgr->b.nr_real_vertex_buffers; i++) {
+ pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
+ }
+
+ translate_cache_destroy(mgr->translate_cache);
+ u_upload_destroy(mgr->b.uploader);
+ FREE(mgr);
+}
+
+
+static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
+ int min_index, int max_index,
+ boolean *upload_flushed)
+{
+ struct translate_key key;
+ struct translate_element *te;
+ unsigned tr_elem_index[PIPE_MAX_ATTRIBS];
+ struct translate *tr;
+ boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
+ uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
+ struct pipe_resource *out_buffer = NULL;
+ unsigned i, num_verts, out_offset;
+ struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
+
+ memset(&key, 0, sizeof(key));
+ memset(tr_elem_index, 0xff, sizeof(tr_elem_index));
+
+ /* Initialize the translate key, i.e. the recipe how vertices should be
+ * translated. */
+ for (i = 0; i < mgr->ve->count; i++) {
+ struct pipe_vertex_buffer *vb =
+ &mgr->b.vertex_buffer[mgr->ve->ve[i].vertex_buffer_index];
+ enum pipe_format output_format = mgr->ve->native_format[i];
+ unsigned output_format_size = mgr->ve->native_format_size[i];
+
+ /* Check for support. */
+ if (mgr->ve->ve[i].src_format == mgr->ve->native_format[i] &&
+ (mgr->caps.fetch_dword_unaligned ||
+ (vb->buffer_offset % 4 == 0 &&
+ vb->stride % 4 == 0 &&
+ mgr->ve->ve[i].src_offset % 4 == 0))) {
+ continue;
+ }
+
+ /* Workaround for translate: output floats instead of halfs. */
+ switch (output_format) {
+ case PIPE_FORMAT_R16_FLOAT:
+ output_format = PIPE_FORMAT_R32_FLOAT;
+ output_format_size = 4;
+ break;
+ case PIPE_FORMAT_R16G16_FLOAT:
+ output_format = PIPE_FORMAT_R32G32_FLOAT;
+ output_format_size = 8;
+ break;
+ case PIPE_FORMAT_R16G16B16_FLOAT:
+ output_format = PIPE_FORMAT_R32G32B32_FLOAT;
+ output_format_size = 12;
+ break;
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ output_format_size = 16;
+ break;
+ default:;
+ }
+
+ /* Add this vertex element. */
+ te = &key.element[key.nr_elements];
+ /*te->type;
+ te->instance_divisor;*/
+ te->input_buffer = mgr->ve->ve[i].vertex_buffer_index;
+ te->input_format = mgr->ve->ve[i].src_format;
+ te->input_offset = mgr->ve->ve[i].src_offset;
+ te->output_format = output_format;
+ te->output_offset = key.output_stride;
+
+ key.output_stride += output_format_size;
+ vb_translated[mgr->ve->ve[i].vertex_buffer_index] = TRUE;
+ tr_elem_index[i] = key.nr_elements;
+ key.nr_elements++;
+ }
+
+ /* Get a translate object. */
+ tr = translate_cache_find(mgr->translate_cache, &key);
+
+ /* Map buffers we want to translate. */
+ for (i = 0; i < mgr->b.nr_vertex_buffers; i++) {
+ if (vb_translated[i]) {
+ struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i];
+
+ vb_map[i] = pipe_buffer_map(mgr->pipe, vb->buffer,
+ PIPE_TRANSFER_READ, &vb_transfer[i]);
+
+ tr->set_buffer(tr, i,
+ vb_map[i] + vb->buffer_offset + vb->stride * min_index,
+ vb->stride, ~0);
+ }
+ }
+
+ /* Create and map the output buffer. */
+ num_verts = max_index + 1 - min_index;
+
+ u_upload_alloc(mgr->b.uploader,
+ key.output_stride * min_index,
+ key.output_stride * num_verts,
+ &out_offset, &out_buffer, upload_flushed,
+ (void**)&out_map);
+
+ out_offset -= key.output_stride * min_index;
+
+ /* Translate. */
+ tr->run(tr, 0, num_verts, 0, out_map);
+
+ /* Unmap all buffers. */
+ for (i = 0; i < mgr->b.nr_vertex_buffers; i++) {
+ if (vb_translated[i]) {
+ pipe_buffer_unmap(mgr->pipe, vb_transfer[i]);
+ }
+ }
+
+ /* Setup the new vertex buffer in the first free slot. */
+ mgr->translate_vb_slot = ~0;
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
+ if (!mgr->b.vertex_buffer[i].buffer) {
+ mgr->translate_vb_slot = i;
+
+ if (i >= mgr->b.nr_vertex_buffers) {
+ mgr->b.nr_real_vertex_buffers = i+1;
+ }
+ break;
+ }
+ }
+
+ if (mgr->translate_vb_slot != ~0) {
+ /* Setup the new vertex buffer. */
+ pipe_resource_reference(
+ &mgr->b.real_vertex_buffer[mgr->translate_vb_slot], out_buffer);
+ mgr->b.vertex_buffer[mgr->translate_vb_slot].buffer_offset = out_offset;
+ mgr->b.vertex_buffer[mgr->translate_vb_slot].stride = key.output_stride;
+
+ /* Setup new vertex elements. */
+ for (i = 0; i < mgr->ve->count; i++) {
+ if (tr_elem_index[i] < key.nr_elements) {
+ te = &key.element[tr_elem_index[i]];
+ new_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor;
+ new_velems[i].src_format = te->output_format;
+ new_velems[i].src_offset = te->output_offset;
+ new_velems[i].vertex_buffer_index = mgr->translate_vb_slot;
+ } else {
+ memcpy(&new_velems[i], &mgr->ve->ve[i],
+ sizeof(struct pipe_vertex_element));
+ }
+ }
+
+ mgr->fallback_ve =
+ mgr->pipe->create_vertex_elements_state(mgr->pipe, mgr->ve->count,
+ new_velems);
+
+ /* Preserve saved_ve. */
+ mgr->ve_binding_lock = TRUE;
+ mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->fallback_ve);
+ mgr->ve_binding_lock = FALSE;
+ }
+
+ pipe_resource_reference(&out_buffer, NULL);
+}
+
+static void u_vbuf_translate_end(struct u_vbuf_mgr_priv *mgr)
+{
+ if (mgr->fallback_ve == NULL) {
+ return;
+ }
+
+ /* Restore vertex elements. */
+ /* Note that saved_ve will be overwritten in bind_vertex_elements_state. */
+ mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->saved_ve);
+ mgr->pipe->delete_vertex_elements_state(mgr->pipe, mgr->fallback_ve);
+ mgr->fallback_ve = NULL;
+
+ /* Delete the now-unused VBO. */
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[mgr->translate_vb_slot],
+ NULL);
+ mgr->b.nr_real_vertex_buffers = mgr->b.nr_vertex_buffers;
+}
+
+#define FORMAT_REPLACE(what, withwhat) \
+ case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
+
+struct u_vbuf_mgr_elements *
+u_vbuf_mgr_create_vertex_elements(struct u_vbuf_mgr *mgrb,
+ unsigned count,
+ const struct pipe_vertex_element *attribs,
+ struct pipe_vertex_element *native_attribs)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ unsigned i;
+ struct u_vbuf_mgr_elements *ve = CALLOC_STRUCT(u_vbuf_mgr_elements);
+
+ ve->count = count;
+
+ if (!count) {
+ return ve;
+ }
+
+ memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count);
+ memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count);
+
+ /* Set the best native format in case the original format is not
+ * supported. */
+ for (i = 0; i < count; i++) {
+ enum pipe_format format = ve->ve[i].src_format;
+
+ /* Choose a native format.
+ * For now we don't care about the alignment, that's going to
+ * be sorted out later. */
+ if (!mgr->caps.format_fixed32) {
+ switch (format) {
+ FORMAT_REPLACE(R32_FIXED, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_float16) {
+ switch (format) {
+ FORMAT_REPLACE(R16_FLOAT, R32_FLOAT);
+ FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT);
+ FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_float64) {
+ switch (format) {
+ FORMAT_REPLACE(R64_FLOAT, R32_FLOAT);
+ FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT);
+ FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_norm32) {
+ switch (format) {
+ FORMAT_REPLACE(R32_UNORM, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT);
+ FORMAT_REPLACE(R32_SNORM, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_scaled32) {
+ switch (format) {
+ FORMAT_REPLACE(R32_USCALED, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
+ FORMAT_REPLACE(R32_SSCALED, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+
+ native_attribs[i].src_format = format;
+ ve->native_format[i] = format;
+ ve->native_format_size[i] =
+ util_format_get_blocksize(ve->native_format[i]);
+
+ ve->incompatible_layout =
+ ve->incompatible_layout ||
+ ve->ve[i].src_format != ve->native_format[i] ||
+ (!mgr->caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0);
+ }
+
+ /* Align the formats to the size of DWORD if needed. */
+ if (!mgr->caps.fetch_dword_unaligned) {
+ for (i = 0; i < count; i++) {
+ ve->native_format_size[i] = align(ve->native_format_size[i], 4);
+ }
+ }
+
+ return ve;
+}
+
+void u_vbuf_mgr_bind_vertex_elements(struct u_vbuf_mgr *mgrb,
+ void *cso,
+ struct u_vbuf_mgr_elements *ve)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+
+ if (!cso) {
+ return;
+ }
+
+ if (!mgr->ve_binding_lock) {
+ mgr->saved_ve = cso;
+ mgr->ve = ve;
+ }
+}
+
+void u_vbuf_mgr_destroy_vertex_elements(struct u_vbuf_mgr *mgr,
+ struct u_vbuf_mgr_elements *ve)
+{
+ FREE(ve);
+}
+
+void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
+ unsigned count,
+ const struct pipe_vertex_buffer *bufs)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ unsigned i;
+
+ mgr->b.max_index = ~0;
+ mgr->any_user_vbs = FALSE;
+ mgr->incompatible_vb_layout = FALSE;
+
+ if (!mgr->caps.fetch_dword_unaligned) {
+ /* Check if the strides and offsets are aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ if (bufs[i].buffer) {
+ if (bufs[i].stride % 4 != 0 ||
+ bufs[i].buffer_offset % 4 != 0) {
+ mgr->incompatible_vb_layout = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ const struct pipe_vertex_buffer *vb = &bufs[i];
+
+ pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
+
+ if (u_vbuf_resource(vb->buffer)->user_ptr) {
+ mgr->any_user_vbs = TRUE;
+ continue;
+ }
+
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], vb->buffer);
+
+ /* The stride of zero means we will be fetching only the first
+ * vertex, so don't care about max_index. */
+ if (!vb->stride) {
+ continue;
+ }
+
+ /* Update the maximum index. */
+ mgr->b.max_index =
+ MIN2(mgr->b.max_index,
+ (vb->buffer->width0 - vb->buffer_offset) / vb->stride);
+ }
+
+ for (; i < mgr->b.nr_real_vertex_buffers; i++) {
+ pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
+ }
+
+ memcpy(mgr->b.vertex_buffer, bufs,
+ sizeof(struct pipe_vertex_buffer) * count);
+
+ mgr->b.nr_vertex_buffers = count;
+ mgr->b.nr_real_vertex_buffers = count;
+}
+
+static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
+ int min_index, int max_index,
+ boolean *upload_flushed)
+{
+ int i, nr = mgr->ve->count;
+ unsigned count = max_index + 1 - min_index;
+ boolean uploaded[PIPE_MAX_ATTRIBS] = {0};
+
+ for (i = 0; i < nr; i++) {
+ unsigned index = mgr->ve->ve[i].vertex_buffer_index;
+ struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index];
+
+ if (vb->buffer &&
+ u_vbuf_resource(vb->buffer)->user_ptr &&
+ !uploaded[index]) {
+ unsigned first, size;
+ boolean flushed;
+
+ if (vb->stride) {
+ first = vb->stride * min_index;
+ size = vb->stride * count;
+ } else {
+ first = 0;
+ size = mgr->ve->native_format_size[i];
+ }
+
+ u_upload_data(mgr->b.uploader, first, size,
+ u_vbuf_resource(vb->buffer)->user_ptr + first,
+ &vb->buffer_offset,
+ &mgr->b.real_vertex_buffer[index],
+ &flushed);
+
+ vb->buffer_offset -= first;
+
+ uploaded[index] = TRUE;
+ *upload_flushed = *upload_flushed || flushed;
+ } else {
+ assert(mgr->b.real_vertex_buffer[index]);
+ }
+ }
+}
+
+void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
+ const struct pipe_draw_info *info,
+ boolean *buffers_updated,
+ boolean *uploader_flushed)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ boolean bufs_updated = FALSE, upload_flushed = FALSE;
+ int min_index, max_index;
+
+ min_index = info->min_index - info->index_bias;
+ max_index = info->max_index - info->index_bias;
+
+ /* Translate vertices with non-native layouts or formats. */
+ if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) {
+ u_vbuf_translate_begin(mgr, min_index, max_index, &upload_flushed);
+
+ if (mgr->fallback_ve) {
+ bufs_updated = TRUE;
+ }
+ }
+
+ /* Upload user buffers. */
+ if (mgr->any_user_vbs) {
+ u_vbuf_upload_buffers(mgr, min_index, max_index, &upload_flushed);
+ bufs_updated = TRUE;
+ }
+
+ /* Set the return values. */
+ if (buffers_updated) {
+ *buffers_updated = bufs_updated;
+ }
+ if (uploader_flushed) {
+ *uploader_flushed = upload_flushed;
+ }
+}
+
+void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgrb)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+
+ if (mgr->fallback_ve) {
+ u_vbuf_translate_end(mgr);
+ }
+}
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.h b/src/gallium/auxiliary/util/u_vbuf_mgr.h
new file mode 100644
index 00000000000..8b241854c83
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.h
@@ -0,0 +1,121 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Marek Olšák <[email protected]>
+ * All Rights Reserved.
+ *
+ * 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 AUTHORS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+#ifndef U_VBUF_MGR_H
+#define U_VBUF_MGR_H
+
+/* This module builds upon u_upload_mgr and translate_cache and takes care of
+ * user buffer uploads and vertex format fallbacks. It's designed
+ * for the drivers which don't always use the Draw module. (e.g. for HWTCL)
+ */
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_transfer.h"
+
+/* The manager.
+ * This structure should also be used to access vertex buffers
+ * from a driver. */
+struct u_vbuf_mgr {
+ /* This is what was set in set_vertex_buffers.
+ * May contain user buffers. */
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ unsigned nr_vertex_buffers;
+
+ /* Contains only real vertex buffers.
+ * Hardware drivers should use real_vertex_buffers[i]
+ * instead of vertex_buffers[i].buffer. */
+ struct pipe_resource *real_vertex_buffer[PIPE_MAX_ATTRIBS];
+ int nr_real_vertex_buffers;
+
+ /* Precomputed max_index for hardware vertex buffers. */
+ int max_index;
+
+ /* This uploader can optionally be used by the driver.
+ *
+ * Allowed functions:
+ * - u_upload_alloc
+ * - u_upload_data
+ * - u_upload_buffer
+ * - u_upload_flush */
+ struct u_upload_mgr *uploader;
+};
+
+struct u_vbuf_resource {
+ struct u_resource b;
+ uint8_t *user_ptr;
+};
+
+/* Opaque type containing information about vertex elements for the manager. */
+struct u_vbuf_mgr_elements;
+
+enum u_fetch_alignment {
+ U_VERTEX_FETCH_BYTE_ALIGNED,
+ U_VERTEX_FETCH_DWORD_ALIGNED
+};
+
+
+struct u_vbuf_mgr *
+u_vbuf_mgr_create(struct pipe_context *pipe,
+ unsigned upload_buffer_size,
+ unsigned upload_buffer_alignment,
+ unsigned upload_buffer_bind,
+ enum u_fetch_alignment fetch_alignment);
+
+void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgr);
+
+struct u_vbuf_mgr_elements *
+u_vbuf_mgr_create_vertex_elements(struct u_vbuf_mgr *mgr,
+ unsigned count,
+ const struct pipe_vertex_element *attrs,
+ struct pipe_vertex_element *native_attrs);
+
+void u_vbuf_mgr_bind_vertex_elements(struct u_vbuf_mgr *mgr,
+ void *cso,
+ struct u_vbuf_mgr_elements *ve);
+
+void u_vbuf_mgr_destroy_vertex_elements(struct u_vbuf_mgr *mgr,
+ struct u_vbuf_mgr_elements *ve);
+
+void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgr,
+ unsigned count,
+ const struct pipe_vertex_buffer *bufs);
+
+void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr,
+ const struct pipe_draw_info *info,
+ boolean *buffers_updated,
+ boolean *uploader_flushed);
+
+void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgr);
+
+
+static INLINE struct u_vbuf_resource *u_vbuf_resource(struct pipe_resource *r)
+{
+ return (struct u_vbuf_resource*)r;
+}
+
+#endif
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index d7b29497ace..d1ba5faf788 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -247,13 +247,13 @@ init_buffers(struct vl_compositor *c)
* Create our vertex buffer and vertex buffer elements
*/
c->vertex_buf.stride = sizeof(struct vertex4f);
- c->vertex_buf.max_index = (VL_COMPOSITOR_MAX_LAYERS + 2) * 6 - 1;
c->vertex_buf.buffer_offset = 0;
/* XXX: Create with DYNAMIC or STREAM */
c->vertex_buf.buffer = pipe_buffer_create
(
c->pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STATIC,
sizeof(struct vertex4f) * (VL_COMPOSITOR_MAX_LAYERS + 2) * 6
);
@@ -276,6 +276,7 @@ init_buffers(struct vl_compositor *c)
(
c->pipe->screen,
PIPE_BIND_CONSTANT_BUFFER,
+ PIPE_USAGE_STATIC,
sizeof(struct fragment_shader_consts)
);
diff --git a/src/gallium/auxiliary/vl/vl_idct.c b/src/gallium/auxiliary/vl/vl_idct.c
index 5d472f93481..89463a5c75c 100644
--- a/src/gallium/auxiliary/vl/vl_idct.c
+++ b/src/gallium/auxiliary/vl/vl_idct.c
@@ -428,7 +428,6 @@ init_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
/* create textures */
memset(&template, 0, sizeof(struct pipe_resource));
template.last_level = 0;
- template.depth0 = 1;
template.bind = PIPE_BIND_SAMPLER_VIEW;
template.flags = 0;
@@ -437,6 +436,7 @@ init_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
template.width0 = idct->buffer_width / 4;
template.height0 = idct->buffer_height;
template.depth0 = 1;
+ template.array_size = 1;
template.usage = PIPE_USAGE_STREAM;
buffer->textures.individual.source = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
@@ -478,7 +478,6 @@ init_vertex_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
assert(idct && buffer);
buffer->vertex_bufs.individual.quad.stride = idct->quad.stride;
- buffer->vertex_bufs.individual.quad.max_index = idct->quad.max_index;
buffer->vertex_bufs.individual.quad.buffer_offset = idct->quad.buffer_offset;
pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, idct->quad.buffer);
@@ -526,6 +525,7 @@ vl_idct_upload_matrix(struct pipe_context *pipe)
template.width0 = 2;
template.height0 = 8;
template.depth0 = 1;
+ template.array_size = 1;
template.usage = PIPE_USAGE_IMMUTABLE;
template.bind = PIPE_BIND_SAMPLER_VIEW;
template.flags = 0;
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index de83b6a5338..484e781f0cb 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -888,6 +888,7 @@ vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg1
template.width0 = renderer->buffer_width;
template.height0 = renderer->buffer_height;
template.depth0 = 1;
+ template.array_size = 1;
template.usage = PIPE_USAGE_STATIC;
template.bind = PIPE_BIND_SAMPLER_VIEW;
template.flags = 0;
@@ -928,7 +929,6 @@ vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg1
}
buffer->vertex_bufs.individual.quad.stride = renderer->quad.stride;
- buffer->vertex_bufs.individual.quad.max_index = renderer->quad.max_index;
buffer->vertex_bufs.individual.quad.buffer_offset = renderer->quad.buffer_offset;
pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, renderer->quad.buffer);
diff --git a/src/gallium/auxiliary/vl/vl_vertex_buffers.c b/src/gallium/auxiliary/vl/vl_vertex_buffers.c
index 8599ed3533d..552a0451fef 100644
--- a/src/gallium/auxiliary/vl/vl_vertex_buffers.c
+++ b/src/gallium/auxiliary/vl/vl_vertex_buffers.c
@@ -53,12 +53,12 @@ vl_vb_upload_quads(struct pipe_context *pipe, unsigned max_blocks)
/* create buffer */
quad.stride = sizeof(struct vertex2f);
- quad.max_index = 4 * max_blocks - 1;
quad.buffer_offset = 0;
quad.buffer = pipe_buffer_create
(
pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STATIC,
sizeof(struct vertex2f) * 4 * max_blocks
);
@@ -100,7 +100,7 @@ unsigned
vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements,
unsigned vertex_buffer_index)
{
- unsigned i, size, offset = 0;
+ unsigned i, offset = 0;
assert(elements && num_elements);
@@ -126,12 +126,12 @@ vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe,
buffer->stride = stride;
buf.stride = stride;
- buf.max_index = 4 * max_blocks - 1;
buf.buffer_offset = 0;
buf.buffer = pipe_buffer_create
(
pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
stride * 4 * max_blocks
);