101e04c3fSmrg/* 201e04c3fSmrg * Copyright 2013 Advanced Micro Devices, Inc. 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2001e04c3fSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2101e04c3fSmrg * SOFTWARE. 2201e04c3fSmrg * 2301e04c3fSmrg * Authors: Marek Olšák <maraeo@gmail.com> 2401e04c3fSmrg * 2501e04c3fSmrg */ 2601e04c3fSmrg 2701e04c3fSmrg#include "r600_pipe_common.h" 2801e04c3fSmrg#include "r600_cs.h" 2901e04c3fSmrg 3001e04c3fSmrg#include "util/u_memory.h" 3101e04c3fSmrg#include "evergreend.h" 3201e04c3fSmrg 3301e04c3fSmrg#define R_008490_CP_STRMOUT_CNTL 0x008490 3401e04c3fSmrg#define R_028AB0_VGT_STRMOUT_EN 0x028AB0 3501e04c3fSmrg#define R_028B20_VGT_STRMOUT_BUFFER_EN 0x028B20 3601e04c3fSmrg 3701e04c3fSmrgstatic void r600_set_streamout_enable(struct r600_common_context *rctx, bool enable); 3801e04c3fSmrg 3901e04c3fSmrgstatic struct pipe_stream_output_target * 4001e04c3fSmrgr600_create_so_target(struct pipe_context *ctx, 4101e04c3fSmrg struct pipe_resource *buffer, 4201e04c3fSmrg unsigned buffer_offset, 4301e04c3fSmrg unsigned buffer_size) 4401e04c3fSmrg{ 4501e04c3fSmrg struct r600_common_context *rctx = (struct r600_common_context *)ctx; 4601e04c3fSmrg struct r600_so_target *t; 4701e04c3fSmrg struct r600_resource *rbuffer = (struct r600_resource*)buffer; 4801e04c3fSmrg 4901e04c3fSmrg t = CALLOC_STRUCT(r600_so_target); 5001e04c3fSmrg if (!t) { 5101e04c3fSmrg return NULL; 5201e04c3fSmrg } 5301e04c3fSmrg 547ec681f3Smrg u_suballocator_alloc(&rctx->allocator_zeroed_memory, 4, 4, 5501e04c3fSmrg &t->buf_filled_size_offset, 5601e04c3fSmrg (struct pipe_resource**)&t->buf_filled_size); 5701e04c3fSmrg if (!t->buf_filled_size) { 5801e04c3fSmrg FREE(t); 5901e04c3fSmrg return NULL; 6001e04c3fSmrg } 6101e04c3fSmrg 6201e04c3fSmrg t->b.reference.count = 1; 6301e04c3fSmrg t->b.context = ctx; 6401e04c3fSmrg pipe_resource_reference(&t->b.buffer, buffer); 6501e04c3fSmrg t->b.buffer_offset = buffer_offset; 6601e04c3fSmrg t->b.buffer_size = buffer_size; 6701e04c3fSmrg 687ec681f3Smrg util_range_add(buffer, &rbuffer->valid_buffer_range, buffer_offset, 6901e04c3fSmrg buffer_offset + buffer_size); 7001e04c3fSmrg return &t->b; 7101e04c3fSmrg} 7201e04c3fSmrg 7301e04c3fSmrgstatic void r600_so_target_destroy(struct pipe_context *ctx, 7401e04c3fSmrg struct pipe_stream_output_target *target) 7501e04c3fSmrg{ 7601e04c3fSmrg struct r600_so_target *t = (struct r600_so_target*)target; 7701e04c3fSmrg pipe_resource_reference(&t->b.buffer, NULL); 7801e04c3fSmrg r600_resource_reference(&t->buf_filled_size, NULL); 7901e04c3fSmrg FREE(t); 8001e04c3fSmrg} 8101e04c3fSmrg 8201e04c3fSmrgvoid r600_streamout_buffers_dirty(struct r600_common_context *rctx) 8301e04c3fSmrg{ 8401e04c3fSmrg struct r600_atom *begin = &rctx->streamout.begin_atom; 8501e04c3fSmrg unsigned num_bufs = util_bitcount(rctx->streamout.enabled_mask); 8601e04c3fSmrg unsigned num_bufs_appended = util_bitcount(rctx->streamout.enabled_mask & 8701e04c3fSmrg rctx->streamout.append_bitmask); 8801e04c3fSmrg 8901e04c3fSmrg if (!num_bufs) 9001e04c3fSmrg return; 9101e04c3fSmrg 9201e04c3fSmrg rctx->streamout.num_dw_for_end = 9301e04c3fSmrg 12 + /* flush_vgt_streamout */ 9401e04c3fSmrg num_bufs * 11; /* STRMOUT_BUFFER_UPDATE, BUFFER_SIZE */ 9501e04c3fSmrg 9601e04c3fSmrg begin->num_dw = 12; /* flush_vgt_streamout */ 9701e04c3fSmrg 9801e04c3fSmrg begin->num_dw += num_bufs * 7; /* SET_CONTEXT_REG */ 9901e04c3fSmrg 10001e04c3fSmrg if (rctx->family >= CHIP_RS780 && rctx->family <= CHIP_RV740) 10101e04c3fSmrg begin->num_dw += num_bufs * 5; /* STRMOUT_BASE_UPDATE */ 10201e04c3fSmrg 10301e04c3fSmrg begin->num_dw += 10401e04c3fSmrg num_bufs_appended * 8 + /* STRMOUT_BUFFER_UPDATE */ 10501e04c3fSmrg (num_bufs - num_bufs_appended) * 6 + /* STRMOUT_BUFFER_UPDATE */ 10601e04c3fSmrg (rctx->family > CHIP_R600 && rctx->family < CHIP_RS780 ? 2 : 0); /* SURFACE_BASE_UPDATE */ 10701e04c3fSmrg 10801e04c3fSmrg rctx->set_atom_dirty(rctx, begin, true); 10901e04c3fSmrg 11001e04c3fSmrg r600_set_streamout_enable(rctx, true); 11101e04c3fSmrg} 11201e04c3fSmrg 11301e04c3fSmrgvoid r600_set_streamout_targets(struct pipe_context *ctx, 11401e04c3fSmrg unsigned num_targets, 11501e04c3fSmrg struct pipe_stream_output_target **targets, 11601e04c3fSmrg const unsigned *offsets) 11701e04c3fSmrg{ 11801e04c3fSmrg struct r600_common_context *rctx = (struct r600_common_context *)ctx; 11901e04c3fSmrg unsigned i; 12001e04c3fSmrg unsigned enabled_mask = 0, append_bitmask = 0; 12101e04c3fSmrg 12201e04c3fSmrg /* Stop streamout. */ 12301e04c3fSmrg if (rctx->streamout.num_targets && rctx->streamout.begin_emitted) { 12401e04c3fSmrg r600_emit_streamout_end(rctx); 12501e04c3fSmrg } 12601e04c3fSmrg 12701e04c3fSmrg /* Set the new targets. */ 12801e04c3fSmrg for (i = 0; i < num_targets; i++) { 12901e04c3fSmrg pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], targets[i]); 13001e04c3fSmrg if (!targets[i]) 13101e04c3fSmrg continue; 13201e04c3fSmrg 13301e04c3fSmrg r600_context_add_resource_size(ctx, targets[i]->buffer); 13401e04c3fSmrg enabled_mask |= 1 << i; 13501e04c3fSmrg if (offsets[i] == ((unsigned)-1)) 13601e04c3fSmrg append_bitmask |= 1 << i; 13701e04c3fSmrg } 13801e04c3fSmrg for (; i < rctx->streamout.num_targets; i++) { 13901e04c3fSmrg pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], NULL); 14001e04c3fSmrg } 14101e04c3fSmrg 14201e04c3fSmrg rctx->streamout.enabled_mask = enabled_mask; 14301e04c3fSmrg 14401e04c3fSmrg rctx->streamout.num_targets = num_targets; 14501e04c3fSmrg rctx->streamout.append_bitmask = append_bitmask; 14601e04c3fSmrg 14701e04c3fSmrg if (num_targets) { 14801e04c3fSmrg r600_streamout_buffers_dirty(rctx); 14901e04c3fSmrg } else { 15001e04c3fSmrg rctx->set_atom_dirty(rctx, &rctx->streamout.begin_atom, false); 15101e04c3fSmrg r600_set_streamout_enable(rctx, false); 15201e04c3fSmrg } 15301e04c3fSmrg} 15401e04c3fSmrg 15501e04c3fSmrgstatic void r600_flush_vgt_streamout(struct r600_common_context *rctx) 15601e04c3fSmrg{ 1577ec681f3Smrg struct radeon_cmdbuf *cs = &rctx->gfx.cs; 15801e04c3fSmrg unsigned reg_strmout_cntl; 15901e04c3fSmrg 16001e04c3fSmrg /* The register is at different places on different ASICs. */ 16101e04c3fSmrg if (rctx->chip_class >= EVERGREEN) { 16201e04c3fSmrg reg_strmout_cntl = R_0084FC_CP_STRMOUT_CNTL; 16301e04c3fSmrg } else { 16401e04c3fSmrg reg_strmout_cntl = R_008490_CP_STRMOUT_CNTL; 16501e04c3fSmrg } 16601e04c3fSmrg 16701e04c3fSmrg radeon_set_config_reg(cs, reg_strmout_cntl, 0); 16801e04c3fSmrg 16901e04c3fSmrg radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); 17001e04c3fSmrg radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_SO_VGTSTREAMOUT_FLUSH) | EVENT_INDEX(0)); 17101e04c3fSmrg 17201e04c3fSmrg radeon_emit(cs, PKT3(PKT3_WAIT_REG_MEM, 5, 0)); 17301e04c3fSmrg radeon_emit(cs, WAIT_REG_MEM_EQUAL); /* wait until the register is equal to the reference value */ 17401e04c3fSmrg radeon_emit(cs, reg_strmout_cntl >> 2); /* register */ 17501e04c3fSmrg radeon_emit(cs, 0); 17601e04c3fSmrg radeon_emit(cs, S_0084FC_OFFSET_UPDATE_DONE(1)); /* reference value */ 17701e04c3fSmrg radeon_emit(cs, S_0084FC_OFFSET_UPDATE_DONE(1)); /* mask */ 17801e04c3fSmrg radeon_emit(cs, 4); /* poll interval */ 17901e04c3fSmrg} 18001e04c3fSmrg 18101e04c3fSmrgstatic void r600_emit_streamout_begin(struct r600_common_context *rctx, struct r600_atom *atom) 18201e04c3fSmrg{ 1837ec681f3Smrg struct radeon_cmdbuf *cs = &rctx->gfx.cs; 18401e04c3fSmrg struct r600_so_target **t = rctx->streamout.targets; 18501e04c3fSmrg uint16_t *stride_in_dw = rctx->streamout.stride_in_dw; 18601e04c3fSmrg unsigned i, update_flags = 0; 18701e04c3fSmrg 18801e04c3fSmrg r600_flush_vgt_streamout(rctx); 18901e04c3fSmrg 19001e04c3fSmrg for (i = 0; i < rctx->streamout.num_targets; i++) { 19101e04c3fSmrg if (!t[i]) 19201e04c3fSmrg continue; 19301e04c3fSmrg 19401e04c3fSmrg t[i]->stride_in_dw = stride_in_dw[i]; 19501e04c3fSmrg 19601e04c3fSmrg uint64_t va = r600_resource(t[i]->b.buffer)->gpu_address; 19701e04c3fSmrg 19801e04c3fSmrg update_flags |= SURFACE_BASE_UPDATE_STRMOUT(i); 19901e04c3fSmrg 20001e04c3fSmrg radeon_set_context_reg_seq(cs, R_028AD0_VGT_STRMOUT_BUFFER_SIZE_0 + 16*i, 3); 20101e04c3fSmrg radeon_emit(cs, (t[i]->b.buffer_offset + 20201e04c3fSmrg t[i]->b.buffer_size) >> 2); /* BUFFER_SIZE (in DW) */ 20301e04c3fSmrg radeon_emit(cs, stride_in_dw[i]); /* VTX_STRIDE (in DW) */ 20401e04c3fSmrg radeon_emit(cs, va >> 8); /* BUFFER_BASE */ 20501e04c3fSmrg 20601e04c3fSmrg r600_emit_reloc(rctx, &rctx->gfx, r600_resource(t[i]->b.buffer), 20701e04c3fSmrg RADEON_USAGE_WRITE, RADEON_PRIO_SHADER_RW_BUFFER); 20801e04c3fSmrg 20901e04c3fSmrg /* R7xx requires this packet after updating BUFFER_BASE. 21001e04c3fSmrg * Without this, R7xx locks up. */ 21101e04c3fSmrg if (rctx->family >= CHIP_RS780 && rctx->family <= CHIP_RV740) { 21201e04c3fSmrg radeon_emit(cs, PKT3(PKT3_STRMOUT_BASE_UPDATE, 1, 0)); 21301e04c3fSmrg radeon_emit(cs, i); 21401e04c3fSmrg radeon_emit(cs, va >> 8); 21501e04c3fSmrg 21601e04c3fSmrg r600_emit_reloc(rctx, &rctx->gfx, r600_resource(t[i]->b.buffer), 21701e04c3fSmrg RADEON_USAGE_WRITE, RADEON_PRIO_SHADER_RW_BUFFER); 21801e04c3fSmrg } 21901e04c3fSmrg 22001e04c3fSmrg if (rctx->streamout.append_bitmask & (1 << i) && t[i]->buf_filled_size_valid) { 22101e04c3fSmrg uint64_t va = t[i]->buf_filled_size->gpu_address + 22201e04c3fSmrg t[i]->buf_filled_size_offset; 22301e04c3fSmrg 22401e04c3fSmrg /* Append. */ 22501e04c3fSmrg radeon_emit(cs, PKT3(PKT3_STRMOUT_BUFFER_UPDATE, 4, 0)); 22601e04c3fSmrg radeon_emit(cs, STRMOUT_SELECT_BUFFER(i) | 22701e04c3fSmrg STRMOUT_OFFSET_SOURCE(STRMOUT_OFFSET_FROM_MEM)); /* control */ 22801e04c3fSmrg radeon_emit(cs, 0); /* unused */ 22901e04c3fSmrg radeon_emit(cs, 0); /* unused */ 23001e04c3fSmrg radeon_emit(cs, va); /* src address lo */ 23101e04c3fSmrg radeon_emit(cs, va >> 32); /* src address hi */ 23201e04c3fSmrg 23301e04c3fSmrg r600_emit_reloc(rctx, &rctx->gfx, t[i]->buf_filled_size, 23401e04c3fSmrg RADEON_USAGE_READ, RADEON_PRIO_SO_FILLED_SIZE); 23501e04c3fSmrg } else { 23601e04c3fSmrg /* Start from the beginning. */ 23701e04c3fSmrg radeon_emit(cs, PKT3(PKT3_STRMOUT_BUFFER_UPDATE, 4, 0)); 23801e04c3fSmrg radeon_emit(cs, STRMOUT_SELECT_BUFFER(i) | 23901e04c3fSmrg STRMOUT_OFFSET_SOURCE(STRMOUT_OFFSET_FROM_PACKET)); /* control */ 24001e04c3fSmrg radeon_emit(cs, 0); /* unused */ 24101e04c3fSmrg radeon_emit(cs, 0); /* unused */ 24201e04c3fSmrg radeon_emit(cs, t[i]->b.buffer_offset >> 2); /* buffer offset in DW */ 24301e04c3fSmrg radeon_emit(cs, 0); /* unused */ 24401e04c3fSmrg } 24501e04c3fSmrg } 24601e04c3fSmrg 24701e04c3fSmrg if (rctx->family > CHIP_R600 && rctx->family < CHIP_RV770) { 24801e04c3fSmrg radeon_emit(cs, PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0)); 24901e04c3fSmrg radeon_emit(cs, update_flags); 25001e04c3fSmrg } 25101e04c3fSmrg rctx->streamout.begin_emitted = true; 25201e04c3fSmrg} 25301e04c3fSmrg 25401e04c3fSmrgvoid r600_emit_streamout_end(struct r600_common_context *rctx) 25501e04c3fSmrg{ 2567ec681f3Smrg struct radeon_cmdbuf *cs = &rctx->gfx.cs; 25701e04c3fSmrg struct r600_so_target **t = rctx->streamout.targets; 25801e04c3fSmrg unsigned i; 25901e04c3fSmrg uint64_t va; 26001e04c3fSmrg 26101e04c3fSmrg r600_flush_vgt_streamout(rctx); 26201e04c3fSmrg 26301e04c3fSmrg for (i = 0; i < rctx->streamout.num_targets; i++) { 26401e04c3fSmrg if (!t[i]) 26501e04c3fSmrg continue; 26601e04c3fSmrg 26701e04c3fSmrg va = t[i]->buf_filled_size->gpu_address + t[i]->buf_filled_size_offset; 26801e04c3fSmrg radeon_emit(cs, PKT3(PKT3_STRMOUT_BUFFER_UPDATE, 4, 0)); 26901e04c3fSmrg radeon_emit(cs, STRMOUT_SELECT_BUFFER(i) | 27001e04c3fSmrg STRMOUT_OFFSET_SOURCE(STRMOUT_OFFSET_NONE) | 27101e04c3fSmrg STRMOUT_STORE_BUFFER_FILLED_SIZE); /* control */ 27201e04c3fSmrg radeon_emit(cs, va); /* dst address lo */ 27301e04c3fSmrg radeon_emit(cs, va >> 32); /* dst address hi */ 27401e04c3fSmrg radeon_emit(cs, 0); /* unused */ 27501e04c3fSmrg radeon_emit(cs, 0); /* unused */ 27601e04c3fSmrg 27701e04c3fSmrg r600_emit_reloc(rctx, &rctx->gfx, t[i]->buf_filled_size, 27801e04c3fSmrg RADEON_USAGE_WRITE, RADEON_PRIO_SO_FILLED_SIZE); 27901e04c3fSmrg 28001e04c3fSmrg /* Zero the buffer size. The counters (primitives generated, 28101e04c3fSmrg * primitives emitted) may be enabled even if there is not 28201e04c3fSmrg * buffer bound. This ensures that the primitives-emitted query 28301e04c3fSmrg * won't increment. */ 28401e04c3fSmrg radeon_set_context_reg(cs, R_028AD0_VGT_STRMOUT_BUFFER_SIZE_0 + 16*i, 0); 28501e04c3fSmrg 28601e04c3fSmrg t[i]->buf_filled_size_valid = true; 28701e04c3fSmrg } 28801e04c3fSmrg 28901e04c3fSmrg rctx->streamout.begin_emitted = false; 29001e04c3fSmrg rctx->flags |= R600_CONTEXT_STREAMOUT_FLUSH; 29101e04c3fSmrg} 29201e04c3fSmrg 29301e04c3fSmrg/* STREAMOUT CONFIG DERIVED STATE 29401e04c3fSmrg * 29501e04c3fSmrg * Streamout must be enabled for the PRIMITIVES_GENERATED query to work. 29601e04c3fSmrg * The buffer mask is an independent state, so no writes occur if there 29701e04c3fSmrg * are no buffers bound. 29801e04c3fSmrg */ 29901e04c3fSmrg 30001e04c3fSmrgstatic void r600_emit_streamout_enable(struct r600_common_context *rctx, 30101e04c3fSmrg struct r600_atom *atom) 30201e04c3fSmrg{ 30301e04c3fSmrg unsigned strmout_config_reg = R_028AB0_VGT_STRMOUT_EN; 30401e04c3fSmrg unsigned strmout_config_val = S_028B94_STREAMOUT_0_EN(r600_get_strmout_en(rctx)); 30501e04c3fSmrg unsigned strmout_buffer_reg = R_028B20_VGT_STRMOUT_BUFFER_EN; 30601e04c3fSmrg unsigned strmout_buffer_val = rctx->streamout.hw_enabled_mask & 30701e04c3fSmrg rctx->streamout.enabled_stream_buffers_mask; 30801e04c3fSmrg 30901e04c3fSmrg if (rctx->chip_class >= EVERGREEN) { 31001e04c3fSmrg strmout_buffer_reg = R_028B98_VGT_STRMOUT_BUFFER_CONFIG; 31101e04c3fSmrg 31201e04c3fSmrg strmout_config_reg = R_028B94_VGT_STRMOUT_CONFIG; 31301e04c3fSmrg strmout_config_val |= 31401e04c3fSmrg S_028B94_STREAMOUT_1_EN(r600_get_strmout_en(rctx)) | 31501e04c3fSmrg S_028B94_STREAMOUT_2_EN(r600_get_strmout_en(rctx)) | 31601e04c3fSmrg S_028B94_STREAMOUT_3_EN(r600_get_strmout_en(rctx)); 31701e04c3fSmrg } 3187ec681f3Smrg radeon_set_context_reg(&rctx->gfx.cs, strmout_buffer_reg, strmout_buffer_val); 3197ec681f3Smrg radeon_set_context_reg(&rctx->gfx.cs, strmout_config_reg, strmout_config_val); 32001e04c3fSmrg} 32101e04c3fSmrg 32201e04c3fSmrgstatic void r600_set_streamout_enable(struct r600_common_context *rctx, bool enable) 32301e04c3fSmrg{ 32401e04c3fSmrg bool old_strmout_en = r600_get_strmout_en(rctx); 32501e04c3fSmrg unsigned old_hw_enabled_mask = rctx->streamout.hw_enabled_mask; 32601e04c3fSmrg 32701e04c3fSmrg rctx->streamout.streamout_enabled = enable; 32801e04c3fSmrg 32901e04c3fSmrg rctx->streamout.hw_enabled_mask = rctx->streamout.enabled_mask | 33001e04c3fSmrg (rctx->streamout.enabled_mask << 4) | 33101e04c3fSmrg (rctx->streamout.enabled_mask << 8) | 33201e04c3fSmrg (rctx->streamout.enabled_mask << 12); 33301e04c3fSmrg 33401e04c3fSmrg if ((old_strmout_en != r600_get_strmout_en(rctx)) || 33501e04c3fSmrg (old_hw_enabled_mask != rctx->streamout.hw_enabled_mask)) { 33601e04c3fSmrg rctx->set_atom_dirty(rctx, &rctx->streamout.enable_atom, true); 33701e04c3fSmrg } 33801e04c3fSmrg} 33901e04c3fSmrg 34001e04c3fSmrgvoid r600_update_prims_generated_query_state(struct r600_common_context *rctx, 34101e04c3fSmrg unsigned type, int diff) 34201e04c3fSmrg{ 34301e04c3fSmrg if (type == PIPE_QUERY_PRIMITIVES_GENERATED) { 34401e04c3fSmrg bool old_strmout_en = r600_get_strmout_en(rctx); 34501e04c3fSmrg 34601e04c3fSmrg rctx->streamout.num_prims_gen_queries += diff; 34701e04c3fSmrg assert(rctx->streamout.num_prims_gen_queries >= 0); 34801e04c3fSmrg 34901e04c3fSmrg rctx->streamout.prims_gen_query_enabled = 35001e04c3fSmrg rctx->streamout.num_prims_gen_queries != 0; 35101e04c3fSmrg 35201e04c3fSmrg if (old_strmout_en != r600_get_strmout_en(rctx)) { 35301e04c3fSmrg rctx->set_atom_dirty(rctx, &rctx->streamout.enable_atom, true); 35401e04c3fSmrg } 35501e04c3fSmrg } 35601e04c3fSmrg} 35701e04c3fSmrg 35801e04c3fSmrgvoid r600_streamout_init(struct r600_common_context *rctx) 35901e04c3fSmrg{ 36001e04c3fSmrg rctx->b.create_stream_output_target = r600_create_so_target; 36101e04c3fSmrg rctx->b.stream_output_target_destroy = r600_so_target_destroy; 36201e04c3fSmrg rctx->streamout.begin_atom.emit = r600_emit_streamout_begin; 36301e04c3fSmrg rctx->streamout.enable_atom.emit = r600_emit_streamout_enable; 36401e04c3fSmrg rctx->streamout.enable_atom.num_dw = 6; 36501e04c3fSmrg} 366