gallium: add facilities for indirect drawing
v2: Added comments to util_draw_indirect, clarified and fixed map size. Removed unlikely().
This commit is contained in:

committed by
Marek Olšák

parent
a27b3582a6
commit
bc198f8e63
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
|
#include "util/u_inlines.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
#include "util/u_format.h"
|
#include "util/u_format.h"
|
||||||
#include "util/u_draw.h"
|
#include "util/u_draw.h"
|
||||||
@@ -123,3 +124,45 @@ util_draw_max_index(
|
|||||||
|
|
||||||
return max_index + 1;
|
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);
|
||||||
|
}
|
||||||
|
@@ -142,6 +142,14 @@ util_draw_range_elements(struct pipe_context *pipe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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
|
unsigned
|
||||||
util_draw_max_index(
|
util_draw_max_index(
|
||||||
const struct pipe_vertex_buffer *vertex_buffers,
|
const struct pipe_vertex_buffer *vertex_buffers,
|
||||||
|
@@ -759,6 +759,9 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
|
|||||||
|
|
||||||
util_dump_member(stream, ptr, state, count_from_stream_output);
|
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);
|
util_dump_struct_end(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -208,6 +208,9 @@ The integer capabilities:
|
|||||||
* ``PIPE_CAP_MAX_VERTEX_STREAMS``: The maximum number of vertex streams
|
* ``PIPE_CAP_MAX_VERTEX_STREAMS``: The maximum number of vertex streams
|
||||||
supported by the geometry shader. If stream-out is supported, this should be
|
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.
|
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:
|
.. _pipe_capf:
|
||||||
|
@@ -215,6 +215,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_SAMPLE_SHADING:
|
case PIPE_CAP_SAMPLE_SHADING:
|
||||||
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
||||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Stream output. */
|
/* Stream output. */
|
||||||
|
@@ -232,6 +232,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
|
|||||||
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||||
case PIPE_CAP_TGSI_VS_LAYER:
|
case PIPE_CAP_TGSI_VS_LAYER:
|
||||||
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
|
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
|
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
|
#include "util/u_draw.h"
|
||||||
#include "util/u_prim.h"
|
#include "util/u_prim.h"
|
||||||
|
|
||||||
#include "lp_context.h"
|
#include "lp_context.h"
|
||||||
@@ -60,6 +61,11 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||||||
if (!llvmpipe_check_render_cond(lp))
|
if (!llvmpipe_check_render_cond(lp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (info->indirect) {
|
||||||
|
util_draw_indirect(pipe, info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (lp->dirty)
|
if (lp->dirty)
|
||||||
llvmpipe_update_derived( lp );
|
llvmpipe_update_derived( lp );
|
||||||
|
|
||||||
|
@@ -217,6 +217,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||||
case PIPE_CAP_TGSI_TEXCOORD:
|
case PIPE_CAP_TGSI_TEXCOORD:
|
||||||
return 0;
|
return 0;
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
|
return 1;
|
||||||
|
|
||||||
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
|
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
|
||||||
return 16;
|
return 16;
|
||||||
|
@@ -147,6 +147,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||||
case PIPE_CAP_USER_VERTEX_BUFFERS:
|
case PIPE_CAP_USER_VERTEX_BUFFERS:
|
||||||
case PIPE_CAP_COMPUTE:
|
case PIPE_CAP_COMPUTE:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -199,6 +199,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
||||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||||
case PIPE_CAP_COMPUTE:
|
case PIPE_CAP_COMPUTE:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -177,6 +177,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_SAMPLE_SHADING:
|
case PIPE_CAP_SAMPLE_SHADING:
|
||||||
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
||||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* SWTCL-only features. */
|
/* SWTCL-only features. */
|
||||||
|
@@ -317,6 +317,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_TEXTURE_QUERY_LOD:
|
case PIPE_CAP_TEXTURE_QUERY_LOD:
|
||||||
case PIPE_CAP_SAMPLE_SHADING:
|
case PIPE_CAP_SAMPLE_SHADING:
|
||||||
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Stream output. */
|
/* Stream output. */
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
#include "util/u_inlines.h"
|
#include "util/u_inlines.h"
|
||||||
|
#include "util/u_draw.h"
|
||||||
#include "util/u_prim.h"
|
#include "util/u_prim.h"
|
||||||
|
|
||||||
#include "sp_context.h"
|
#include "sp_context.h"
|
||||||
@@ -67,6 +68,11 @@ softpipe_draw_vbo(struct pipe_context *pipe,
|
|||||||
if (!softpipe_check_render_cond(sp))
|
if (!softpipe_check_render_cond(sp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (info->indirect) {
|
||||||
|
util_draw_indirect(pipe, info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sp->reduced_api_prim = u_reduced_prim(info->mode);
|
sp->reduced_api_prim = u_reduced_prim(info->mode);
|
||||||
|
|
||||||
if (sp->dirty) {
|
if (sp->dirty) {
|
||||||
|
@@ -200,6 +200,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
|
case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
|
||||||
case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
|
case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
|
||||||
return 0;
|
return 0;
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
/* should only get here on unhandled cases */
|
/* should only get here on unhandled cases */
|
||||||
debug_printf("Unexpected PIPE_CAP %d query\n", param);
|
debug_printf("Unexpected PIPE_CAP %d query\n", param);
|
||||||
|
@@ -277,6 +277,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_SAMPLE_SHADING:
|
case PIPE_CAP_SAMPLE_SHADING:
|
||||||
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
|
||||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||||
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
|
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
|
||||||
return 64;
|
return 64;
|
||||||
|
@@ -718,6 +718,9 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
|
|||||||
|
|
||||||
trace_dump_member(ptr, state, count_from_stream_output);
|
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();
|
trace_dump_struct_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -561,6 +561,7 @@ enum pipe_cap {
|
|||||||
PIPE_CAP_TEXTURE_GATHER_OFFSETS = 98,
|
PIPE_CAP_TEXTURE_GATHER_OFFSETS = 98,
|
||||||
PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99,
|
PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION = 99,
|
||||||
PIPE_CAP_MAX_VERTEX_STREAMS = 100,
|
PIPE_CAP_MAX_VERTEX_STREAMS = 100,
|
||||||
|
PIPE_CAP_DRAW_INDIRECT = 101,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
|
#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
|
||||||
|
@@ -570,6 +570,28 @@ struct pipe_draw_info
|
|||||||
* be set via set_vertex_buffers manually.
|
* be set via set_vertex_buffers manually.
|
||||||
*/
|
*/
|
||||||
struct pipe_stream_output_target *count_from_stream_output;
|
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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user