#endif
draw->pipe = pipe;
+ draw->constant_buffer_stride = (sizeof(float) * 4);
if (!draw_init(draw))
goto err_destroy;
draw->disk_cache_find_shader = find_shader;
draw->disk_cache_insert_shader = insert_shader;
draw->disk_cache_cookie = data_cookie;
+}
+void draw_set_constant_buffer_stride(struct draw_context *draw, unsigned num_bytes)
+{
+ draw->constant_buffer_stride = num_bytes;
}
void draw_set_zs_format(struct draw_context *draw, enum pipe_format format);
+/* for TGSI constants are 4 * sizeof(float), but for NIR they need to be sizeof(float); */
+void draw_set_constant_buffer_stride(struct draw_context *draw, unsigned num_bytes);
+
boolean
draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe);
unsigned instance_id;
unsigned start_instance;
unsigned start_index;
-
+ unsigned constant_buffer_stride;
struct draw_llvm *llvm;
/** Texture sampler and sampler view state.
}
}
+static unsigned
+get_num_consts_robust(struct draw_context *draw, unsigned *sizes, unsigned idx)
+{
+ unsigned const_bytes = sizes[idx];
+
+ if (const_bytes < sizeof(float))
+ return 0;
+
+ return DIV_ROUND_UP(const_bytes, draw->constant_buffer_stride);
+}
/**
* Bind/update constant buffer pointers, clip planes and viewport dims.
* shader expects 16-byte allocations, the fix is likely to move
* to LOAD intrinsic in the future and remove the vec4 constraint.
*/
- int num_consts =
- DIV_ROUND_UP(draw->pt.user.vs_constants_size[i], (sizeof(float) * 4));
+ int num_consts = get_num_consts_robust(draw, draw->pt.user.vs_constants_size, i);
llvm->jit_context.vs_constants[i] = draw->pt.user.vs_constants[i];
llvm->jit_context.num_vs_constants[i] = num_consts;
if (num_consts == 0) {
}
for (i = 0; i < ARRAY_SIZE(llvm->gs_jit_context.constants); ++i) {
- int num_consts =
- DIV_ROUND_UP(draw->pt.user.gs_constants_size[i], (sizeof(float) * 4));
+ int num_consts = get_num_consts_robust(draw, draw->pt.user.gs_constants_size, i);
llvm->gs_jit_context.constants[i] = draw->pt.user.gs_constants[i];
llvm->gs_jit_context.num_constants[i] = num_consts;
if (num_consts == 0) {
}
for (i = 0; i < ARRAY_SIZE(llvm->tcs_jit_context.constants); ++i) {
- int num_consts =
- DIV_ROUND_UP(draw->pt.user.tcs_constants_size[i], (sizeof(float) * 4));
+ int num_consts = get_num_consts_robust(draw, draw->pt.user.tcs_constants_size, i);
llvm->tcs_jit_context.constants[i] = draw->pt.user.tcs_constants[i];
llvm->tcs_jit_context.num_constants[i] = num_consts;
if (num_consts == 0) {
}
for (i = 0; i < ARRAY_SIZE(llvm->tes_jit_context.constants); ++i) {
- int num_consts =
- DIV_ROUND_UP(draw->pt.user.tes_constants_size[i], (sizeof(float) * 4));
+ int num_consts = get_num_consts_robust(draw, draw->pt.user.tes_constants_size, i);
llvm->tes_jit_context.constants[i] = draw->pt.user.tes_constants[i];
llvm->tes_jit_context.num_constants[i] = num_consts;
if (num_consts == 0) {
LLVMValueRef overflow_mask;
LLVMValueRef num_consts = lp_build_array_get(gallivm, bld->const_sizes_ptr, index);
- num_consts = LLVMBuildShl(gallivm->builder, num_consts, lp_build_const_int32(gallivm, 4), "");
num_consts = lp_build_broadcast_scalar(uint_bld, num_consts);
for (unsigned c = 0; c < nc; c++) {
LLVMValueRef this_offset = lp_build_add(uint_bld, offset, lp_build_const_int_vec(gallivm, uint_bld->type, c));
overflow_mask = lp_build_compare(gallivm, uint_bld->type, PIPE_FUNC_GEQUAL,
this_offset, num_consts);
-
result[c] = build_gather(bld_base, bld_broad, consts_ptr, this_offset, overflow_mask, NULL);
}
}
#include "lp_query.h"
#include "lp_setup.h"
#include "lp_screen.h"
+
/* This is only safe if there's just one concurrent context */
#ifdef EMBEDDED_DEVICE
#define USE_GLOBAL_LLVM_CONTEXT
llvmpipe_screen(screen),
lp_draw_disk_cache_find_shader,
lp_draw_disk_cache_insert_shader);
+
+ draw_set_constant_buffer_stride(llvmpipe->draw, lp_get_constant_buffer_stride(screen));
+
/* FIXME: devise alternative to draw_texture_samplers */
llvmpipe->setup = lp_setup_create( &llvmpipe->pipe,
return (struct llvmpipe_screen *)pipe;
}
-
+static inline unsigned lp_get_constant_buffer_stride(struct pipe_screen *_screen)
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ return screen->use_tgsi ? (sizeof(float) * 4) : sizeof(float);
+}
#endif /* LP_SCREEN_H */
current_data = (ubyte *) setup->constants[i].current.user_buffer;
}
- if (current_data) {
+ if (current_data && current_size >= sizeof(float)) {
current_data += setup->constants[i].current.buffer_offset;
/* TODO: copy only the actually used constants? */
}
num_constants =
- DIV_ROUND_UP(setup->constants[i].stored_size, (sizeof(float) * 4));
+ DIV_ROUND_UP(setup->constants[i].stored_size, lp_get_constant_buffer_stride(scene->pipe->screen));
setup->fs.current.jit_context.num_constants[i] = num_constants;
setup->dirty |= LP_SETUP_NEW_FS;
}
for (i = 0; i < ARRAY_SIZE(csctx->constants); ++i) {
struct pipe_resource *buffer = csctx->constants[i].current.buffer;
const ubyte *current_data = NULL;
-
+ unsigned current_size = csctx->constants[i].current.buffer_size;
if (buffer) {
/* resource buffer */
current_data = (ubyte *) llvmpipe_resource_data(buffer);
current_data = (ubyte *) csctx->constants[i].current.user_buffer;
}
- if (current_data) {
+ if (current_data && current_size >= sizeof(float)) {
current_data += csctx->constants[i].current.buffer_offset;
-
csctx->cs.current.jit_context.constants[i] = (const float *)current_data;
- csctx->cs.current.jit_context.num_constants[i] = csctx->constants[i].current.buffer_size;
+ csctx->cs.current.jit_context.num_constants[i] =
+ DIV_ROUND_UP(csctx->constants[i].current.buffer_size,
+ lp_get_constant_buffer_stride(llvmpipe->pipe.screen));
} else {
- csctx->cs.current.jit_context.constants[i] = NULL;
+ static const float fake_const_buf[4];
+ csctx->cs.current.jit_context.constants[i] = fake_const_buf;
csctx->cs.current.jit_context.num_constants[i] = 0;
}
}