summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c')
-rw-r--r--lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c188
1 files changed, 111 insertions, 77 deletions
diff --git a/lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c b/lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c
index fd6c49aac..3428eed4e 100644
--- a/lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/lib/mesa/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -134,7 +134,7 @@ generate_quad_mask(struct gallivm_state *gallivm,
* XXX: We'll need a different path for 16 x u8
*/
assert(fs_type.width == 32);
- assert(fs_type.length <= Elements(bits));
+ assert(fs_type.length <= ARRAY_SIZE(bits));
mask_type = lp_int_type(fs_type);
/*
@@ -238,6 +238,54 @@ lp_llvm_viewport(LLVMValueRef context_ptr,
}
+static LLVMValueRef
+lp_build_depth_clamp(struct gallivm_state *gallivm,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ LLVMValueRef context_ptr,
+ LLVMValueRef thread_data_ptr,
+ LLVMValueRef z)
+{
+ LLVMValueRef viewport, min_depth, max_depth;
+ LLVMValueRef viewport_index;
+ struct lp_build_context f32_bld;
+
+ assert(type.floating);
+ lp_build_context_init(&f32_bld, gallivm, type);
+
+ /*
+ * Assumes clamping of the viewport index will occur in setup/gs. Value
+ * is passed through the rasterization stage via lp_rast_shader_inputs.
+ *
+ * See: draw_clamp_viewport_idx and lp_clamp_viewport_idx for clamping
+ * semantics.
+ */
+ viewport_index = lp_jit_thread_data_raster_state_viewport_index(gallivm,
+ thread_data_ptr);
+
+ /*
+ * Load the min and max depth from the lp_jit_context.viewports
+ * array of lp_jit_viewport structures.
+ */
+ viewport = lp_llvm_viewport(context_ptr, gallivm, viewport_index);
+
+ /* viewports[viewport_index].min_depth */
+ min_depth = LLVMBuildExtractElement(builder, viewport,
+ lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MIN_DEPTH), "");
+ min_depth = lp_build_broadcast_scalar(&f32_bld, min_depth);
+
+ /* viewports[viewport_index].max_depth */
+ max_depth = LLVMBuildExtractElement(builder, viewport,
+ lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MAX_DEPTH), "");
+ max_depth = lp_build_broadcast_scalar(&f32_bld, max_depth);
+
+ /*
+ * Clamp to the min and max depth values for the given viewport.
+ */
+ return lp_build_clamp(&f32_bld, z, min_depth, max_depth);
+}
+
+
/**
* Generate the fragment shader, depth/stencil test, and alpha tests.
*/
@@ -383,6 +431,13 @@ generate_fs_loop(struct gallivm_state *gallivm,
z = interp->pos[2];
if (depth_mode & EARLY_DEPTH_TEST) {
+ /*
+ * Clamp according to ARB_depth_clamp semantics.
+ */
+ if (key->depth_clamp) {
+ z = lp_build_depth_clamp(gallivm, builder, type, context_ptr,
+ thread_data_ptr, z);
+ }
lp_build_depth_stencil_load_swizzled(gallivm, type,
zs_format_desc, key->resource_1d,
depth_ptr, depth_stride,
@@ -421,7 +476,7 @@ generate_fs_loop(struct gallivm_state *gallivm,
lp_build_tgsi_soa(gallivm, tokens, type, &mask,
consts_ptr, num_consts_ptr, &system_values,
interp->inputs,
- outputs, context_ptr,
+ outputs, context_ptr, thread_data_ptr,
sampler, &shader->info.base, NULL);
/* Alpha test */
@@ -471,51 +526,13 @@ generate_fs_loop(struct gallivm_state *gallivm,
0);
if (pos0 != -1 && outputs[pos0][2]) {
z = LLVMBuildLoad(builder, outputs[pos0][2], "output.z");
-
- /*
- * Clamp according to ARB_depth_clamp semantics.
- */
- if (key->depth_clamp) {
- LLVMValueRef viewport, min_depth, max_depth;
- LLVMValueRef viewport_index;
- struct lp_build_context f32_bld;
-
- assert(type.floating);
- lp_build_context_init(&f32_bld, gallivm, type);
-
- /*
- * Assumes clamping of the viewport index will occur in setup/gs. Value
- * is passed through the rasterization stage via lp_rast_shader_inputs.
- *
- * See: draw_clamp_viewport_idx and lp_clamp_viewport_idx for clamping
- * semantics.
- */
- viewport_index = lp_jit_thread_data_raster_state_viewport_index(gallivm,
- thread_data_ptr);
-
- /*
- * Load the min and max depth from the lp_jit_context.viewports
- * array of lp_jit_viewport structures.
- */
- viewport = lp_llvm_viewport(context_ptr, gallivm, viewport_index);
-
- /* viewports[viewport_index].min_depth */
- min_depth = LLVMBuildExtractElement(builder, viewport,
- lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MIN_DEPTH),
- "");
- min_depth = lp_build_broadcast_scalar(&f32_bld, min_depth);
-
- /* viewports[viewport_index].max_depth */
- max_depth = LLVMBuildExtractElement(builder, viewport,
- lp_build_const_int32(gallivm, LP_JIT_VIEWPORT_MAX_DEPTH),
- "");
- max_depth = lp_build_broadcast_scalar(&f32_bld, max_depth);
-
- /*
- * Clamp to the min and max depth values for the given viewport.
- */
- z = lp_build_clamp(&f32_bld, z, min_depth, max_depth);
- }
+ }
+ /*
+ * Clamp according to ARB_depth_clamp semantics.
+ */
+ if (key->depth_clamp) {
+ z = lp_build_depth_clamp(gallivm, builder, type, context_ptr,
+ thread_data_ptr, z);
}
if (s_out != -1 && outputs[s_out][1]) {
@@ -646,7 +663,7 @@ generate_fs_twiddle(struct gallivm_state *gallivm,
src_count = num_fs * src_channels;
assert(pixels == 2 || pixels == 1);
- assert(num_fs * src_channels <= Elements(src));
+ assert(num_fs * src_channels <= ARRAY_SIZE(src));
/*
* Transpose from SoA -> AoS
@@ -786,7 +803,7 @@ load_unswizzled_block(struct gallivm_state *gallivm,
dst[i] = LLVMBuildLoad(builder, dst_ptr, "");
- lp_set_load_alignment(dst[i], dst_alignment);
+ LLVMSetAlignment(dst[i], dst_alignment);
}
}
@@ -830,7 +847,7 @@ store_unswizzled_block(struct gallivm_state *gallivm,
src_ptr = LLVMBuildStore(builder, src[i], src_ptr);
- lp_set_store_alignment(src_ptr, src_alignment);
+ LLVMSetAlignment(src_ptr, src_alignment);
}
}
@@ -1601,7 +1618,7 @@ generate_unswizzled_blend(struct gallivm_state *gallivm,
LLVMValueRef fs_src[4][TGSI_NUM_CHANNELS];
LLVMValueRef fs_src1[4][TGSI_NUM_CHANNELS];
LLVMValueRef src_alpha[4 * 4];
- LLVMValueRef src1_alpha[4 * 4];
+ LLVMValueRef src1_alpha[4 * 4] = { NULL };
LLVMValueRef src_mask[4 * 4];
LLVMValueRef src[4 * 4];
LLVMValueRef src1[4 * 4];
@@ -2267,7 +2284,7 @@ generate_fragment(struct llvmpipe_context *lp,
arg_types[12] = int32_type; /* depth_stride */
func_type = LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context),
- arg_types, Elements(arg_types), 0);
+ arg_types, ARRAY_SIZE(arg_types), 0);
function = LLVMAddFunction(gallivm->module, func_name, func_type);
LLVMSetFunctionCallConv(function, LLVMCCallConv);
@@ -2277,7 +2294,7 @@ generate_fragment(struct llvmpipe_context *lp,
/* XXX: need to propagate noalias down into color param now we are
* passing a pointer-to-pointer?
*/
- for(i = 0; i < Elements(arg_types); ++i)
+ for(i = 0; i < ARRAY_SIZE(arg_types); ++i)
if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
LLVMAddAttribute(LLVMGetParam(function, i), LLVMNoAliasAttribute);
@@ -2303,8 +2320,8 @@ generate_fragment(struct llvmpipe_context *lp,
lp_build_name(dady_ptr, "dady");
lp_build_name(color_ptr_ptr, "color_ptr_ptr");
lp_build_name(depth_ptr, "depth");
- lp_build_name(thread_data_ptr, "thread_data");
lp_build_name(mask_input, "mask_input");
+ lp_build_name(thread_data_ptr, "thread_data");
lp_build_name(stride_ptr, "stride_ptr");
lp_build_name(depth_stride, "depth_stride");
@@ -2344,6 +2361,7 @@ generate_fragment(struct llvmpipe_context *lp,
shader->info.base.num_inputs,
inputs,
pixel_center_integer,
+ key->depth_clamp,
builder, fs_type,
a0_ptr, dadx_ptr, dady_ptr,
x, y);
@@ -2563,7 +2581,7 @@ generate_variant(struct llvmpipe_context *lp,
char module_name[64];
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
- if(!variant)
+ if (!variant)
return NULL;
util_snprintf(module_name, sizeof(module_name), "fs%u_variant%u",
@@ -2695,34 +2713,35 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
switch (shader->info.base.input_interpolate[i]) {
case TGSI_INTERPOLATE_CONSTANT:
- shader->inputs[i].interp = LP_INTERP_CONSTANT;
- break;
+ shader->inputs[i].interp = LP_INTERP_CONSTANT;
+ break;
case TGSI_INTERPOLATE_LINEAR:
- shader->inputs[i].interp = LP_INTERP_LINEAR;
- break;
+ shader->inputs[i].interp = LP_INTERP_LINEAR;
+ break;
case TGSI_INTERPOLATE_PERSPECTIVE:
- shader->inputs[i].interp = LP_INTERP_PERSPECTIVE;
- break;
+ shader->inputs[i].interp = LP_INTERP_PERSPECTIVE;
+ break;
case TGSI_INTERPOLATE_COLOR:
- shader->inputs[i].interp = LP_INTERP_COLOR;
- break;
+ shader->inputs[i].interp = LP_INTERP_COLOR;
+ break;
default:
- assert(0);
- break;
+ assert(0);
+ break;
}
switch (shader->info.base.input_semantic_name[i]) {
case TGSI_SEMANTIC_FACE:
- shader->inputs[i].interp = LP_INTERP_FACING;
- break;
+ shader->inputs[i].interp = LP_INTERP_FACING;
+ break;
case TGSI_SEMANTIC_POSITION:
- /* Position was already emitted above
- */
- shader->inputs[i].interp = LP_INTERP_POSITION;
- shader->inputs[i].src_index = 0;
- continue;
+ /* Position was already emitted above
+ */
+ shader->inputs[i].interp = LP_INTERP_POSITION;
+ shader->inputs[i].src_index = 0;
+ continue;
}
+ /* XXX this is a completely pointless index map... */
shader->inputs[i].src_index = i+1;
}
@@ -2835,17 +2854,24 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
static void
llvmpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_constant_buffer *cb)
+ const struct pipe_constant_buffer *cb)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct pipe_resource *constants = cb ? cb->buffer : NULL;
assert(shader < PIPE_SHADER_TYPES);
- assert(index < Elements(llvmpipe->constants[shader]));
+ assert(index < ARRAY_SIZE(llvmpipe->constants[shader]));
/* note: reference counting */
util_copy_constant_buffer(&llvmpipe->constants[shader][index], cb);
+ if (constants) {
+ if (!(constants->bind & PIPE_BIND_CONSTANT_BUFFER)) {
+ debug_printf("Illegal set constant without bind flag\n");
+ constants->bind |= PIPE_BIND_CONSTANT_BUFFER;
+ }
+ }
+
if (shader == PIPE_SHADER_VERTEX ||
shader == PIPE_SHADER_GEOMETRY) {
/* Pass the constants to the 'draw' module */
@@ -2868,8 +2894,9 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
draw_set_mapped_constant_buffer(llvmpipe->draw, shader,
index, data, size);
}
-
- llvmpipe->dirty |= LP_NEW_CONSTANTS;
+ else {
+ llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
+ }
if (cb && cb->user_buffer) {
pipe_resource_reference(&constants, NULL);
@@ -2940,6 +2967,13 @@ make_variant_key(struct llvmpipe_context *lp,
* depth_clip == 0 implies depth clamping is enabled.
*
* When clip_halfz is enabled, then always clamp the depth values.
+ *
+ * XXX: This is incorrect for GL, but correct for d3d10 (depth
+ * clamp is always active in d3d10, regardless if depth clip is
+ * enabled or not).
+ * (GL has an always-on [0,1] clamp on fs depth output instead
+ * to ensure the depth values stay in range. Doesn't look like
+ * we do that, though...)
*/
if (lp->rasterizer->clip_halfz) {
key->depth_clamp = 1;
@@ -3026,7 +3060,7 @@ make_variant_key(struct llvmpipe_context *lp,
* Also, force rgb/alpha func/factors match, to make AoS blending
* easier.
*/
- if (format_desc->swizzle[3] > UTIL_FORMAT_SWIZZLE_W ||
+ if (format_desc->swizzle[3] > PIPE_SWIZZLE_W ||
format_desc->swizzle[3] == format_desc->swizzle[0]) {
/* Doesn't cover mixed snorm/unorm but can't render to them anyway */
boolean clamped_zero = !util_format_is_float(format) &&