-/*****************************************************************************
- * The emission of draw packets for r300 which take care of the two-sided *
- * stencil ref fallback and call r500's functions. *
- ****************************************************************************/
-
-/* Set drawing for front faces. */
-static void r300_begin_stencil_ref_fallback(struct r300_context *r300)
-{
- struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
- CS_LOCALS(r300);
-
- BEGIN_CS(2);
- OUT_CS_REG(R300_SU_CULL_MODE, rs->cull_mode | R300_CULL_BACK);
- END_CS;
-}
-
-/* Set drawing for back faces. */
-static void r300_switch_stencil_ref_side(struct r300_context *r300)
-{
- struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
- struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
- CS_LOCALS(r300);
-
- BEGIN_CS(4);
- OUT_CS_REG(R300_SU_CULL_MODE, rs->cull_mode | R300_CULL_FRONT);
- OUT_CS_REG(R300_ZB_STENCILREFMASK,
- dsa->stencil_ref_bf | r300->stencil_ref.ref_value[1]);
- END_CS;
-}
-
-/* Restore the original state. */
-static void r300_end_stencil_ref_fallback(struct r300_context *r300)
-{
- struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
- struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
- CS_LOCALS(r300);
-
- BEGIN_CS(4);
- OUT_CS_REG(R300_SU_CULL_MODE, rs->cull_mode);
- OUT_CS_REG(R300_ZB_STENCILREFMASK,
- dsa->stencil_ref_mask | r300->stencil_ref.ref_value[0]);
- END_CS;
-}
-
-static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
- unsigned mode,
- unsigned start,
- unsigned count)
-{
- if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_arrays_immediate(r300, mode, start, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_arrays_immediate(r300, mode, start, count);
- r300_switch_stencil_ref_side(r300);
- r500_emit_draw_arrays_immediate(r300, mode, start, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
-
-static void r300_emit_draw_arrays(struct r300_context *r300,
- unsigned mode,
- unsigned count)
-{
- if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_arrays(r300, mode, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_arrays(r300, mode, count);
- r300_switch_stencil_ref_side(r300);
- r500_emit_draw_arrays(r300, mode, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
-
-static void r300_emit_draw_elements(struct r300_context *r300,
- struct pipe_resource* indexBuffer,
- unsigned indexSize,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count)
-{
- if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count);
- r300_switch_stencil_ref_side(r300);
- r500_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
-
-static void r300_shorten_ubyte_elts(struct r300_context* r300,
- struct pipe_resource** elts,
- unsigned start,
- unsigned count)
-{
- struct pipe_context* context = &r300->context;
- struct pipe_screen* screen = r300->context.screen;
- struct pipe_resource* new_elts;
- unsigned char *in_map;
- unsigned short *out_map;
- struct pipe_transfer *src_transfer, *dst_transfer;
- unsigned i;
-
- new_elts = pipe_buffer_create(screen,
- PIPE_BIND_INDEX_BUFFER,
- 2 * count);
-
- in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer);
- out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer);
-
- in_map += start;
-
- for (i = 0; i < count; i++) {
- *out_map = (unsigned short)*in_map;
- in_map++;
- out_map++;
- }
-
- pipe_buffer_unmap(context, *elts, src_transfer);
- pipe_buffer_unmap(context, new_elts, dst_transfer);
-
- *elts = new_elts;
-}
-
-static void r300_align_ushort_elts(struct r300_context *r300,
- struct pipe_resource **elts,
- unsigned start, unsigned count)
-{
- struct pipe_context* context = &r300->context;
- struct pipe_transfer *in_transfer = NULL;
- struct pipe_transfer *out_transfer = NULL;
- struct pipe_resource* new_elts;
- unsigned short *in_map;
- unsigned short *out_map;
-
- new_elts = pipe_buffer_create(context->screen,
- PIPE_BIND_INDEX_BUFFER,
- 2 * count);
-
- in_map = pipe_buffer_map(context, *elts,
- PIPE_TRANSFER_READ, &in_transfer);
- out_map = pipe_buffer_map(context, new_elts,
- PIPE_TRANSFER_WRITE, &out_transfer);
-
- memcpy(out_map, in_map+start, 2 * count);
-
- pipe_buffer_unmap(context, *elts, in_transfer);
- pipe_buffer_unmap(context, new_elts, out_transfer);
-
- *elts = new_elts;
-}
-