#include "util/u_debug.h"
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_draw.h"
return max_index + 1;
}
+
+
+/* This extracts the draw arguments from the info_in->indirect resource,
+ * puts them into a new instance of pipe_draw_info, and calls draw_vbo on it.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+ const struct pipe_draw_info *info_in)
+{
+ struct pipe_draw_info info;
+ struct pipe_transfer *transfer;
+ uint32_t *params;
+ const unsigned num_params = info_in->indexed ? 5 : 4;
+
+ assert(info_in->indirect);
+ assert(!info_in->count_from_stream_output);
+
+ memcpy(&info, info_in, sizeof(info));
+
+ params = (uint32_t *)
+ pipe_buffer_map_range(pipe,
+ info_in->indirect,
+ info_in->indirect_offset,
+ num_params * sizeof(uint32_t),
+ PIPE_TRANSFER_READ,
+ &transfer);
+ if (!transfer) {
+ debug_printf("%s: failed to map indirect buffer\n", __FUNCTION__);
+ return;
+ }
+
+ info.count = params[0];
+ info.instance_count = params[1];
+ info.start = params[2];
+ info.index_bias = info_in->indexed ? params[3] : 0;
+ info.start_instance = info_in->indexed ? params[4] : params[3];
+ info.indirect = NULL;
+
+ pipe_buffer_unmap(pipe, transfer);
+
+ pipe->draw_vbo(pipe, &info);
+}
}
+/* This converts an indirect draw into a direct draw by mapping the indirect
+ * buffer, extracting its arguments, and calling pipe->draw_vbo.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
+
+
unsigned
util_draw_max_index(
const struct pipe_vertex_buffer *vertex_buffers,
util_dump_member(stream, ptr, state, count_from_stream_output);
+ util_dump_member(stream, ptr, state, indirect);
+ util_dump_member(stream, uint, state, indirect_offset);
+
util_dump_struct_end(stream);
}
* ``PIPE_CAP_MAX_VERTEX_STREAMS``: The maximum number of vertex streams
supported by the geometry shader. If stream-out is supported, this should be
at least 1. If stream-out is not supported, this should be 0.
+* ``PIPE_CAP_DRAW_INDIRECT``: Whether the driver supports taking draw arguments
+ { count, instance_count, start, index_bias } from a PIPE_BUFFER resource.
+ See pipe_draw_info.
.. _pipe_capf:
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
/* Stream output. */
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_TGSI_VS_LAYER:
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
+#include "util/u_draw.h"
#include "util/u_prim.h"
#include "lp_context.h"
if (!llvmpipe_check_render_cond(lp))
return;
+ if (info->indirect) {
+ util_draw_indirect(pipe, info);
+ return;
+ }
+
if (lp->dirty)
llvmpipe_update_derived( lp );
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
case PIPE_CAP_TGSI_TEXCOORD:
return 0;
+ case PIPE_CAP_DRAW_INDIRECT:
+ return 1;
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
return 16;
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
case PIPE_CAP_USER_VERTEX_BUFFERS:
case PIPE_CAP_COMPUTE:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
}
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
case PIPE_CAP_COMPUTE:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
}
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
/* SWTCL-only features. */
case PIPE_CAP_TEXTURE_QUERY_LOD:
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
/* Stream output. */
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
+#include "util/u_draw.h"
#include "util/u_prim.h"
#include "sp_context.h"
if (!softpipe_check_render_cond(sp))
return;
+ if (info->indirect) {
+ util_draw_indirect(pipe, info);
+ return;
+ }
+
sp->reduced_api_prim = u_reduced_prim(info->mode);
if (sp->dirty) {
case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
return 0;
+ case PIPE_CAP_DRAW_INDIRECT:
+ return 1;
}
/* should only get here on unhandled cases */
debug_printf("Unexpected PIPE_CAP %d query\n", param);
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
+ case PIPE_CAP_DRAW_INDIRECT:
return 0;
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
return 64;
trace_dump_member(ptr, state, count_from_stream_output);
+ trace_dump_member(ptr, state, indirect);
+ trace_dump_member(uint, state, indirect_offset);
+
trace_dump_struct_end();
}
PIPE_CAP_TEXTURE_GATHER_OFFSETS = 98,
PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99,
PIPE_CAP_MAX_VERTEX_STREAMS = 100,
+ PIPE_CAP_DRAW_INDIRECT = 101,
};
#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
* be set via set_vertex_buffers manually.
*/
struct pipe_stream_output_target *count_from_stream_output;
+
+ /* Indirect parameters resource: If not NULL, most values are taken
+ * from this buffer instead, which is laid out as follows:
+ *
+ * if indexed is TRUE:
+ * struct {
+ * uint32_t count;
+ * uint32_t instance_count;
+ * uint32_t start;
+ * int32_t index_bias;
+ * uint32_t start_instance;
+ * };
+ * otherwise:
+ * struct {
+ * uint32_t count;
+ * uint32_t instance_count;
+ * uint32_t start;
+ * uint32_t start_instance;
+ * };
+ */
+ struct pipe_resource *indirect;
+ unsigned indirect_offset; /**< must be 4 byte aligned */
};