svga: Performance fixes

This is a squash commit of in house performance fixes and misc bug fixes
for GL4.1 support.

Performance fixes:
* started using system memory for constant buffer to gain 3X performance boost with metro redux

Misc bug fixes:
* fixed usage of vertexid in shader
* added empty control point phase in hull shader for zero ouput control point
* misc shader signature fixes
* fixed clip_distance input declaration
* clearing the dirty bit for the surface while using direct map if surface is already flushed
  and there is no pending primitive

This patch also uses SVGA_RETRY macro for commands retries. Part of it is already
used in previous patch.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
Signed-off-by: Neha Bhende <bhenden@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5317>
This commit is contained in:
Neha Bhende 2020-05-26 21:29:50 +05:30 committed by Marge Bot
parent ccb4ea5a43
commit ba37d408da
41 changed files with 1140 additions and 716 deletions

View file

@ -656,6 +656,12 @@ SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
uint32 offsetInBytes, uint32 offsetInBytes,
uint32 sizeInBytes); uint32 sizeInBytes);
enum pipe_error
SVGA3D_vgpu10_SetConstantBufferOffset(struct svga_winsys_context *swc,
unsigned command,
unsigned slot,
uint32 offsetInBytes);
enum pipe_error enum pipe_error
SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc, SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
struct svga_winsys_surface *surface, struct svga_winsys_surface *surface,

View file

@ -1264,6 +1264,31 @@ SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
} }
enum pipe_error
SVGA3D_vgpu10_SetConstantBufferOffset(struct svga_winsys_context *swc,
unsigned command,
unsigned slot,
uint32 offsetInBytes)
{
SVGA3dCmdDXSetConstantBufferOffset *cmd;
assert(offsetInBytes % 256 == 0);
cmd = SVGA3D_FIFOReserve(swc, command,
sizeof(SVGA3dCmdDXSetConstantBufferOffset),
0); /* one relocation */
if (!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
cmd->slot = slot;
cmd->offsetInBytes = offsetInBytes;
swc->commit(swc);
return PIPE_OK;
}
enum pipe_error enum pipe_error
SVGA3D_vgpu10_ReadbackSubResource(struct svga_winsys_context *swc, SVGA3D_vgpu10_ReadbackSubResource(struct svga_winsys_context *swc,
struct svga_winsys_surface *surface, struct svga_winsys_surface *surface,

View file

@ -75,7 +75,9 @@ svga_destroy(struct pipe_context *pipe)
/* free HW constant buffers */ /* free HW constant buffers */
for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) { for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], NULL); for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.constbuf[0]); i++) {
pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][i], NULL);
}
} }
pipe->delete_blend_state(pipe, svga->noop_blend); pipe->delete_blend_state(pipe, svga->noop_blend);

View file

@ -258,6 +258,10 @@ struct svga_velems_state {
SVGA3dElementLayoutId id; /**< VGPU10 */ SVGA3dElementLayoutId id; /**< VGPU10 */
}; };
struct svga_constant_buffer {
struct svga_winsys_surface *handle;
unsigned size;
};
/* Use to calculate differences between state emitted to hardware and /* Use to calculate differences between state emitted to hardware and
* current driver-calculated state. * current driver-calculated state.
@ -308,6 +312,8 @@ struct svga_state
unsigned num_vertex_buffers; unsigned num_vertex_buffers;
enum pipe_prim_type reduced_prim; enum pipe_prim_type reduced_prim;
unsigned vertex_id_bias;
struct { struct {
unsigned flag_1d; unsigned flag_1d;
unsigned flag_srgb; unsigned flag_srgb;
@ -391,7 +397,8 @@ struct svga_hw_draw_state
struct svga_shader_variant *cs; struct svga_shader_variant *cs;
/** Currently bound constant buffer, per shader stage */ /** Currently bound constant buffer, per shader stage */
struct pipe_resource *constbuf[PIPE_SHADER_TYPES]; struct pipe_resource *constbuf[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
struct svga_constant_buffer constbufoffsets[PIPE_SHADER_TYPES][SVGA_MAX_CONST_BUFS];
/** Bitmask of enabled constant buffers */ /** Bitmask of enabled constant buffers */
unsigned enabled_constbufs[PIPE_SHADER_TYPES]; unsigned enabled_constbufs[PIPE_SHADER_TYPES];
@ -699,8 +706,18 @@ struct svga_context
#define SVGA_NEW_TCS_CONST_BUFFER ((uint64_t) 0x1000000000) #define SVGA_NEW_TCS_CONST_BUFFER ((uint64_t) 0x1000000000)
#define SVGA_NEW_TES_CONST_BUFFER ((uint64_t) 0x2000000000) #define SVGA_NEW_TES_CONST_BUFFER ((uint64_t) 0x2000000000)
#define SVGA_NEW_TCS_PARAM ((uint64_t) 0x4000000000) #define SVGA_NEW_TCS_PARAM ((uint64_t) 0x4000000000)
#define SVGA_NEW_FS_CONSTS ((uint64_t) 0x8000000000)
#define SVGA_NEW_VS_CONSTS ((uint64_t) 0x10000000000)
#define SVGA_NEW_GS_CONSTS ((uint64_t) 0x20000000000)
#define SVGA_NEW_TCS_CONSTS ((uint64_t) 0x40000000000)
#define SVGA_NEW_TES_CONSTS ((uint64_t) 0x800000000000)
#define SVGA_NEW_ALL ((uint64_t) 0xFFFFFFFFFFFFFFFF) #define SVGA_NEW_ALL ((uint64_t) 0xFFFFFFFFFFFFFFFF)
#define SVGA_NEW_CONST_BUFFER \
(SVGA_NEW_FS_CONST_BUFFER | SVGA_NEW_VS_CONST_BUFFER | \
SVGA_NEW_GS_CONST_BUFFER | \
SVGA_NEW_TCS_CONST_BUFFER | SVGA_NEW_TES_CONST_BUFFER)
void svga_init_state_functions( struct svga_context *svga ); void svga_init_state_functions( struct svga_context *svga );
void svga_init_flush_functions( struct svga_context *svga ); void svga_init_flush_functions( struct svga_context *svga );
@ -739,6 +756,7 @@ void svga_context_finish(struct svga_context *svga);
void svga_hwtnl_flush_retry( struct svga_context *svga ); void svga_hwtnl_flush_retry( struct svga_context *svga );
void svga_hwtnl_flush_buffer( struct svga_context *svga, void svga_hwtnl_flush_buffer( struct svga_context *svga,
struct pipe_resource *buffer ); struct pipe_resource *buffer );
boolean svga_hwtnl_has_pending_prim(struct svga_hwtnl *);
void svga_surfaces_flush(struct svga_context *svga); void svga_surfaces_flush(struct svga_context *svga);

View file

@ -419,12 +419,10 @@ validate_constant_buffers(struct svga_context *svga)
for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_COMPUTE; shader++) { for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_COMPUTE; shader++) {
enum pipe_error ret; enum pipe_error ret;
struct svga_buffer *buffer; struct svga_buffer *buffer;
struct svga_winsys_surface *handle;
unsigned enabled_constbufs;
/* Rebind the default constant buffer if needed */ /* Rebind the default constant buffer if needed */
if (svga->rebind.flags.constbufs) { if (svga->rebind.flags.constbufs) {
buffer = svga_buffer(svga->state.hw_draw.constbuf[shader]); buffer = svga_buffer(svga->state.hw_draw.constbuf[shader][0]);
if (buffer) { if (buffer) {
ret = svga->swc->resource_rebind(svga->swc, ret = svga->swc->resource_rebind(svga->swc,
buffer->handle, buffer->handle,
@ -435,6 +433,9 @@ validate_constant_buffers(struct svga_context *svga)
} }
} }
struct svga_winsys_surface *handle;
unsigned enabled_constbufs;
/* /*
* Reference other bound constant buffers to ensure pending updates are * Reference other bound constant buffers to ensure pending updates are
* noticed by the device. * noticed by the device.
@ -443,18 +444,23 @@ validate_constant_buffers(struct svga_context *svga)
while (enabled_constbufs) { while (enabled_constbufs) {
unsigned i = u_bit_scan(&enabled_constbufs); unsigned i = u_bit_scan(&enabled_constbufs);
buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer); buffer = svga_buffer(svga->curr.constbufs[shader][i].buffer);
if (buffer) {
/* If the constant buffer has hw storage, get the buffer winsys handle.
* Rebind the resource if needed.
*/
if (buffer && !buffer->use_swbuf)
handle = svga_buffer_handle(svga, &buffer->b.b, handle = svga_buffer_handle(svga, &buffer->b.b,
PIPE_BIND_CONSTANT_BUFFER); PIPE_BIND_CONSTANT_BUFFER);
else
handle = svga->state.hw_draw.constbufoffsets[shader][i].handle;
if (svga->rebind.flags.constbufs) { if (svga->rebind.flags.constbufs && handle) {
ret = svga->swc->resource_rebind(svga->swc, ret = svga->swc->resource_rebind(svga->swc,
handle, handle,
NULL, NULL,
SVGA_RELOC_READ); SVGA_RELOC_READ);
if (ret != PIPE_OK) if (ret != PIPE_OK)
return ret; return ret;
}
} }
} }
} }
@ -1189,3 +1195,13 @@ done:
SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws); SVGA_STATS_TIME_POP(svga_screen(hwtnl->svga->pipe.screen)->sws);
return ret; return ret;
} }
/**
* Return TRUE if there are pending primitives.
*/
boolean
svga_hwtnl_has_pending_prim(struct svga_hwtnl *hwtnl)
{
return hwtnl->cmd.prim_count > 0;
}

View file

@ -50,6 +50,10 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
linkage->input_map[i] = INVALID_INDEX; linkage->input_map[i] = INVALID_INDEX;
} }
for (i = 0; i < ARRAY_SIZE(linkage->prevShader.output_map); i++) {
linkage->prevShader.output_map[i] = INVALID_INDEX;
}
/* Assign input slots for input shader inputs. /* Assign input slots for input shader inputs.
* Basically, we want to use the same index for the output shader's outputs * Basically, we want to use the same index for the output shader's outputs
* and the input shader's inputs that should be linked together. * and the input shader's inputs that should be linked together.
@ -65,26 +69,31 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
enum tgsi_semantic sem_name = inshader_info->input_semantic_name[i]; enum tgsi_semantic sem_name = inshader_info->input_semantic_name[i];
unsigned sem_index = inshader_info->input_semantic_index[i]; unsigned sem_index = inshader_info->input_semantic_index[i];
unsigned j; unsigned j;
unsigned out_index;
/* search output shader outputs for same item */
for (j = 0; j < outshader_info->num_outputs; j++) {
assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));
if (outshader_info->output_semantic_name[j] == sem_name &&
outshader_info->output_semantic_index[j] == sem_index) {
linkage->input_map[i] = j;
linkage->prevShader.output_map[j] = i;
break;
}
}
/** /**
* Get the clip distance inputs from the output shader's * The clip distance inputs come from the output shader's
* clip distance shadow copy. * clip distance shadow copy, so mark the input index to match
* the index of the shadow copy.
*/ */
if (sem_name == TGSI_SEMANTIC_CLIPDIST) { if (sem_name == TGSI_SEMANTIC_CLIPDIST) {
linkage->input_map[i] = outshader_info->num_outputs + 1 + sem_index; out_index = outshader_info->num_outputs + 1 + sem_index;
linkage->input_map[i] = out_index;
linkage->prevShader.output_map[out_index] = i;
/* make sure free_slot includes this extra output */ /* make sure free_slot includes this extra output */
free_slot = MAX2(free_slot, linkage->input_map[i] + 1); free_slot = MAX2(free_slot, linkage->input_map[i] + 1);
} }
else {
/* search output shader outputs for same item */
for (j = 0; j < outshader_info->num_outputs; j++) {
assert(j < ARRAY_SIZE(outshader_info->output_semantic_name));
if (outshader_info->output_semantic_name[j] == sem_name &&
outshader_info->output_semantic_index[j] == sem_index) {
linkage->input_map[i] = j;
break;
}
}
}
} }
/* Find the index for position */ /* Find the index for position */
@ -97,12 +106,14 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
} }
linkage->num_inputs = inshader_info->num_inputs; linkage->num_inputs = inshader_info->num_inputs;
linkage->prevShader.num_outputs = outshader_info->num_outputs;
/* Things like the front-face register are handled here */ /* Things like the front-face register are handled here */
for (i = 0; i < inshader_info->num_inputs; i++) { for (i = 0; i < inshader_info->num_inputs; i++) {
if (linkage->input_map[i] == INVALID_INDEX) { if (linkage->input_map[i] == INVALID_INDEX) {
unsigned j = free_slot++; unsigned j = free_slot++;
linkage->input_map[i] = j; linkage->input_map[i] = j;
linkage->prevShader.output_map[j] = i;
} }
} }
linkage->input_map_max = free_slot - 1; linkage->input_map_max = free_slot - 1;
@ -111,8 +122,11 @@ svga_link_shaders(const struct tgsi_shader_info *outshader_info,
if (SVGA_DEBUG & DEBUG_TGSI) { if (SVGA_DEBUG & DEBUG_TGSI) {
uint64_t reg = 0; uint64_t reg = 0;
uint64_t one = 1; uint64_t one = 1;
debug_printf("### linkage info: num_inputs=%d input_map_max=%d\n",
linkage->num_inputs, linkage->input_map_max); debug_printf(
"### linkage info: num_inputs=%d input_map_max=%d prevShader.num_outputs=%d\n",
linkage->num_inputs, linkage->input_map_max,
linkage->prevShader.num_outputs);
for (i = 0; i < linkage->num_inputs; i++) { for (i = 0; i < linkage->num_inputs; i++) {

View file

@ -8,10 +8,15 @@ struct svga_context;
struct shader_linkage struct shader_linkage
{ {
unsigned num_inputs; unsigned num_inputs; /* number of inputs in the current shader */
unsigned position_index; /* position register index */ unsigned position_index; /* position register index */
unsigned input_map_max; /* highest index of mapped inputs */ unsigned input_map_max; /* highest index of mapped inputs */
ubyte input_map[PIPE_MAX_SHADER_INPUTS]; ubyte input_map[PIPE_MAX_SHADER_INPUTS];
struct {
unsigned num_outputs;
ubyte output_map[PIPE_MAX_SHADER_OUTPUTS];
} prevShader;
}; };
void void

View file

@ -77,15 +77,32 @@ svga_set_constant_buffer(struct pipe_context *pipe,
svga->curr.constbufs[shader][index].buffer_offset = cb ? cb->buffer_offset : 0; svga->curr.constbufs[shader][index].buffer_offset = cb ? cb->buffer_offset : 0;
svga->curr.constbufs[shader][index].user_buffer = NULL; /* not used */ svga->curr.constbufs[shader][index].user_buffer = NULL; /* not used */
if (shader == PIPE_SHADER_FRAGMENT) if (index == 0) {
svga->dirty |= SVGA_NEW_FS_CONST_BUFFER; if (shader == PIPE_SHADER_FRAGMENT)
else if (shader == PIPE_SHADER_VERTEX) svga->dirty |= SVGA_NEW_FS_CONSTS;
svga->dirty |= SVGA_NEW_VS_CONST_BUFFER; else if (shader == PIPE_SHADER_VERTEX)
else svga->dirty |= SVGA_NEW_VS_CONSTS;
svga->dirty |= SVGA_NEW_GS_CONST_BUFFER; else if (shader == PIPE_SHADER_GEOMETRY)
svga->dirty |= SVGA_NEW_GS_CONSTS;
else if (shader == PIPE_SHADER_TESS_CTRL)
svga->dirty |= SVGA_NEW_TCS_CONSTS;
else if (shader == PIPE_SHADER_TESS_EVAL)
svga->dirty |= SVGA_NEW_TES_CONSTS;
} else {
if (shader == PIPE_SHADER_FRAGMENT)
svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
else if (shader == PIPE_SHADER_VERTEX)
svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
else if (shader == PIPE_SHADER_GEOMETRY)
svga->dirty |= SVGA_NEW_GS_CONST_BUFFER;
else if (shader == PIPE_SHADER_TESS_CTRL)
svga->dirty |= SVGA_NEW_TCS_CONST_BUFFER;
else if (shader == PIPE_SHADER_TESS_EVAL)
svga->dirty |= SVGA_NEW_TES_CONST_BUFFER;
/* update bitmask of dirty const buffers */ /* update bitmask of dirty const buffers */
svga->state.dirty_constbufs[shader] |= (1 << index); svga->state.dirty_constbufs[shader] |= (1 << index);
}
if (cb && cb->user_buffer) { if (cb && cb->user_buffer) {
pipe_resource_reference(&buf, NULL); pipe_resource_reference(&buf, NULL);

View file

@ -79,8 +79,6 @@ static void
define_depth_stencil_state_object(struct svga_context *svga, define_depth_stencil_state_object(struct svga_context *svga,
struct svga_depth_stencil_state *ds) struct svga_depth_stencil_state *ds)
{ {
unsigned try;
assert(svga_have_vgpu10(svga)); assert(svga_have_vgpu10(svga));
ds->id = util_bitmask_add(svga->ds_object_id_bm); ds->id = util_bitmask_add(svga->ds_object_id_bm);
@ -90,40 +88,33 @@ define_depth_stencil_state_object(struct svga_context *svga,
STATIC_ASSERT(SVGA3D_COMPARISON_LESS == SVGA3D_CMP_LESS); STATIC_ASSERT(SVGA3D_COMPARISON_LESS == SVGA3D_CMP_LESS);
STATIC_ASSERT(SVGA3D_COMPARISON_NOT_EQUAL == SVGA3D_CMP_NOTEQUAL); STATIC_ASSERT(SVGA3D_COMPARISON_NOT_EQUAL == SVGA3D_CMP_NOTEQUAL);
/* Loop in case command buffer is full and we need to flush and retry */ /* Note: we use the ds->stencil[0].enabled value for both the front
for (try = 0; try < 2; try++) { * and back-face enables. If single-side stencil is used, we'll have
enum pipe_error ret; * set the back state the same as the front state.
*/
/* Note: we use the ds->stencil[0].enabled value for both the front SVGA_RETRY(svga, SVGA3D_vgpu10_DefineDepthStencilState
* and back-face enables. If single-side stencil is used, we'll have (svga->swc,
* set the back state the same as the front state. ds->id,
*/ /* depth/Z */
ret = SVGA3D_vgpu10_DefineDepthStencilState(svga->swc, ds->zenable,
ds->id, ds->zwriteenable,
/* depth/Z */ ds->zfunc,
ds->zenable, /* Stencil */
ds->zwriteenable, ds->stencil[0].enabled, /*f|b*/
ds->zfunc, ds->stencil[0].enabled, /*f*/
/* Stencil */ ds->stencil[0].enabled, /*b*/
ds->stencil[0].enabled, /*f|b*/ ds->stencil_mask,
ds->stencil[0].enabled, /*f*/ ds->stencil_writemask,
ds->stencil[0].enabled, /*b*/ /* front stencil */
ds->stencil_mask, ds->stencil[0].fail,
ds->stencil_writemask, ds->stencil[0].zfail,
/* front stencil */ ds->stencil[0].pass,
ds->stencil[0].fail, ds->stencil[0].func,
ds->stencil[0].zfail, /* back stencil */
ds->stencil[0].pass, ds->stencil[1].fail,
ds->stencil[0].func, ds->stencil[1].zfail,
/* back stencil */ ds->stencil[1].pass,
ds->stencil[1].fail, ds->stencil[1].func));
ds->stencil[1].zfail,
ds->stencil[1].pass,
ds->stencil[1].func);
if (ret == PIPE_OK)
return;
svga_context_flush(svga, NULL);
}
} }
@ -251,18 +242,12 @@ svga_delete_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
(struct svga_depth_stencil_state *) depth_stencil; (struct svga_depth_stencil_state *) depth_stencil;
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
enum pipe_error ret;
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
assert(ds->id != SVGA3D_INVALID_ID); assert(ds->id != SVGA3D_INVALID_ID);
ret = SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc, ds->id); SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc,
if (ret != PIPE_OK) { ds->id));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_DestroyDepthStencilState(svga->swc, ds->id);
assert(ret == PIPE_OK);
}
if (ds->id == svga->state.hw_draw.depth_stencil_id) if (ds->id == svga->state.hw_draw.depth_stencil_id)
svga->state.hw_draw.depth_stencil_id = SVGA3D_INVALID_ID; svga->state.hw_draw.depth_stencil_id = SVGA3D_INVALID_ID;

View file

@ -244,6 +244,15 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE; svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
} }
/* We need to adjust the vertexID in the vertex shader since SV_VertexID
* always start from 0 for DrawArrays and does not include baseVertex for
* DrawIndexed.
*/
if (svga->curr.vertex_id_bias != (info->start + info->index_bias)) {
svga->curr.vertex_id_bias = info->start + info->index_bias;
svga->dirty |= SVGA_NEW_VS_CONSTS;
}
if (svga->curr.vertices_per_patch != info->vertices_per_patch) { if (svga->curr.vertices_per_patch != info->vertices_per_patch) {
svga->curr.vertices_per_patch = info->vertices_per_patch; svga->curr.vertices_per_patch = info->vertices_per_patch;

View file

@ -87,7 +87,6 @@ svga_delete_fs_state(struct pipe_context *pipe, void *shader)
struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader; struct svga_fragment_shader *fs = (struct svga_fragment_shader *) shader;
struct svga_fragment_shader *next_fs; struct svga_fragment_shader *next_fs;
struct svga_shader_variant *variant, *tmp; struct svga_shader_variant *variant, *tmp;
enum pipe_error ret;
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
@ -103,12 +102,7 @@ svga_delete_fs_state(struct pipe_context *pipe, void *shader)
/* Check if deleting currently bound shader */ /* Check if deleting currently bound shader */
if (variant == svga->state.hw_draw.fs) { if (variant == svga->state.hw_draw.fs) {
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL); SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL);
assert(ret == PIPE_OK);
}
svga->state.hw_draw.fs = NULL; svga->state.hw_draw.fs = NULL;
} }

View file

@ -89,7 +89,6 @@ svga_delete_gs_state(struct pipe_context *pipe, void *shader)
struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader; struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
struct svga_geometry_shader *next_gs; struct svga_geometry_shader *next_gs;
struct svga_shader_variant *variant, *tmp; struct svga_shader_variant *variant, *tmp;
enum pipe_error ret;
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
@ -111,12 +110,7 @@ svga_delete_gs_state(struct pipe_context *pipe, void *shader)
/* Check if deleting currently bound shader */ /* Check if deleting currently bound shader */
if (variant == svga->state.hw_draw.gs) { if (variant == svga->state.hw_draw.gs) {
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL); SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL);
assert(ret == PIPE_OK);
}
svga->state.hw_draw.gs = NULL; svga->state.hw_draw.gs = NULL;
} }

View file

@ -119,11 +119,10 @@ define_query_vgpu9(struct svga_context *svga,
return PIPE_OK; return PIPE_OK;
} }
static enum pipe_error static void
begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq) begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
{ {
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
enum pipe_error ret = PIPE_OK;
if (sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) { if (sq->queryResult->state == SVGA3D_QUERYSTATE_PENDING) {
/* The application doesn't care for the pending query result. /* The application doesn't care for the pending query result.
@ -141,28 +140,16 @@ begin_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
sq->queryResult->state = SVGA3D_QUERYSTATE_NEW; sq->queryResult->state = SVGA3D_QUERYSTATE_NEW;
sws->fence_reference(sws, &sq->fence, NULL); sws->fence_reference(sws, &sq->fence, NULL);
ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type); SVGA_RETRY(svga, SVGA3D_BeginQuery(svga->swc, sq->svga_type));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_BeginQuery(svga->swc, sq->svga_type);
}
return ret;
} }
static enum pipe_error static void
end_query_vgpu9(struct svga_context *svga, struct svga_query *sq) end_query_vgpu9(struct svga_context *svga, struct svga_query *sq)
{ {
enum pipe_error ret = PIPE_OK;
/* Set to PENDING before sending EndQuery. */ /* Set to PENDING before sending EndQuery. */
sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING; sq->queryResult->state = SVGA3D_QUERYSTATE_PENDING;
ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf); SVGA_RETRY(svga, SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_EndQuery(svga->swc, sq->svga_type, sq->hwbuf);
}
return ret;
} }
static bool static bool
@ -170,7 +157,6 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
bool wait, uint64_t *result) bool wait, uint64_t *result)
{ {
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
enum pipe_error ret;
SVGA3dQueryState state; SVGA3dQueryState state;
if (!sq->fence) { if (!sq->fence) {
@ -178,12 +164,8 @@ get_query_result_vgpu9(struct svga_context *svga, struct svga_query *sq,
* SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause * SVGA_3D_CMD_WAIT_FOR_QUERY is emitted. Unfortunately this will cause
* a synchronous wait on the host. * a synchronous wait on the host.
*/ */
ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf); SVGA_RETRY(svga, SVGA3D_WaitForQuery(svga->swc, sq->svga_type,
if (ret != PIPE_OK) { sq->hwbuf));
svga_context_flush(svga, NULL);
ret = SVGA3D_WaitForQuery(svga->swc, sq->svga_type, sq->hwbuf);
}
assert (ret == PIPE_OK);
svga_context_flush(svga, &sq->fence); svga_context_flush(svga, &sq->fence);
assert(sq->fence); assert(sq->fence);
} }
@ -510,12 +492,8 @@ define_query_vgpu10(struct svga_context *svga,
svga->gb_query_alloc_mask = util_bitmask_create(); svga->gb_query_alloc_mask = util_bitmask_create();
/* Bind the query object to the context */ /* Bind the query object to the context */
if (svga->swc->query_bind(svga->swc, svga->gb_query, SVGA_RETRY(svga, svga->swc->query_bind(svga->swc, svga->gb_query,
SVGA_QUERY_FLAG_SET) != PIPE_OK) { SVGA_QUERY_FLAG_SET));
svga_context_flush(svga, NULL);
svga->swc->query_bind(svga->swc, svga->gb_query,
SVGA_QUERY_FLAG_SET);
}
} }
sq->gb_query = svga->gb_query; sq->gb_query = svga->gb_query;
@ -536,42 +514,26 @@ define_query_vgpu10(struct svga_context *svga,
/** /**
* Send SVGA3D commands to define the query * Send SVGA3D commands to define the query
*/ */
ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags); SVGA_RETRY_OOM(svga, ret, SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id,
if (ret != PIPE_OK) { sq->svga_type,
svga_context_flush(svga, NULL); sq->flags));
ret = SVGA3D_vgpu10_DefineQuery(svga->swc, sq->id, sq->svga_type, sq->flags);
}
if (ret != PIPE_OK) if (ret != PIPE_OK)
return PIPE_ERROR_OUT_OF_MEMORY; return PIPE_ERROR_OUT_OF_MEMORY;
ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id); SVGA_RETRY(svga, SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id));
if (ret != PIPE_OK) { SVGA_RETRY(svga, SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id,
svga_context_flush(svga, NULL); sq->offset));
ret = SVGA3D_vgpu10_BindQuery(svga->swc, sq->gb_query, sq->id);
}
assert(ret == PIPE_OK);
ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_SetQueryOffset(svga->swc, sq->id, sq->offset);
}
assert(ret == PIPE_OK);
return PIPE_OK; return PIPE_OK;
} }
static enum pipe_error static void
destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq) destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{ {
enum pipe_error ret; SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id));
ret = SVGA3D_vgpu10_DestroyQuery(svga->swc, sq->id);
/* Deallocate the memory slot allocated for this query */ /* Deallocate the memory slot allocated for this query */
deallocate_query(svga, sq); deallocate_query(svga, sq);
return ret;
} }
@ -581,13 +543,8 @@ destroy_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
static void static void
rebind_vgpu10_query(struct svga_context *svga) rebind_vgpu10_query(struct svga_context *svga)
{ {
if (svga->swc->query_bind(svga->swc, svga->gb_query, SVGA_RETRY(svga, svga->swc->query_bind(svga->swc, svga->gb_query,
SVGA_QUERY_FLAG_REF) != PIPE_OK) { SVGA_QUERY_FLAG_REF));
svga_context_flush(svga, NULL);
svga->swc->query_bind(svga->swc, svga->gb_query,
SVGA_QUERY_FLAG_REF);
}
svga->rebind.flags.query = FALSE; svga->rebind.flags.query = FALSE;
} }
@ -596,7 +553,6 @@ static enum pipe_error
begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq) begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{ {
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
enum pipe_error ret = PIPE_OK;
int status = 0; int status = 0;
sws->fence_reference(sws, &sq->fence, NULL); sws->fence_reference(sws, &sq->fence, NULL);
@ -611,30 +567,18 @@ begin_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
} }
/* Send the BeginQuery command to the device */ /* Send the BeginQuery command to the device */
ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id); SVGA_RETRY(svga, SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id));
if (ret != PIPE_OK) { return PIPE_OK;
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_BeginQuery(svga->swc, sq->id);
}
return ret;
} }
static enum pipe_error static void
end_query_vgpu10(struct svga_context *svga, struct svga_query *sq) end_query_vgpu10(struct svga_context *svga, struct svga_query *sq)
{ {
enum pipe_error ret = PIPE_OK;
if (svga->rebind.flags.query) { if (svga->rebind.flags.query) {
rebind_vgpu10_query(svga); rebind_vgpu10_query(svga);
} }
ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id); SVGA_RETRY(svga, SVGA3D_vgpu10_EndQuery(svga->swc, sq->id));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_EndQuery(svga->swc, sq->id);
}
return ret;
} }
static bool static bool
@ -775,6 +719,7 @@ svga_create_query(struct pipe_context *pipe,
case SVGA_QUERY_NUM_BUFFERS_MAPPED: case SVGA_QUERY_NUM_BUFFERS_MAPPED:
case SVGA_QUERY_NUM_TEXTURES_MAPPED: case SVGA_QUERY_NUM_TEXTURES_MAPPED:
case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_NUM_BYTES_UPLOADED:
case SVGA_QUERY_NUM_COMMAND_BUFFERS:
case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_COMMAND_BUFFER_SIZE:
case SVGA_QUERY_SURFACE_WRITE_FLUSHES: case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
case SVGA_QUERY_MEMORY_USED: case SVGA_QUERY_MEMORY_USED:
@ -790,12 +735,16 @@ svga_create_query(struct pipe_context *pipe,
case SVGA_QUERY_NUM_CONST_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES:
case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
case SVGA_QUERY_SHADER_MEM_USED:
break; break;
case SVGA_QUERY_FLUSH_TIME: case SVGA_QUERY_FLUSH_TIME:
case SVGA_QUERY_MAP_BUFFER_TIME: case SVGA_QUERY_MAP_BUFFER_TIME:
/* These queries need os_time_get() */ /* These queries need os_time_get() */
svga->hud.uses_time = TRUE; svga->hud.uses_time = TRUE;
break; break;
default: default:
assert(!"unexpected query type in svga_create_query()"); assert(!"unexpected query type in svga_create_query()");
} }
@ -856,6 +805,7 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_BUFFERS_MAPPED: case SVGA_QUERY_NUM_BUFFERS_MAPPED:
case SVGA_QUERY_NUM_TEXTURES_MAPPED: case SVGA_QUERY_NUM_TEXTURES_MAPPED:
case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_NUM_BYTES_UPLOADED:
case SVGA_QUERY_NUM_COMMAND_BUFFERS:
case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_COMMAND_BUFFER_SIZE:
case SVGA_QUERY_FLUSH_TIME: case SVGA_QUERY_FLUSH_TIME:
case SVGA_QUERY_SURFACE_WRITE_FLUSHES: case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
@ -872,6 +822,9 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_CONST_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES:
case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
case SVGA_QUERY_SHADER_MEM_USED:
/* nothing */ /* nothing */
break; break;
default: default:
@ -890,14 +843,11 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
{ {
struct svga_context *svga = svga_context(pipe); struct svga_context *svga = svga_context(pipe);
struct svga_query *sq = svga_query(q); struct svga_query *sq = svga_query(q);
enum pipe_error ret; enum pipe_error ret = PIPE_OK;
assert(sq); assert(sq);
assert(sq->type < SVGA_QUERY_MAX); assert(sq->type < SVGA_QUERY_MAX);
SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__,
sq, sq->id);
/* Need to flush out buffered drawing commands so that they don't /* Need to flush out buffered drawing commands so that they don't
* get counted in the query results. * get counted in the query results.
*/ */
@ -917,7 +867,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
(void) status; (void) status;
} }
} else { } else {
ret = begin_query_vgpu9(svga, sq); begin_query_vgpu9(svga, sq);
} }
assert(ret == PIPE_OK); assert(ret == PIPE_OK);
(void) ret; (void) ret;
@ -954,6 +904,9 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_NUM_BYTES_UPLOADED:
sq->begin_count = svga->hud.num_bytes_uploaded; sq->begin_count = svga->hud.num_bytes_uploaded;
break; break;
case SVGA_QUERY_NUM_COMMAND_BUFFERS:
sq->begin_count = svga->swc->num_command_buffers;
break;
case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_COMMAND_BUFFER_SIZE:
sq->begin_count = svga->hud.command_buffer_size; sq->begin_count = svga->hud.command_buffer_size;
break; break;
@ -978,6 +931,12 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_CONST_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES:
sq->begin_count = svga->hud.num_const_updates; sq->begin_count = svga->hud.num_const_updates;
break; break;
case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
sq->begin_count = svga->swc->num_shader_reloc;
break;
case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
sq->begin_count = svga->swc->num_surf_reloc;
break;
case SVGA_QUERY_MEMORY_USED: case SVGA_QUERY_MEMORY_USED:
case SVGA_QUERY_NUM_SHADERS: case SVGA_QUERY_NUM_SHADERS:
case SVGA_QUERY_NUM_RESOURCES: case SVGA_QUERY_NUM_RESOURCES:
@ -986,6 +945,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_GENERATE_MIPMAP: case SVGA_QUERY_NUM_GENERATE_MIPMAP:
case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
case SVGA_QUERY_SHADER_MEM_USED:
/* nothing */ /* nothing */
break; break;
default: default:
@ -1006,17 +966,19 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
{ {
struct svga_context *svga = svga_context(pipe); struct svga_context *svga = svga_context(pipe);
struct svga_query *sq = svga_query(q); struct svga_query *sq = svga_query(q);
enum pipe_error ret;
assert(sq); assert(sq);
assert(sq->type < SVGA_QUERY_MAX); assert(sq->type < SVGA_QUERY_MAX);
SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d\n", __FUNCTION__, SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x type=%d\n",
sq, sq->id); __FUNCTION__, sq, sq->type);
if (sq->type == PIPE_QUERY_TIMESTAMP && !sq->active) if (sq->type == PIPE_QUERY_TIMESTAMP && !sq->active)
svga_begin_query(pipe, q); svga_begin_query(pipe, q);
SVGA_DBG(DEBUG_QUERY, "%s sq=0x%x id=%d type=%d svga_type=%d\n",
__FUNCTION__, sq, sq->id, sq->type, sq->svga_type);
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
assert(sq->active); assert(sq->active);
@ -1026,27 +988,21 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
case PIPE_QUERY_OCCLUSION_PREDICATE: case PIPE_QUERY_OCCLUSION_PREDICATE:
case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
ret = end_query_vgpu10(svga, sq); end_query_vgpu10(svga, sq);
/* also need to end the associated occlusion predicate query */ /* also need to end the associated occlusion predicate query */
if (sq->predicate) { if (sq->predicate) {
enum pipe_error status; end_query_vgpu10(svga, svga_query(sq->predicate));
status = end_query_vgpu10(svga, svga_query(sq->predicate));
assert(status == PIPE_OK);
(void) status;
} }
} else { } else {
ret = end_query_vgpu9(svga, sq); end_query_vgpu9(svga, sq);
} }
assert(ret == PIPE_OK);
(void) ret;
break; break;
case PIPE_QUERY_PRIMITIVES_GENERATED: case PIPE_QUERY_PRIMITIVES_GENERATED:
case PIPE_QUERY_PRIMITIVES_EMITTED: case PIPE_QUERY_PRIMITIVES_EMITTED:
case PIPE_QUERY_SO_STATISTICS: case PIPE_QUERY_SO_STATISTICS:
case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_TIMESTAMP:
assert(svga_have_vgpu10(svga)); assert(svga_have_vgpu10(svga));
ret = end_query_vgpu10(svga, sq); end_query_vgpu10(svga, sq);
assert(ret == PIPE_OK);
break; break;
case SVGA_QUERY_NUM_DRAW_CALLS: case SVGA_QUERY_NUM_DRAW_CALLS:
sq->end_count = svga->hud.num_draw_calls; sq->end_count = svga->hud.num_draw_calls;
@ -1072,6 +1028,9 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_NUM_BYTES_UPLOADED:
sq->end_count = svga->hud.num_bytes_uploaded; sq->end_count = svga->hud.num_bytes_uploaded;
break; break;
case SVGA_QUERY_NUM_COMMAND_BUFFERS:
sq->end_count = svga->swc->num_command_buffers;
break;
case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_COMMAND_BUFFER_SIZE:
sq->end_count = svga->hud.command_buffer_size; sq->end_count = svga->hud.command_buffer_size;
break; break;
@ -1096,6 +1055,12 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_CONST_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES:
sq->end_count = svga->hud.num_const_updates; sq->end_count = svga->hud.num_const_updates;
break; break;
case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
sq->end_count = svga->swc->num_shader_reloc;
break;
case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
sq->end_count = svga->swc->num_surf_reloc;
break;
case SVGA_QUERY_MEMORY_USED: case SVGA_QUERY_MEMORY_USED:
case SVGA_QUERY_NUM_SHADERS: case SVGA_QUERY_NUM_SHADERS:
case SVGA_QUERY_NUM_RESOURCES: case SVGA_QUERY_NUM_RESOURCES:
@ -1104,6 +1069,7 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q)
case SVGA_QUERY_NUM_GENERATE_MIPMAP: case SVGA_QUERY_NUM_GENERATE_MIPMAP:
case SVGA_QUERY_NUM_FAILED_ALLOCATIONS: case SVGA_QUERY_NUM_FAILED_ALLOCATIONS:
case SVGA_QUERY_NUM_COMMANDS_PER_DRAW: case SVGA_QUERY_NUM_COMMANDS_PER_DRAW:
case SVGA_QUERY_SHADER_MEM_USED:
/* nothing */ /* nothing */
break; break;
default: default:
@ -1204,6 +1170,7 @@ svga_get_query_result(struct pipe_context *pipe,
case SVGA_QUERY_NUM_BUFFERS_MAPPED: case SVGA_QUERY_NUM_BUFFERS_MAPPED:
case SVGA_QUERY_NUM_TEXTURES_MAPPED: case SVGA_QUERY_NUM_TEXTURES_MAPPED:
case SVGA_QUERY_NUM_BYTES_UPLOADED: case SVGA_QUERY_NUM_BYTES_UPLOADED:
case SVGA_QUERY_NUM_COMMAND_BUFFERS:
case SVGA_QUERY_COMMAND_BUFFER_SIZE: case SVGA_QUERY_COMMAND_BUFFER_SIZE:
case SVGA_QUERY_FLUSH_TIME: case SVGA_QUERY_FLUSH_TIME:
case SVGA_QUERY_SURFACE_WRITE_FLUSHES: case SVGA_QUERY_SURFACE_WRITE_FLUSHES:
@ -1212,6 +1179,8 @@ svga_get_query_result(struct pipe_context *pipe,
case SVGA_QUERY_NUM_BUFFER_UPLOADS: case SVGA_QUERY_NUM_BUFFER_UPLOADS:
case SVGA_QUERY_NUM_CONST_BUF_UPDATES: case SVGA_QUERY_NUM_CONST_BUF_UPDATES:
case SVGA_QUERY_NUM_CONST_UPDATES: case SVGA_QUERY_NUM_CONST_UPDATES:
case SVGA_QUERY_NUM_SHADER_RELOCATIONS:
case SVGA_QUERY_NUM_SURFACE_RELOCATIONS:
vresult->u64 = sq->end_count - sq->begin_count; vresult->u64 = sq->end_count - sq->begin_count;
break; break;
/* These are running total counters */ /* These are running total counters */
@ -1245,6 +1214,9 @@ svga_get_query_result(struct pipe_context *pipe,
vresult->f = (float) svga->swc->num_commands vresult->f = (float) svga->swc->num_commands
/ (float) svga->swc->num_draw_commands; / (float) svga->swc->num_draw_commands;
break; break;
case SVGA_QUERY_SHADER_MEM_USED:
vresult->u64 = svga->hud.shader_mem_used;
break;
default: default:
assert(!"unexpected query type in svga_get_query_result"); assert(!"unexpected query type in svga_get_query_result");
} }
@ -1262,7 +1234,6 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws; struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
struct svga_query *sq = svga_query(q); struct svga_query *sq = svga_query(q);
SVGA3dQueryId queryId; SVGA3dQueryId queryId;
enum pipe_error ret;
SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__); SVGA_DBG(DEBUG_QUERY, "%s\n", __FUNCTION__);
@ -1296,13 +1267,8 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q,
* This is probably acceptable for the typical case of occlusion culling. * This is probably acceptable for the typical case of occlusion culling.
*/ */
if (sws->have_set_predication_cmd) { if (sws->have_set_predication_cmd) {
ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId, SVGA_RETRY(svga, SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
(uint32) condition); (uint32) condition));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId,
(uint32) condition);
}
svga->pred.query_id = queryId; svga->pred.query_id = queryId;
svga->pred.cond = condition; svga->pred.cond = condition;
} }
@ -1350,7 +1316,6 @@ svga_toggle_render_condition(struct svga_context *svga,
boolean on) boolean on)
{ {
SVGA3dQueryId query_id; SVGA3dQueryId query_id;
enum pipe_error ret;
if (render_condition_enabled || if (render_condition_enabled ||
svga->pred.query_id == SVGA3D_INVALID_ID) { svga->pred.query_id == SVGA3D_INVALID_ID) {
@ -1365,14 +1330,8 @@ svga_toggle_render_condition(struct svga_context *svga,
*/ */
query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID; query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID;
ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id, SVGA_RETRY(svga, SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
(uint32) svga->pred.cond); (uint32) svga->pred.cond));
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id,
(uint32) svga->pred.cond);
assert(ret == PIPE_OK);
}
} }

View file

@ -121,8 +121,6 @@ define_rasterizer_object(struct svga_context *svga,
const uint8 pv_last = !rast->templ.flatshade_first && const uint8 pv_last = !rast->templ.flatshade_first &&
svgascreen->haveProvokingVertex; svgascreen->haveProvokingVertex;
unsigned try;
rast->id = util_bitmask_add(svga->rast_object_id_bm); rast->id = util_bitmask_add(svga->rast_object_id_bm);
if (rast->templ.fill_front != rast->templ.fill_back) { if (rast->templ.fill_front != rast->templ.fill_back) {
@ -133,31 +131,24 @@ define_rasterizer_object(struct svga_context *svga,
fill_mode = SVGA3D_FILLMODE_FILL; fill_mode = SVGA3D_FILLMODE_FILL;
} }
for (try = 0; try < 2; try++) { SVGA_RETRY(svga, SVGA3D_vgpu10_DefineRasterizerState
const uint8 pv_last = !rast->templ.flatshade_first && (svga->swc,
svgascreen->haveProvokingVertex; rast->id,
enum pipe_error ret = fill_mode,
SVGA3D_vgpu10_DefineRasterizerState(svga->swc, cull_mode,
rast->id, rast->templ.front_ccw,
fill_mode, depth_bias,
cull_mode, depth_bias_clamp,
rast->templ.front_ccw, slope_scaled_depth_bias,
depth_bias, rast->templ.depth_clip_near,
depth_bias_clamp, rast->templ.scissor,
slope_scaled_depth_bias, rast->templ.multisample,
rast->templ.depth_clip_near, rast->templ.line_smooth,
rast->templ.scissor, line_width,
rast->templ.multisample, rast->templ.line_stipple_enable,
rast->templ.line_smooth, line_factor,
line_width, line_pattern,
rast->templ.line_stipple_enable, pv_last));
line_factor,
line_pattern,
pv_last);
if (ret == PIPE_OK)
return;
svga_context_flush(svga, NULL);
}
} }
@ -418,12 +409,8 @@ svga_delete_rasterizer_state(struct pipe_context *pipe, void *state)
(struct svga_rasterizer_state *) state; (struct svga_rasterizer_state *) state;
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
enum pipe_error ret = SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyRasterizerState(svga->swc,
SVGA3D_vgpu10_DestroyRasterizerState(svga->swc, raster->id); raster->id));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_DestroyRasterizerState(svga->swc, raster->id);
}
if (raster->id == svga->state.hw_draw.rasterizer_id) if (raster->id == svga->state.hw_draw.rasterizer_id)
svga->state.hw_draw.rasterizer_id = SVGA3D_INVALID_ID; svga->state.hw_draw.rasterizer_id = SVGA3D_INVALID_ID;

View file

@ -166,7 +166,6 @@ define_sampler_state_object(struct svga_context *svga,
uint8 compare_func; uint8 compare_func;
SVGA3dFilter filter; SVGA3dFilter filter;
SVGA3dRGBAFloat bcolor; SVGA3dRGBAFloat bcolor;
unsigned try;
float min_lod, max_lod; float min_lod, max_lod;
assert(svga_have_vgpu10(svga)); assert(svga_have_vgpu10(svga));
@ -207,25 +206,19 @@ define_sampler_state_object(struct svga_context *svga,
for (i = 0; i <= ss->compare_mode; i++) { for (i = 0; i <= ss->compare_mode; i++) {
ss->id[i] = util_bitmask_add(svga->sampler_object_id_bm); ss->id[i] = util_bitmask_add(svga->sampler_object_id_bm);
/* Loop in case command buffer is full and we need to flush and retry */ SVGA_RETRY(svga, SVGA3D_vgpu10_DefineSamplerState
for (try = 0; try < 2; try++) { (svga->swc,
enum pipe_error ret = ss->id[i],
SVGA3D_vgpu10_DefineSamplerState(svga->swc, filter,
ss->id[i], ss->addressu,
filter, ss->addressv,
ss->addressu, ss->addressw,
ss->addressv, ss->lod_bias, /* float */
ss->addressw, max_aniso,
ss->lod_bias, /* float */ compare_func,
max_aniso, bcolor,
compare_func, min_lod, /* float */
bcolor, max_lod)); /* float */
min_lod, /* float */
max_lod); /* float */
if (ret == PIPE_OK)
break;
svga_context_flush(svga, NULL);
}
/* turn off the shadow compare option for second iteration */ /* turn off the shadow compare option for second iteration */
filter &= ~SVGA3D_FILTER_COMPARE; filter &= ~SVGA3D_FILTER_COMPARE;
@ -349,16 +342,11 @@ svga_delete_sampler_state(struct pipe_context *pipe, void *sampler)
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
unsigned i; unsigned i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
enum pipe_error ret;
if (ss->id[i] != SVGA3D_INVALID_ID) { if (ss->id[i] != SVGA3D_INVALID_ID) {
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id[i]); SVGA_RETRY(svga, SVGA3D_vgpu10_DestroySamplerState(svga->swc,
if (ret != PIPE_OK) { ss->id[i]));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_DestroySamplerState(svga->swc, ss->id[i]);
}
util_bitmask_clear(svga->sampler_object_id_bm, ss->id[i]); util_bitmask_clear(svga->sampler_object_id_bm, ss->id[i]);
} }
} }
@ -405,17 +393,12 @@ svga_sampler_view_destroy(struct pipe_context *pipe,
struct svga_pipe_sampler_view *sv = svga_pipe_sampler_view(view); struct svga_pipe_sampler_view *sv = svga_pipe_sampler_view(view);
if (svga_have_vgpu10(svga) && sv->id != SVGA3D_INVALID_ID) { if (svga_have_vgpu10(svga) && sv->id != SVGA3D_INVALID_ID) {
enum pipe_error ret;
assert(view->context == pipe); assert(view->context == pipe);
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
ret = SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc, sv->id); SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc,
if (ret != PIPE_OK) { sv->id));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_DestroyShaderResourceView(svga->swc, sv->id);
}
util_bitmask_clear(svga->sampler_view_id_bm, sv->id); util_bitmask_clear(svga->sampler_view_id_bm, sv->id);
} }
@ -534,7 +517,7 @@ svga_cleanup_sampler_state(struct svga_context *svga)
{ {
enum pipe_shader_type shader; enum pipe_shader_type shader;
for (shader = 0; shader <= PIPE_SHADER_GEOMETRY; shader++) { for (shader = 0; shader <= PIPE_SHADER_TESS_EVAL; shader++) {
unsigned i; unsigned i;
for (i = 0; i < svga->state.hw_draw.num_sampler_views[shader]; i++) { for (i = 0; i < svga->state.hw_draw.num_sampler_views[shader]; i++) {

View file

@ -354,6 +354,15 @@ svga_delete_stream_output(struct svga_context *svga,
sws->buffer_destroy(sws, streamout->declBuf); sws->buffer_destroy(sws, streamout->declBuf);
} }
/* Before deleting the current streamout, make sure to stop any pending
* SO queries.
*/
if (svga->current_so == streamout) {
if (svga->in_streamout)
svga_end_stream_output_queries(svga, svga->current_so->streammask);
svga->current_so = NULL;
}
/* Release the ID */ /* Release the ID */
util_bitmask_clear(svga->stream_output_id_bm, streamout->id); util_bitmask_clear(svga->stream_output_id_bm, streamout->id);

View file

@ -120,7 +120,6 @@ define_input_element_object(struct svga_context *svga,
struct svga_velems_state *velems) struct svga_velems_state *velems)
{ {
SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS]; SVGA3dInputElementDesc elements[PIPE_MAX_ATTRIBS];
enum pipe_error ret;
unsigned i; unsigned i;
assert(velems->count <= PIPE_MAX_ATTRIBS); assert(velems->count <= PIPE_MAX_ATTRIBS);
@ -186,14 +185,8 @@ define_input_element_object(struct svga_context *svga,
velems->id = util_bitmask_add(svga->input_element_object_id_bm); velems->id = util_bitmask_add(svga->input_element_object_id_bm);
ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count, SVGA_RETRY(svga, SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
velems->id, elements); velems->id, elements));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_DefineElementLayout(svga->swc, velems->count,
velems->id, elements);
assert(ret == PIPE_OK);
}
} }
@ -293,16 +286,10 @@ svga_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
struct svga_velems_state *velems = (struct svga_velems_state *) state; struct svga_velems_state *velems = (struct svga_velems_state *) state;
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
enum pipe_error ret;
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, velems->id); SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyElementLayout(svga->swc,
if (ret != PIPE_OK) { velems->id));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_DestroyElementLayout(svga->swc, velems->id);
assert(ret == PIPE_OK);
}
if (velems->id == svga->state.hw_draw.layout_id) if (velems->id == svga->state.hw_draw.layout_id)
svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID; svga->state.hw_draw.layout_id = SVGA3D_INVALID_ID;

View file

@ -168,7 +168,6 @@ svga_delete_vs_state(struct pipe_context *pipe, void *shader)
struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader; struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
struct svga_vertex_shader *next_vs; struct svga_vertex_shader *next_vs;
struct svga_shader_variant *variant, *tmp; struct svga_shader_variant *variant, *tmp;
enum pipe_error ret;
svga_hwtnl_flush_retry(svga); svga_hwtnl_flush_retry(svga);
@ -194,12 +193,7 @@ svga_delete_vs_state(struct pipe_context *pipe, void *shader)
/* Check if deleting currently bound shader */ /* Check if deleting currently bound shader */
if (variant == svga->state.hw_draw.vs) { if (variant == svga->state.hw_draw.vs) {
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL); SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, NULL);
assert(ret == PIPE_OK);
}
svga->state.hw_draw.vs = NULL; svga->state.hw_draw.vs = NULL;
} }

View file

@ -62,14 +62,13 @@ svga_buffer_needs_hw_storage(const struct svga_screen *ss,
* tagged with PIPE_BIND_CUSTOM * tagged with PIPE_BIND_CUSTOM
*/ */
bind_mask |= PIPE_BIND_CUSTOM; bind_mask |= PIPE_BIND_CUSTOM;
/* Uniform buffer objects. /**
* Make sure we don't create hardware storage for gallium frontend * Uniform buffer objects.
* const0 buffers, because we frequently map them for reading. * Don't create hardware storage for state-tracker constant buffers,
* They are distinguished by having PIPE_USAGE_STREAM, but not * because we frequently map them for reading and writing, and
* PIPE_BIND_CUSTOM. * the length of those buffers are always small, so it is better
* to just use system memory.
*/ */
if (template->usage != PIPE_USAGE_STREAM)
bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
} }
if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
@ -132,7 +131,6 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty && if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty &&
!sbuf->key.coherent && !svga->swc->force_coherent) { !sbuf->key.coherent && !svga->swc->force_coherent) {
enum pipe_error ret;
/* Host-side buffers can only be dirtied with vgpu10 features /* Host-side buffers can only be dirtied with vgpu10 features
* (streamout and buffer copy). * (streamout and buffer copy).
@ -150,13 +148,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
assert(sbuf->handle); assert(sbuf->handle);
ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0); SVGA_RETRY(svga, SVGA3D_vgpu10_ReadbackSubResource(svga->swc,
if (ret != PIPE_OK) { sbuf->handle, 0));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, sbuf->handle, 0);
assert(ret == PIPE_OK);
}
svga->hud.num_readbacks++; svga->hud.num_readbacks++;
svga_context_finish(svga); svga_context_finish(svga);
@ -278,15 +271,18 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
else if (svga_buffer_has_hw_storage(sbuf)) { else if (svga_buffer_has_hw_storage(sbuf)) {
boolean retry; boolean retry;
map = svga_buffer_hw_storage_map(svga, sbuf, transfer->usage, &retry); map = SVGA_TRY_MAP(svga_buffer_hw_storage_map
(svga, sbuf, transfer->usage, &retry), retry);
if (map == NULL && retry) { if (map == NULL && retry) {
/* /*
* At this point, svga_buffer_get_transfer() has already * At this point, svga_buffer_get_transfer() has already
* hit the DISCARD_WHOLE_RESOURCE path and flushed HWTNL * hit the DISCARD_WHOLE_RESOURCE path and flushed HWTNL
* for this buffer. * for this buffer.
*/ */
svga_retry_enter(svga);
svga_context_flush(svga, NULL); svga_context_flush(svga, NULL);
map = svga_buffer_hw_storage_map(svga, sbuf, transfer->usage, &retry); map = svga_buffer_hw_storage_map(svga, sbuf, transfer->usage, &retry);
svga_retry_exit(svga);
} }
} }
else { else {
@ -349,6 +345,7 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
} }
if (svga_buffer_has_hw_storage(sbuf)) { if (svga_buffer_has_hw_storage(sbuf)) {
/* Note: we may wind up flushing here and unmapping other buffers /* Note: we may wind up flushing here and unmapping other buffers
* which leads to recursively locking ss->swc_mutex. * which leads to recursively locking ss->swc_mutex.
*/ */
@ -370,6 +367,19 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf) if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf)
svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0); svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
} }
if (sbuf->swbuf &&
(!sbuf->bind_flags || (sbuf->bind_flags & PIPE_BIND_CONSTANT_BUFFER))) {
/*
* Since the constant buffer is in system buffer, we need
* to set the constant buffer dirty bits, so that the context
* can update the changes in the device.
* According to the GL spec, buffer bound to other contexts will
* have to be explicitly rebound by the user to have the changes take
* into effect.
*/
svga->dirty |= SVGA_NEW_CONST_BUFFER;
}
} }
mtx_unlock(&ss->swc_mutex); mtx_unlock(&ss->swc_mutex);
@ -491,6 +501,13 @@ svga_buffer_create(struct pipe_screen *screen,
sbuf->swbuf = align_malloc(sbuf->b.b.width0, 64); sbuf->swbuf = align_malloc(sbuf->b.b.width0, 64);
if (!sbuf->swbuf) if (!sbuf->swbuf)
goto error2; goto error2;
/* Since constant buffer is usually small, it is much cheaper to
* use system memory for the data just as it is being done for
* the default constant buffer.
*/
if ((bind_flags & PIPE_BIND_CONSTANT_BUFFER) || !bind_flags)
sbuf->use_swbuf = TRUE;
} }
debug_reference(&sbuf->b.b.reference, debug_reference(&sbuf->b.b.reference,

View file

@ -93,6 +93,11 @@ struct svga_buffer
*/ */
boolean user; boolean user;
/**
* Whether swbuf is used for this buffer.
*/
boolean use_swbuf;
/** /**
* Creation key for the host surface handle. * Creation key for the host surface handle.
* *
@ -323,16 +328,10 @@ svga_buffer_hw_storage_unmap(struct svga_context *svga,
if (sws->have_gb_objects) { if (sws->have_gb_objects) {
struct svga_winsys_context *swc = svga->swc; struct svga_winsys_context *swc = svga->swc;
boolean rebind; boolean rebind;
swc->surface_unmap(swc, sbuf->handle, &rebind); swc->surface_unmap(swc, sbuf->handle, &rebind);
if (rebind) { if (rebind) {
enum pipe_error ret; SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, sbuf->handle));
ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
if (ret != PIPE_OK) {
/* flush and retry */
svga_context_flush(svga, NULL);
ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
assert(ret == PIPE_OK);
}
} }
} else } else
sws->buffer_unmap(sws, sbuf->hwbuf); sws->buffer_unmap(sws, sbuf->hwbuf);

View file

@ -72,14 +72,16 @@ svga_winsys_buffer_create( struct svga_context *svga,
struct svga_winsys_buffer *buf; struct svga_winsys_buffer *buf;
/* Just try */ /* Just try */
buf = sws->buffer_create(sws, alignment, usage, size); buf = SVGA_TRY_PTR(sws->buffer_create(sws, alignment, usage, size));
if (!buf) { if (!buf) {
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing context to find %d bytes GMR\n", SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "flushing context to find %d bytes GMR\n",
size); size);
/* Try flushing all pending DMAs */ /* Try flushing all pending DMAs */
svga_retry_enter(svga);
svga_context_flush(svga, NULL); svga_context_flush(svga, NULL);
buf = sws->buffer_create(sws, alignment, usage, size); buf = sws->buffer_create(sws, alignment, usage, size);
svga_retry_exit(svga);
} }
return buf; return buf;
@ -229,6 +231,12 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
bind_flags); bind_flags);
} }
if (ss->sws->have_gb_objects) {
/* Initialize the surface with zero */
ss->sws->surface_init(ss->sws, sbuf->handle, svga_surface_size(&sbuf->key),
sbuf->key.flags);
}
return ret; return ret;
} }
@ -255,14 +263,9 @@ svga_buffer_recreate_host_surface(struct svga_context *svga,
if (ret == PIPE_OK) { if (ret == PIPE_OK) {
/* Copy the surface data */ /* Copy the surface data */
assert(sbuf->handle); assert(sbuf->handle);
ret = SVGA3D_vgpu10_BufferCopy(svga->swc, old_handle, sbuf->handle, SVGA_RETRY(svga, SVGA3D_vgpu10_BufferCopy(svga->swc, old_handle,
0, 0, sbuf->b.b.width0); sbuf->handle,
if (ret != PIPE_OK) { 0, 0, sbuf->b.b.width0));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_BufferCopy(svga->swc, old_handle, sbuf->handle,
0, 0, sbuf->b.b.width0);
assert(ret == PIPE_OK);
}
} }
/* Set the new bind flags for this buffer resource */ /* Set the new bind flags for this buffer resource */
@ -344,8 +347,6 @@ svga_buffer_bind_host_surface(struct svga_context *svga,
struct svga_buffer *sbuf, struct svga_buffer *sbuf,
struct svga_buffer_surface *bufsurf) struct svga_buffer_surface *bufsurf)
{ {
enum pipe_error ret;
/* Update the to-bind surface */ /* Update the to-bind surface */
assert(bufsurf->handle); assert(bufsurf->handle);
assert(sbuf->handle); assert(sbuf->handle);
@ -354,14 +355,9 @@ svga_buffer_bind_host_surface(struct svga_context *svga,
* make sure to copy the buffer content. * make sure to copy the buffer content.
*/ */
if (sbuf->bind_flags & PIPE_BIND_STREAM_OUTPUT) { if (sbuf->bind_flags & PIPE_BIND_STREAM_OUTPUT) {
ret = SVGA3D_vgpu10_BufferCopy(svga->swc, sbuf->handle, bufsurf->handle, SVGA_RETRY(svga, SVGA3D_vgpu10_BufferCopy(svga->swc, sbuf->handle,
0, 0, sbuf->b.b.width0); bufsurf->handle,
if (ret != PIPE_OK) { 0, 0, sbuf->b.b.width0));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_BufferCopy(svga->swc, sbuf->handle, bufsurf->handle,
0, 0, sbuf->b.b.width0);
assert(ret == PIPE_OK);
}
} }
/* Set this surface as the current one */ /* Set this surface as the current one */
@ -943,7 +939,6 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
while (offset < range->end) { while (offset < range->end) {
struct svga_winsys_buffer *hwbuf; struct svga_winsys_buffer *hwbuf;
uint8_t *map; uint8_t *map;
enum pipe_error ret;
if (offset + size > range->end) if (offset + size > range->end)
size = range->end - offset; size = range->end - offset;
@ -968,19 +963,10 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
sws->buffer_unmap(sws, hwbuf); sws->buffer_unmap(sws, hwbuf);
} }
ret = SVGA3D_BufferDMA(svga->swc, SVGA_RETRY(svga, SVGA3D_BufferDMA(svga->swc,
hwbuf, sbuf->handle, hwbuf, sbuf->handle,
SVGA3D_WRITE_HOST_VRAM, SVGA3D_WRITE_HOST_VRAM,
size, 0, offset, sbuf->dma.flags); size, 0, offset, sbuf->dma.flags));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_BufferDMA(svga->swc,
hwbuf, sbuf->handle,
SVGA3D_WRITE_HOST_VRAM,
size, 0, offset, sbuf->dma.flags);
assert(ret == PIPE_OK);
}
sbuf->dma.flags.discard = FALSE; sbuf->dma.flags.discard = FALSE;
sws->buffer_destroy(sws, hwbuf); sws->buffer_destroy(sws, hwbuf);
@ -1061,12 +1047,7 @@ svga_buffer_handle(struct svga_context *svga, struct pipe_resource *buf,
ret = svga_buffer_update_hw(svga, sbuf, sbuf->bind_flags); ret = svga_buffer_update_hw(svga, sbuf, sbuf->bind_flags);
if (ret == PIPE_OK) { if (ret == PIPE_OK) {
/* Emit DMA or UpdateGBImage commands */ /* Emit DMA or UpdateGBImage commands */
ret = svga_buffer_upload_command(svga, sbuf); SVGA_RETRY_OOM(svga, ret, svga_buffer_upload_command(svga, sbuf));
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
svga_context_flush(svga, NULL);
ret = svga_buffer_upload_command(svga, sbuf);
assert(ret == PIPE_OK);
}
if (ret == PIPE_OK) { if (ret == PIPE_OK) {
sbuf->dma.pending = TRUE; sbuf->dma.pending = TRUE;
assert(!sbuf->head.prev && !sbuf->head.next); assert(!sbuf->head.prev && !sbuf->head.next);

View file

@ -58,7 +58,6 @@ svga_transfer_dma_band(struct svga_context *svga,
{ {
struct svga_texture *texture = svga_texture(st->base.resource); struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCopyBox box; SVGA3dCopyBox box;
enum pipe_error ret;
assert(!st->use_direct_map); assert(!st->use_direct_map);
@ -87,12 +86,7 @@ svga_transfer_dma_band(struct svga_context *svga,
(util_format_get_blockwidth(texture->b.b.format) (util_format_get_blockwidth(texture->b.b.format)
* util_format_get_blockheight(texture->b.b.format))); * util_format_get_blockheight(texture->b.b.format)));
ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags); SVGA_RETRY(svga, SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
assert(ret == PIPE_OK);
}
} }
@ -274,40 +268,28 @@ need_tex_readback(struct svga_transfer *st)
} }
static enum pipe_error static void
readback_image_vgpu9(struct svga_context *svga, readback_image_vgpu9(struct svga_context *svga,
struct svga_winsys_surface *surf, struct svga_winsys_surface *surf,
unsigned slice, unsigned slice,
unsigned level) unsigned level)
{ {
enum pipe_error ret; SVGA_RETRY(svga, SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level));
ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_ReadbackGBImage(svga->swc, surf, slice, level);
}
return ret;
} }
static enum pipe_error static void
readback_image_vgpu10(struct svga_context *svga, readback_image_vgpu10(struct svga_context *svga,
struct svga_winsys_surface *surf, struct svga_winsys_surface *surf,
unsigned slice, unsigned slice,
unsigned level, unsigned level,
unsigned numMipLevels) unsigned numMipLevels)
{ {
enum pipe_error ret;
unsigned subResource; unsigned subResource;
subResource = slice * numMipLevels + level; subResource = slice * numMipLevels + level;
ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource); SVGA_RETRY(svga, SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf,
if (ret != PIPE_OK) { subResource));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_ReadbackSubResource(svga->swc, surf, subResource);
}
return ret;
} }
@ -397,25 +379,20 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
unsigned usage = st->base.usage; unsigned usage = st->base.usage;
if (need_tex_readback(st)) { if (need_tex_readback(st)) {
enum pipe_error ret;
svga_surfaces_flush(svga); svga_surfaces_flush(svga);
if (!svga->swc->force_coherent || tex->imported) { if (!svga->swc->force_coherent || tex->imported) {
for (i = 0; i < st->box.d; i++) { for (i = 0; i < st->box.d; i++) {
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
ret = readback_image_vgpu10(svga, surf, st->slice + i, level, readback_image_vgpu10(svga, surf, st->slice + i, level,
tex->b.b.last_level + 1); tex->b.b.last_level + 1);
} else { } else {
ret = readback_image_vgpu9(svga, surf, st->slice + i, level); readback_image_vgpu9(svga, surf, st->slice + i, level);
} }
} }
svga->hud.num_readbacks++; svga->hud.num_readbacks++;
SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK); SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
assert(ret == PIPE_OK);
(void) ret;
svga_context_flush(svga, NULL); svga_context_flush(svga, NULL);
} }
/* /*
@ -465,26 +442,19 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
usage |= PIPE_TRANSFER_PERSISTENT | PIPE_TRANSFER_COHERENT; usage |= PIPE_TRANSFER_PERSISTENT | PIPE_TRANSFER_COHERENT;
} }
map = swc->surface_map(swc, surf, usage, &retry, &rebind); map = SVGA_TRY_MAP(svga->swc->surface_map
(svga->swc, surf, usage, &retry, &rebind), retry);
if (map == NULL && retry) { if (map == NULL && retry) {
/* /*
* At this point, the svga_surfaces_flush() should already have * At this point, the svga_surfaces_flush() should already have
* called in svga_texture_get_transfer(). * called in svga_texture_get_transfer().
*/ */
svga->hud.surface_write_flushes++; svga->hud.surface_write_flushes++;
svga_retry_enter(svga);
svga_context_flush(svga, NULL); svga_context_flush(svga, NULL);
map = swc->surface_map(swc, surf, usage, &retry, &rebind); map = svga->swc->surface_map(svga->swc, surf, usage, &retry, &rebind);
} svga_retry_exit(svga);
if (map && rebind) {
enum pipe_error ret;
ret = SVGA3D_BindGBSurface(swc, surf);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_BindGBSurface(swc, surf);
assert(ret == PIPE_OK);
}
svga_context_flush(svga, NULL);
} }
if (map && rebind) { if (map && rebind) {
@ -626,9 +596,12 @@ svga_texture_transfer_map(struct pipe_context *pipe,
pipe_resource_reference(&st->base.resource, texture); pipe_resource_reference(&st->base.resource, texture);
/* If this is the first time mapping to the surface in this /* If this is the first time mapping to the surface in this
* command buffer, clear the dirty masks of this surface. * command buffer and there is no pending primitives, clear
* the dirty masks of this surface.
*/ */
if (sws->surface_is_flushed(sws, surf)) { if (sws->surface_is_flushed(sws, surf) &&
(svga_have_vgpu10(svga) ||
!svga_hwtnl_has_pending_prim(svga->hwtnl))) {
svga_clear_texture_dirty(tex); svga_clear_texture_dirty(tex);
} }
@ -716,37 +689,23 @@ svga_texture_surface_unmap(struct svga_context *svga,
swc->surface_unmap(swc, surf, &rebind); swc->surface_unmap(swc, surf, &rebind);
if (rebind) { if (rebind) {
enum pipe_error ret; SVGA_RETRY(svga, SVGA3D_BindGBSurface(swc, surf));
ret = SVGA3D_BindGBSurface(swc, surf);
if (ret != PIPE_OK) {
/* flush and retry */
svga_context_flush(svga, NULL);
ret = SVGA3D_BindGBSurface(swc, surf);
assert(ret == PIPE_OK);
}
} }
} }
static enum pipe_error static void
update_image_vgpu9(struct svga_context *svga, update_image_vgpu9(struct svga_context *svga,
struct svga_winsys_surface *surf, struct svga_winsys_surface *surf,
const SVGA3dBox *box, const SVGA3dBox *box,
unsigned slice, unsigned slice,
unsigned level) unsigned level)
{ {
enum pipe_error ret; SVGA_RETRY(svga, SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level));
ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_UpdateGBImage(svga->swc, surf, box, slice, level);
}
return ret;
} }
static enum pipe_error static void
update_image_vgpu10(struct svga_context *svga, update_image_vgpu10(struct svga_context *svga,
struct svga_winsys_surface *surf, struct svga_winsys_surface *surf,
const SVGA3dBox *box, const SVGA3dBox *box,
@ -754,17 +713,12 @@ update_image_vgpu10(struct svga_context *svga,
unsigned level, unsigned level,
unsigned numMipLevels) unsigned numMipLevels)
{ {
enum pipe_error ret;
unsigned subResource; unsigned subResource;
subResource = slice * numMipLevels + level; subResource = slice * numMipLevels + level;
ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource); SVGA_RETRY(svga, SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box,
if (ret != PIPE_OK) { subResource));
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_UpdateSubResource(svga->swc, surf, box, subResource);
}
return ret;
} }
@ -819,7 +773,6 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
/* Now send an update command to update the content in the backend. */ /* Now send an update command to update the content in the backend. */
if (st->base.usage & PIPE_TRANSFER_WRITE) { if (st->base.usage & PIPE_TRANSFER_WRITE) {
struct svga_winsys_surface *surf = tex->handle; struct svga_winsys_surface *surf = tex->handle;
enum pipe_error ret;
assert(svga_have_gb_objects(svga)); assert(svga_have_gb_objects(svga));
@ -851,19 +804,16 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
unsigned i; unsigned i;
for (i = 0; i < nlayers; i++) { for (i = 0; i < nlayers; i++) {
ret = update_image_vgpu10(svga, surf, &box, update_image_vgpu10(svga, surf, &box,
st->slice + i, transfer->level, st->slice + i, transfer->level,
tex->b.b.last_level + 1); tex->b.b.last_level + 1);
assert(ret == PIPE_OK);
} }
} else { } else {
assert(nlayers == 1); assert(nlayers == 1);
ret = update_image_vgpu9(svga, surf, &box, st->slice, update_image_vgpu9(svga, surf, &box, st->slice,
transfer->level); transfer->level);
assert(ret == PIPE_OK);
} }
} }
(void) ret;
} }
} }
@ -1311,7 +1261,6 @@ svga_texture_generate_mipmap(struct pipe_context *pipe,
struct svga_pipe_sampler_view *sv; struct svga_pipe_sampler_view *sv;
struct svga_context *svga = svga_context(pipe); struct svga_context *svga = svga_context(pipe);
struct svga_texture *tex = svga_texture(pt); struct svga_texture *tex = svga_texture(pt);
enum pipe_error ret;
assert(svga_have_vgpu10(svga)); assert(svga_have_vgpu10(svga));
@ -1342,18 +1291,9 @@ svga_texture_generate_mipmap(struct pipe_context *pipe,
return false; return false;
sv = svga_pipe_sampler_view(psv); sv = svga_pipe_sampler_view(psv);
ret = svga_validate_pipe_sampler_view(svga, sv); SVGA_RETRY(svga, svga_validate_pipe_sampler_view(svga, sv));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = svga_validate_pipe_sampler_view(svga, sv);
assert(ret == PIPE_OK);
}
ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle); SVGA_RETRY(svga, SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_GenMips(svga->swc, sv->id, tex->handle);
}
pipe_sampler_view_reference(&psv, NULL); pipe_sampler_view_reference(&psv, NULL);
svga->hud.num_generate_mipmap++; svga->hud.num_generate_mipmap++;
@ -1521,7 +1461,6 @@ svga_texture_transfer_unmap_upload(struct svga_context *svga,
struct svga_winsys_surface *dstsurf; struct svga_winsys_surface *dstsurf;
struct pipe_resource *texture = st->base.resource; struct pipe_resource *texture = st->base.resource;
struct svga_texture *tex = svga_texture(texture); struct svga_texture *tex = svga_texture(texture);
enum pipe_error ret;
unsigned subResource; unsigned subResource;
unsigned numMipLevels; unsigned numMipLevels;
unsigned i, layer; unsigned i, layer;
@ -1545,22 +1484,12 @@ svga_texture_transfer_unmap_upload(struct svga_context *svga,
/* send a transferFromBuffer command to update the host texture surface */ /* send a transferFromBuffer command to update the host texture surface */
assert((offset & 15) == 0); assert((offset & 15) == 0);
ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf, SVGA_RETRY(svga, SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
offset, offset,
st->base.stride, st->base.stride,
st->base.layer_stride, st->base.layer_stride,
dstsurf, subResource, dstsurf, subResource,
&st->upload.box); &st->upload.box));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_TransferFromBuffer(svga->swc, srcsurf,
offset,
st->base.stride,
st->base.layer_stride,
dstsurf, subResource,
&st->upload.box);
assert(ret == PIPE_OK);
}
offset += st->base.layer_stride; offset += st->base.layer_stride;
/* Set rendered-to flag */ /* Set rendered-to flag */

View file

@ -723,7 +723,7 @@ vgpu10_get_shader_param(struct pipe_screen *screen,
else if (shader == PIPE_SHADER_GEOMETRY) else if (shader == PIPE_SHADER_GEOMETRY)
return VGPU10_MAX_GS_INPUTS; return VGPU10_MAX_GS_INPUTS;
else if (shader == PIPE_SHADER_TESS_CTRL) else if (shader == PIPE_SHADER_TESS_CTRL)
return VGPU11_MAX_HS_INPUTS; return VGPU11_MAX_HS_INPUT_CONTROL_POINTS;
else if (shader == PIPE_SHADER_TESS_EVAL) else if (shader == PIPE_SHADER_TESS_EVAL)
return VGPU11_MAX_DS_INPUT_CONTROL_POINTS; return VGPU11_MAX_DS_INPUT_CONTROL_POINTS;
else else

View file

@ -41,8 +41,8 @@
/** /**
* Return the size of the surface described by the key (in bytes). * Return the size of the surface described by the key (in bytes).
*/ */
static unsigned unsigned
surface_size(const struct svga_host_surface_cache_key *key) svga_surface_size(const struct svga_host_surface_cache_key *key)
{ {
unsigned bw, bh, bpb, total_size, i; unsigned bw, bh, bpb, total_size, i;
@ -142,7 +142,7 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen,
list_add(&entry->head, &cache->empty); list_add(&entry->head, &cache->empty);
/* update the cache size */ /* update the cache size */
surf_size = surface_size(&entry->key); surf_size = svga_surface_size(&entry->key);
assert(surf_size <= cache->total_size); assert(surf_size <= cache->total_size);
if (surf_size > cache->total_size) if (surf_size > cache->total_size)
cache->total_size = 0; /* should never happen, but be safe */ cache->total_size = 0; /* should never happen, but be safe */
@ -187,7 +187,7 @@ svga_screen_cache_shrink(struct svga_screen *svgascreen,
if (entry->key.format != SVGA3D_BUFFER) { if (entry->key.format != SVGA3D_BUFFER) {
/* we don't want to discard vertex/index buffers */ /* we don't want to discard vertex/index buffers */
cache->total_size -= surface_size(&entry->key); cache->total_size -= svga_surface_size(&entry->key);
assert(entry->handle); assert(entry->handle);
sws->surface_reference(sws, &entry->handle, NULL); sws->surface_reference(sws, &entry->handle, NULL);
@ -225,7 +225,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
if (!handle) if (!handle)
return; return;
surf_size = surface_size(key); surf_size = svga_surface_size(key);
*p_handle = NULL; *p_handle = NULL;
mtx_lock(&cache->mutex); mtx_lock(&cache->mutex);
@ -273,7 +273,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, SVGA_DBG(DEBUG_CACHE|DEBUG_DMA,
"unref sid %p (make space)\n", entry->handle); "unref sid %p (make space)\n", entry->handle);
cache->total_size -= surface_size(&entry->key); cache->total_size -= svga_surface_size(&entry->key);
sws->surface_reference(sws, &entry->handle, NULL); sws->surface_reference(sws, &entry->handle, NULL);
@ -373,7 +373,8 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
/* It is now safe to invalidate the surface content. /* It is now safe to invalidate the surface content.
* It will be done using the current context. * It will be done using the current context.
*/ */
if (SVGA3D_InvalidateGBSurface(svga->swc, entry->handle) != PIPE_OK) { if (SVGA_TRY(SVGA3D_InvalidateGBSurface(svga->swc, entry->handle))
!= PIPE_OK) {
ASSERTED enum pipe_error ret; ASSERTED enum pipe_error ret;
/* Even though surface invalidation here is done after the command /* Even though surface invalidation here is done after the command
@ -384,13 +385,16 @@ svga_screen_cache_flush(struct svga_screen *svgascreen,
* Note, we don't want to call svga_context_flush() here because * Note, we don't want to call svga_context_flush() here because
* this function itself is called inside svga_context_flush(). * this function itself is called inside svga_context_flush().
*/ */
svga_retry_enter(svga);
svga->swc->flush(svga->swc, NULL); svga->swc->flush(svga->swc, NULL);
nsurf = 0; nsurf = 0;
ret = SVGA3D_InvalidateGBSurface(svga->swc, entry->handle); ret = SVGA3D_InvalidateGBSurface(svga->swc, entry->handle);
svga_retry_exit(svga);
assert(ret == PIPE_OK); assert(ret == PIPE_OK);
} }
/* add the entry to the invalidated list */ /* add the entry to the invalidated list */
list_add(&entry->head, &cache->invalidated); list_add(&entry->head, &cache->invalidated);
nsurf++; nsurf++;
} }
@ -430,7 +434,7 @@ svga_screen_cache_cleanup(struct svga_screen *svgascreen)
"unref sid %p (shutdown)\n", cache->entries[i].handle); "unref sid %p (shutdown)\n", cache->entries[i].handle);
sws->surface_reference(sws, &cache->entries[i].handle, NULL); sws->surface_reference(sws, &cache->entries[i].handle, NULL);
cache->total_size -= surface_size(&cache->entries[i].key); cache->total_size -= svga_surface_size(&cache->entries[i].key);
} }
if (cache->entries[i].fence) if (cache->entries[i].fence)

View file

@ -159,5 +159,8 @@ svga_screen_surface_destroy(struct svga_screen *svgascreen,
void void
svga_screen_cache_dump(const struct svga_screen *svgascreen); svga_screen_cache_dump(const struct svga_screen *svgascreen);
unsigned
svga_surface_size(const struct svga_host_surface_cache_key *key);
#endif /* SVGA_SCREEN_CACHE_H_ */ #endif /* SVGA_SCREEN_CACHE_H_ */

View file

@ -50,6 +50,8 @@ struct svga_compile_key
unsigned need_prescale:1; unsigned need_prescale:1;
unsigned undo_viewport:1; unsigned undo_viewport:1;
unsigned allow_psiz:1; unsigned allow_psiz:1;
unsigned need_vertex_id_bias:1;
/** The following are all 32-bit bitmasks (per VS input) */ /** The following are all 32-bit bitmasks (per VS input) */
unsigned adjust_attrib_range; unsigned adjust_attrib_range;
unsigned attrib_is_pure_int; unsigned attrib_is_pure_int;
@ -93,6 +95,7 @@ struct svga_compile_key
/* tessellation control shader */ /* tessellation control shader */
struct { struct {
unsigned vertices_per_patch:8; unsigned vertices_per_patch:8;
unsigned vertices_out:8;
enum pipe_prim_type prim_mode:8; enum pipe_prim_type prim_mode:8;
enum pipe_tess_spacing spacing:3; enum pipe_tess_spacing spacing:3;
unsigned vertices_order_cw:1; unsigned vertices_order_cw:1;

View file

@ -97,8 +97,11 @@ static const struct svga_tracked_state *hw_draw_state_vgpu10[] =
&svga_hw_clip_planes, &svga_hw_clip_planes,
&svga_hw_vdecl, &svga_hw_vdecl,
&svga_hw_fs_constants, &svga_hw_fs_constants,
&svga_hw_fs_constbufs,
&svga_hw_gs_constants, &svga_hw_gs_constants,
&svga_hw_gs_constbufs,
&svga_hw_vs_constants, &svga_hw_vs_constants,
&svga_hw_vs_constbufs,
NULL NULL
}; };
@ -122,10 +125,15 @@ static const struct svga_tracked_state *hw_draw_state_sm5[] =
&svga_hw_clip_planes, &svga_hw_clip_planes,
&svga_hw_vdecl, &svga_hw_vdecl,
&svga_hw_fs_constants, &svga_hw_fs_constants,
&svga_hw_fs_constbufs,
&svga_hw_gs_constants, &svga_hw_gs_constants,
&svga_hw_gs_constbufs,
&svga_hw_tes_constants, &svga_hw_tes_constants,
&svga_hw_tes_constbufs,
&svga_hw_tcs_constants, &svga_hw_tcs_constants,
&svga_hw_tcs_constbufs,
&svga_hw_vs_constants, &svga_hw_vs_constants,
&svga_hw_vs_constbufs,
NULL NULL
}; };

View file

@ -76,6 +76,11 @@ extern struct svga_tracked_state svga_hw_gs_constants;
extern struct svga_tracked_state svga_hw_vs_constants; extern struct svga_tracked_state svga_hw_vs_constants;
extern struct svga_tracked_state svga_hw_tes_constants; extern struct svga_tracked_state svga_hw_tes_constants;
extern struct svga_tracked_state svga_hw_tcs_constants; extern struct svga_tracked_state svga_hw_tcs_constants;
extern struct svga_tracked_state svga_hw_fs_constbufs;
extern struct svga_tracked_state svga_hw_vs_constbufs;
extern struct svga_tracked_state svga_hw_gs_constbufs;
extern struct svga_tracked_state svga_hw_tcs_constbufs;
extern struct svga_tracked_state svga_hw_tes_constbufs;
/* SWTNL_DRAW /* SWTNL_DRAW
*/ */

View file

@ -219,6 +219,17 @@ svga_get_extra_vs_constants(const struct svga_context *svga, float *dest)
count += 1; count += 1;
} }
/* Bias to be added to VertexID */
if (variant->key.vs.need_vertex_id_bias) {
uint32_t *dest_u = (uint32_t *) dest; // uint version of dest
dest_u[0] = svga->curr.vertex_id_bias;
dest_u[1] = 1;
dest_u[2] = 1;
dest_u[3] = 1;
dest+=4;
count++;
}
/* SVGA_NEW_CLIP */ /* SVGA_NEW_CLIP */
count += svga_get_clip_plane_constants(svga, variant, &dest); count += svga_get_clip_plane_constants(svga, variant, &dest);
@ -560,22 +571,170 @@ emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
} }
/**
* A helper function to emit a constant buffer binding at the
* specified slot for the specified shader type
*/
static enum pipe_error static enum pipe_error
emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader) emit_constbuf(struct svga_context *svga,
unsigned slot,
enum pipe_shader_type shader,
unsigned buffer_offset,
unsigned buffer_size,
const void *buffer,
unsigned extra_buffer_offset,
unsigned extra_buffer_size,
const void *extra_buffer)
{ {
const struct pipe_constant_buffer *cbuf; struct svga_buffer *sbuf = svga_buffer((struct pipe_resource *)buffer);
struct pipe_resource *dst_buffer = NULL; struct pipe_resource *dst_buffer = NULL;
enum pipe_error ret = PIPE_OK; enum pipe_error ret = PIPE_OK;
struct pipe_transfer *src_transfer; struct pipe_transfer *src_transfer;
struct svga_winsys_surface *dst_handle; struct svga_winsys_surface *dst_handle = NULL;
unsigned new_buf_size = 0;
unsigned alloc_buf_size;
unsigned offset = 0;;
void *src_map = NULL, *dst_map;
if ((sbuf && sbuf->swbuf) || extra_buffer) {
/* buffer here is a user-space buffer so mapping it is really cheap. */
if (buffer_size > 0) {
src_map = pipe_buffer_map_range(&svga->pipe,
(struct pipe_resource *)buffer,
buffer_offset, buffer_size,
PIPE_TRANSFER_READ, &src_transfer);
assert(src_map);
if (!src_map) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
}
new_buf_size = MAX2(buffer_size, extra_buffer_offset) + extra_buffer_size;
/* According to the DX10 spec, the constant buffer size must be
* in multiples of 16.
*/
new_buf_size = align(new_buf_size, 16);
/* Constant buffer size in the upload buffer must be in multiples of 256.
* In order to maximize the chance of merging the upload buffer chunks
* when svga_buffer_add_range() is called,
* the allocate buffer size needs to be in multiples of 256 as well.
* Otherwise, since there is gap between each dirty range of the upload buffer,
* each dirty range will end up in its own UPDATE_GB_IMAGE command.
*/
alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
CONST0_UPLOAD_ALIGNMENT, &offset,
&dst_buffer, &dst_map);
if (!dst_map) {
if (src_map)
pipe_buffer_unmap(&svga->pipe, src_transfer);
return PIPE_ERROR_OUT_OF_MEMORY;
}
/* Initialize the allocated buffer slot to 0 to ensure the padding is
* filled with 0.
*/
memset(dst_map, 0, alloc_buf_size);
if (src_map) {
memcpy(dst_map, src_map, buffer_size);
pipe_buffer_unmap(&svga->pipe, src_transfer);
}
if (extra_buffer_size) {
assert(extra_buffer_offset + extra_buffer_size <= new_buf_size);
memcpy((char *) dst_map + extra_buffer_offset, extra_buffer,
extra_buffer_size);
}
/* Get winsys handle for the constant buffer */
if (svga->state.hw_draw.const0_buffer == dst_buffer &&
svga->state.hw_draw.const0_handle) {
/* re-reference already mapped buffer */
dst_handle = svga->state.hw_draw.const0_handle;
}
else {
/* we must unmap the buffer before getting the winsys handle */
u_upload_unmap(svga->const0_upload);
dst_handle = svga_buffer_handle(svga, dst_buffer,
PIPE_BIND_CONSTANT_BUFFER);
if (!dst_handle) {
pipe_resource_reference(&dst_buffer, NULL);
return PIPE_ERROR_OUT_OF_MEMORY;
}
}
}
else if (sbuf) {
dst_handle = svga_buffer_handle(svga, &sbuf->b.b, PIPE_BIND_CONSTANT_BUFFER);
new_buf_size = align(buffer_size, 16);
offset = buffer_offset;
}
assert(new_buf_size % 16 == 0);
const struct svga_screen *screen = svga_screen(svga->pipe.screen);
const struct svga_winsys_screen *sws = screen->sws;
/* Issue the SetSingleConstantBuffer command */
if (!sws->have_constant_buffer_offset_cmd ||
svga->state.hw_draw.constbufoffsets[shader][slot].handle != dst_handle ||
svga->state.hw_draw.constbufoffsets[shader][slot].size != new_buf_size) {
ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
slot, /* index */
svga_shader_type(shader),
dst_handle,
offset,
new_buf_size);
}
else if (dst_handle){
unsigned command = SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET + shader;
ret = SVGA3D_vgpu10_SetConstantBufferOffset(svga->swc,
command,
slot, /* index */
offset);
}
if (ret != PIPE_OK) {
pipe_resource_reference(&dst_buffer, NULL);
return ret;
}
/* save the upload buffer / handle for next time */
if (dst_buffer != buffer && dst_buffer) {
pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
svga->state.hw_draw.const0_handle = dst_handle;
}
/* Save this const buffer until it's replaced in the future.
* Otherwise, all references to the buffer will go away after the
* command buffer is submitted, it'll get recycled and we will have
* incorrect constant buffer bindings.
*/
pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][slot], dst_buffer);
svga->state.hw_draw.constbufoffsets[shader][slot].handle = dst_handle;
svga->state.hw_draw.constbufoffsets[shader][slot].size = new_buf_size;
pipe_resource_reference(&dst_buffer, NULL);
return PIPE_OK;
}
/* For constbuf 0 */
static enum pipe_error
emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
{
const struct pipe_constant_buffer *cbuf;
enum pipe_error ret = PIPE_OK;
float extras[MAX_EXTRA_CONSTS][4]; float extras[MAX_EXTRA_CONSTS][4];
unsigned extra_count, extra_size, extra_offset; unsigned extra_count, extra_size, extra_offset;
unsigned new_buf_size;
void *src_map = NULL, *dst_map;
unsigned offset;
const struct svga_shader_variant *variant; const struct svga_shader_variant *variant;
unsigned alloc_buf_size;
assert(shader == PIPE_SHADER_VERTEX || assert(shader == PIPE_SHADER_VERTEX ||
shader == PIPE_SHADER_GEOMETRY || shader == PIPE_SHADER_GEOMETRY ||
@ -630,131 +789,30 @@ emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
if (cbuf->buffer_size + extra_size == 0) if (cbuf->buffer_size + extra_size == 0)
return PIPE_OK; /* nothing to do */ return PIPE_OK; /* nothing to do */
/* Typically, the cbuf->buffer here is a user-space buffer so mapping ret = emit_constbuf(svga, 0, shader,
* it is really cheap. If we ever get real HW buffers for constants cbuf->buffer_offset, cbuf->buffer_size, cbuf->buffer,
* we should void mapping and instead use a ResourceCopy command. extra_offset, extra_size, extras);
*/ if (ret != PIPE_OK)
if (cbuf->buffer_size > 0) {
src_map = pipe_buffer_map_range(&svga->pipe, cbuf->buffer,
cbuf->buffer_offset, cbuf->buffer_size,
PIPE_TRANSFER_READ, &src_transfer);
assert(src_map);
if (!src_map) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
}
/* The new/dest buffer's size must be large enough to hold the original,
* user-specified constants, plus the extra constants.
* The size of the original constant buffer _should_ agree with what the
* shader is expecting, but it might not (it's not enforced anywhere by
* gallium).
*/
new_buf_size = MAX2(cbuf->buffer_size, extra_offset) + extra_size;
/* According to the DX10 spec, the constant buffer size must be
* in multiples of 16.
*/
new_buf_size = align(new_buf_size, 16);
/* Constant buffer size in the upload buffer must be in multiples of 256.
* In order to maximize the chance of merging the upload buffer chunks
* when svga_buffer_add_range() is called,
* the allocate buffer size needs to be in multiples of 256 as well.
* Otherwise, since there is gap between each dirty range of the upload buffer,
* each dirty range will end up in its own UPDATE_GB_IMAGE command.
*/
alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
CONST0_UPLOAD_ALIGNMENT, &offset,
&dst_buffer, &dst_map);
if (!dst_map) {
if (src_map)
pipe_buffer_unmap(&svga->pipe, src_transfer);
return PIPE_ERROR_OUT_OF_MEMORY;
}
if (src_map) {
memcpy(dst_map, src_map, cbuf->buffer_size);
pipe_buffer_unmap(&svga->pipe, src_transfer);
}
if (extra_size) {
assert(extra_offset + extra_size <= new_buf_size);
memcpy((char *) dst_map + extra_offset, extras, extra_size);
}
/* Get winsys handle for the constant buffer */
if (svga->state.hw_draw.const0_buffer == dst_buffer &&
svga->state.hw_draw.const0_handle) {
/* re-reference already mapped buffer */
dst_handle = svga->state.hw_draw.const0_handle;
}
else {
/* we must unmap the buffer before getting the winsys handle */
u_upload_unmap(svga->const0_upload);
dst_handle = svga_buffer_handle(svga, dst_buffer,
PIPE_BIND_CONSTANT_BUFFER);
if (!dst_handle) {
pipe_resource_reference(&dst_buffer, NULL);
return PIPE_ERROR_OUT_OF_MEMORY;
}
/* save the buffer / handle for next time */
pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
svga->state.hw_draw.const0_handle = dst_handle;
}
/* Issue the SetSingleConstantBuffer command */
assert(new_buf_size % 16 == 0);
ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
0, /* index */
svga_shader_type(shader),
dst_handle,
offset,
new_buf_size);
if (ret != PIPE_OK) {
pipe_resource_reference(&dst_buffer, NULL);
return ret; return ret;
}
/* Save this const buffer until it's replaced in the future. svga->state.hw_draw.default_constbuf_size[shader] =
* Otherwise, all references to the buffer will go away after the svga->state.hw_draw.constbufoffsets[shader][0].size;
* command buffer is submitted, it'll get recycled and we will have
* incorrect constant buffer bindings.
*/
pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], dst_buffer);
svga->state.hw_draw.default_constbuf_size[shader] = new_buf_size; svga->hud.num_const_updates++;
pipe_resource_reference(&dst_buffer, NULL);
svga->hud.num_const_buf_updates++;
return ret; return ret;
} }
static enum pipe_error static enum pipe_error
emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader) emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
{ {
enum pipe_error ret; enum pipe_error ret = PIPE_OK;
unsigned dirty_constbufs; unsigned dirty_constbufs;
unsigned enabled_constbufs; unsigned enabled_constbufs;
/* Emit 0th constant buffer (with extra constants) */
ret = emit_constbuf_vgpu10(svga, shader);
if (ret != PIPE_OK) {
return ret;
}
enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u; enabled_constbufs = svga->state.hw_draw.enabled_constbufs[shader] | 1u;
dirty_constbufs = (svga->state.dirty_constbufs[shader]|enabled_constbufs) & ~1u;
/* Emit other constant buffers (UBOs) */
dirty_constbufs = svga->state.dirty_constbufs[shader] & ~1u;
while (dirty_constbufs) { while (dirty_constbufs) {
unsigned index = u_bit_scan(&dirty_constbufs); unsigned index = u_bit_scan(&dirty_constbufs);
@ -762,15 +820,11 @@ emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
unsigned size = svga->curr.constbufs[shader][index].buffer_size; unsigned size = svga->curr.constbufs[shader][index].buffer_size;
struct svga_buffer *buffer = struct svga_buffer *buffer =
svga_buffer(svga->curr.constbufs[shader][index].buffer); svga_buffer(svga->curr.constbufs[shader][index].buffer);
struct svga_winsys_surface *handle;
if (buffer) { if (buffer) {
handle = svga_buffer_handle(svga, &buffer->b.b,
PIPE_BIND_CONSTANT_BUFFER);
enabled_constbufs |= 1 << index; enabled_constbufs |= 1 << index;
} }
else { else {
handle = NULL;
enabled_constbufs &= ~(1 << index); enabled_constbufs &= ~(1 << index);
assert(offset == 0); assert(offset == 0);
assert(size == 0); assert(size == 0);
@ -795,12 +849,9 @@ emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
} }
assert(size % 16 == 0); assert(size % 16 == 0);
ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
index, ret = emit_constbuf(svga, index, shader, offset, size, buffer,
svga_shader_type(shader), 0, 0, NULL);
handle,
offset,
size);
if (ret != PIPE_OK) if (ret != PIPE_OK)
return ret; return ret;
@ -824,7 +875,7 @@ emit_fs_consts(struct svga_context *svga, uint64_t dirty)
if (!variant) if (!variant)
return PIPE_OK; return PIPE_OK;
/* SVGA_NEW_FS_CONST_BUFFER /* SVGA_NEW_FS_CONSTS
*/ */
if (svga_have_vgpu10(svga)) { if (svga_have_vgpu10(svga)) {
ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT); ret = emit_consts_vgpu10(svga, PIPE_SHADER_FRAGMENT);
@ -836,17 +887,42 @@ emit_fs_consts(struct svga_context *svga, uint64_t dirty)
return ret; return ret;
} }
static enum pipe_error
emit_fs_constbuf(struct svga_context *svga, uint64_t dirty)
{
const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
enum pipe_error ret = PIPE_OK;
/* SVGA_NEW_FS_VARIANT
*/
if (!variant)
return PIPE_OK;
/* SVGA_NEW_FS_CONSTBUF
*/
assert(svga_have_vgpu10(svga));
ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_FRAGMENT);
return ret;
}
struct svga_tracked_state svga_hw_fs_constants = struct svga_tracked_state svga_hw_fs_constants =
{ {
"hw fs params", "hw fs params",
(SVGA_NEW_FS_CONST_BUFFER | (SVGA_NEW_FS_CONSTS |
SVGA_NEW_FS_VARIANT | SVGA_NEW_FS_VARIANT |
SVGA_NEW_TEXTURE_CONSTS), SVGA_NEW_TEXTURE_CONSTS),
emit_fs_consts emit_fs_consts
}; };
struct svga_tracked_state svga_hw_fs_constbufs =
{
"hw fs params",
SVGA_NEW_FS_CONST_BUFFER,
emit_fs_constbuf
};
static enum pipe_error static enum pipe_error
emit_vs_consts(struct svga_context *svga, uint64_t dirty) emit_vs_consts(struct svga_context *svga, uint64_t dirty)
@ -872,17 +948,45 @@ emit_vs_consts(struct svga_context *svga, uint64_t dirty)
} }
static enum pipe_error
emit_vs_constbuf(struct svga_context *svga, uint64_t dirty)
{
const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
enum pipe_error ret = PIPE_OK;
/* SVGA_NEW_FS_VARIANT
*/
if (!variant)
return PIPE_OK;
/* SVGA_NEW_FS_CONSTBUF
*/
assert(svga_have_vgpu10(svga));
ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_VERTEX);
return ret;
}
struct svga_tracked_state svga_hw_vs_constants = struct svga_tracked_state svga_hw_vs_constants =
{ {
"hw vs params", "hw vs params",
(SVGA_NEW_PRESCALE | (SVGA_NEW_PRESCALE |
SVGA_NEW_VS_CONST_BUFFER | SVGA_NEW_VS_CONSTS |
SVGA_NEW_VS_VARIANT | SVGA_NEW_VS_VARIANT |
SVGA_NEW_TEXTURE_CONSTS), SVGA_NEW_TEXTURE_CONSTS),
emit_vs_consts emit_vs_consts
}; };
struct svga_tracked_state svga_hw_vs_constbufs =
{
"hw vs params",
SVGA_NEW_VS_CONST_BUFFER,
emit_vs_constbuf
};
static enum pipe_error static enum pipe_error
emit_gs_consts(struct svga_context *svga, uint64_t dirty) emit_gs_consts(struct svga_context *svga, uint64_t dirty)
{ {
@ -912,11 +1016,31 @@ emit_gs_consts(struct svga_context *svga, uint64_t dirty)
} }
static enum pipe_error
emit_gs_constbuf(struct svga_context *svga, uint64_t dirty)
{
const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
enum pipe_error ret = PIPE_OK;
/* SVGA_NEW_GS_VARIANT
*/
if (!variant)
return PIPE_OK;
/* SVGA_NEW_GS_CONSTBUF
*/
assert(svga_have_vgpu10(svga));
ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_GEOMETRY);
return ret;
}
struct svga_tracked_state svga_hw_gs_constants = struct svga_tracked_state svga_hw_gs_constants =
{ {
"hw gs params", "hw gs params",
(SVGA_NEW_PRESCALE | (SVGA_NEW_PRESCALE |
SVGA_NEW_GS_CONST_BUFFER | SVGA_NEW_GS_CONSTS |
SVGA_NEW_RAST | SVGA_NEW_RAST |
SVGA_NEW_GS_VARIANT | SVGA_NEW_GS_VARIANT |
SVGA_NEW_TEXTURE_CONSTS), SVGA_NEW_TEXTURE_CONSTS),
@ -924,6 +1048,14 @@ struct svga_tracked_state svga_hw_gs_constants =
}; };
struct svga_tracked_state svga_hw_gs_constbufs =
{
"hw gs params",
SVGA_NEW_GS_CONST_BUFFER,
emit_gs_constbuf
};
/** /**
* Emit constant buffer for tessellation control shader * Emit constant buffer for tessellation control shader
*/ */
@ -947,15 +1079,43 @@ emit_tcs_consts(struct svga_context *svga, uint64_t dirty)
} }
static enum pipe_error
emit_tcs_constbuf(struct svga_context *svga, uint64_t dirty)
{
const struct svga_shader_variant *variant = svga->state.hw_draw.tcs;
enum pipe_error ret = PIPE_OK;
/* SVGA_NEW_TCS_VARIANT
*/
if (!variant)
return PIPE_OK;
/* SVGA_NEW_TCS_CONSTBUF
*/
assert(svga_have_vgpu10(svga));
ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_CTRL);
return ret;
}
struct svga_tracked_state svga_hw_tcs_constants = struct svga_tracked_state svga_hw_tcs_constants =
{ {
"hw tcs params", "hw tcs params",
(SVGA_NEW_TCS_CONST_BUFFER | (SVGA_NEW_TCS_CONSTS |
SVGA_NEW_TCS_VARIANT), SVGA_NEW_TCS_VARIANT),
emit_tcs_consts emit_tcs_consts
}; };
struct svga_tracked_state svga_hw_tcs_constbufs =
{
"hw tcs params",
SVGA_NEW_TCS_CONST_BUFFER,
emit_tcs_constbuf
};
/** /**
* Emit constant buffer for tessellation evaluation shader * Emit constant buffer for tessellation evaluation shader
*/ */
@ -977,11 +1137,39 @@ emit_tes_consts(struct svga_context *svga, uint64_t dirty)
} }
static enum pipe_error
emit_tes_constbuf(struct svga_context *svga, uint64_t dirty)
{
const struct svga_shader_variant *variant = svga->state.hw_draw.tes;
enum pipe_error ret = PIPE_OK;
/* SVGA_NEW_TES_VARIANT
*/
if (!variant)
return PIPE_OK;
/* SVGA_NEW_TES_CONSTBUF
*/
assert(svga_have_vgpu10(svga));
ret = emit_constbuf_vgpu10(svga, PIPE_SHADER_TESS_EVAL);
return ret;
}
struct svga_tracked_state svga_hw_tes_constants = struct svga_tracked_state svga_hw_tes_constants =
{ {
"hw tes params", "hw tes params",
(SVGA_NEW_PRESCALE | (SVGA_NEW_PRESCALE |
SVGA_NEW_TES_CONST_BUFFER | SVGA_NEW_TES_CONSTS |
SVGA_NEW_TES_VARIANT), SVGA_NEW_TES_VARIANT),
emit_tes_consts emit_tes_consts
}; };
struct svga_tracked_state svga_hw_tes_constbufs =
{
"hw gs params",
SVGA_NEW_TES_CONST_BUFFER,
emit_tes_constbuf
};

View file

@ -210,16 +210,34 @@ make_fs_key(const struct svga_context *svga,
if (!svga->state.sw.need_swtnl) { if (!svga->state.sw.need_swtnl) {
/* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE /* SVGA_NEW_RAST, SVGA_NEW_REDUCED_PRIMITIVE
*/ */
enum pipe_prim_type prim_mode;
struct svga_shader *shader;
/* Find the last shader in the vertex pipeline and the output primitive mode
* from that shader.
*/
if (svga->curr.tes) {
shader = &svga->curr.tes->base;
prim_mode = shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
} else if (svga->curr.gs) {
shader = &svga->curr.gs->base;
prim_mode = shader->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
} else {
shader = &svga->curr.vs->base;
prim_mode = svga->curr.reduced_prim;
}
key->fs.light_twoside = svga->curr.rast->templ.light_twoside; key->fs.light_twoside = svga->curr.rast->templ.light_twoside;
key->fs.front_ccw = svga->curr.rast->templ.front_ccw; key->fs.front_ccw = svga->curr.rast->templ.front_ccw;
key->fs.pstipple = (svga->curr.rast->templ.poly_stipple_enable && key->fs.pstipple = (svga->curr.rast->templ.poly_stipple_enable &&
svga->curr.reduced_prim == PIPE_PRIM_TRIANGLES); prim_mode == PIPE_PRIM_TRIANGLES);
key->fs.aa_point = (svga->curr.rast->templ.point_smooth && key->fs.aa_point = (svga->curr.rast->templ.point_smooth &&
svga->curr.reduced_prim == PIPE_PRIM_POINTS && prim_mode == PIPE_PRIM_POINTS &&
(svga->curr.rast->pointsize > 1.0 || (svga->curr.rast->pointsize > 1.0 ||
svga->curr.vs->base.info.writes_psize)); shader->info.writes_psize));
if (key->fs.aa_point) {
assert(svga->curr.gs != NULL); if (key->fs.aa_point && svga->curr.gs) {
assert(svga->curr.gs->aa_point_coord_index != -1); assert(svga->curr.gs->aa_point_coord_index != -1);
key->fs.aa_point_coord_index = svga->curr.gs->aa_point_coord_index; key->fs.aa_point_coord_index = svga->curr.gs->aa_point_coord_index;
} }

View file

@ -89,6 +89,14 @@ make_tcs_key(struct svga_context *svga, struct svga_compile_key *key)
key->tcs.vertices_order_cw = tes->vertices_order_cw; key->tcs.vertices_order_cw = tes->vertices_order_cw;
key->tcs.point_mode = tes->point_mode; key->tcs.point_mode = tes->point_mode;
/* The number of control point output from tcs is determined by the
* number of control point input expected in tes. If tes does not expect
* any control point input, then vertices_per_patch in the tes key will
* be 0, otherwise it will contain the number of vertices out as specified
* in the tcs property.
*/
key->tcs.vertices_out = tes->base.key.tes.vertices_per_patch;
if (svga->tcs.passthrough) if (svga->tcs.passthrough)
key->tcs.passthrough = 1; key->tcs.passthrough = 1;
@ -208,6 +216,7 @@ static void
make_tes_key(struct svga_context *svga, struct svga_compile_key *key) make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
{ {
struct svga_tes_shader *tes = svga->curr.tes; struct svga_tes_shader *tes = svga->curr.tes;
boolean has_control_point_inputs = FALSE;
memset(key, 0, sizeof *key); memset(key, 0, sizeof *key);
@ -217,8 +226,23 @@ make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
svga_init_shader_key_common(svga, PIPE_SHADER_TESS_EVAL, &tes->base, key); svga_init_shader_key_common(svga, PIPE_SHADER_TESS_EVAL, &tes->base, key);
assert(svga->curr.tcs); assert(svga->curr.tcs);
key->tes.vertices_per_patch =
svga->curr.tcs->base.info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT]; /*
* Check if this tes expects any output control points from tcs.
*/
for (unsigned i = 0; i < tes->base.info.num_inputs; i++) {
switch (tes->base.info.input_semantic_name[i]) {
case TGSI_SEMANTIC_PATCH:
case TGSI_SEMANTIC_TESSOUTER:
case TGSI_SEMANTIC_TESSINNER:
break;
default:
has_control_point_inputs = TRUE;
}
}
key->tes.vertices_per_patch = has_control_point_inputs ?
svga->curr.tcs->base.info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT] : 0;
key->tes.need_prescale = svga->state.hw_clear.prescale[0].enabled && key->tes.need_prescale = svga->state.hw_clear.prescale[0].enabled &&
(svga->curr.gs == NULL); (svga->curr.gs == NULL);
@ -239,7 +263,7 @@ make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
key->tes.need_tessinner = 0; key->tes.need_tessinner = 0;
key->tes.need_tessouter = 0; key->tes.need_tessouter = 0;
for (int i = 0; i < svga->curr.tcs->base.info.num_outputs; i++) { for (unsigned i = 0; i < svga->curr.tcs->base.info.num_outputs; i++) {
switch (svga->curr.tcs->base.info.output_semantic_name[i]) { switch (svga->curr.tcs->base.info.output_semantic_name[i]) {
case TGSI_SEMANTIC_TESSOUTER: case TGSI_SEMANTIC_TESSOUTER:
key->tes.need_tessouter = 1; key->tes.need_tessouter = 1;

View file

@ -175,6 +175,10 @@ make_vs_key(struct svga_context *svga, struct svga_compile_key *key)
return; return;
} }
if (svga_have_vgpu10(svga)) {
key->vs.need_vertex_id_bias = 1;
}
/* SVGA_NEW_PRESCALE */ /* SVGA_NEW_PRESCALE */
key->vs.need_prescale = svga->state.hw_clear.prescale[0].enabled && key->vs.need_prescale = svga->state.hw_clear.prescale[0].enabled &&
(svga->curr.tes == NULL) && (svga->curr.tes == NULL) &&

View file

@ -54,7 +54,6 @@ svga_texture_copy_region(struct svga_context *svga,
unsigned dst_x, unsigned dst_y, unsigned dst_z, unsigned dst_x, unsigned dst_y, unsigned dst_z,
unsigned width, unsigned height, unsigned depth) unsigned width, unsigned height, unsigned depth)
{ {
enum pipe_error ret;
SVGA3dCopyBox box; SVGA3dCopyBox box;
assert(svga_have_vgpu10(svga)); assert(svga_have_vgpu10(svga));
@ -69,16 +68,9 @@ svga_texture_copy_region(struct svga_context *svga,
box.srcy = src_y; box.srcy = src_y;
box.srcz = src_z; box.srcz = src_z;
ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc, SVGA_RETRY(svga, SVGA3D_vgpu10_PredCopyRegion
dst_handle, dstSubResource, (svga->swc, dst_handle, dstSubResource,
src_handle, srcSubResource, &box); src_handle, srcSubResource, &box));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
dst_handle, dstSubResource,
src_handle, srcSubResource, &box);
assert(ret == PIPE_OK);
}
} }
@ -93,7 +85,6 @@ svga_texture_copy_handle(struct svga_context *svga,
unsigned width, unsigned height, unsigned depth) unsigned width, unsigned height, unsigned depth)
{ {
struct svga_surface dst, src; struct svga_surface dst, src;
enum pipe_error ret;
SVGA3dCopyBox box, *boxes; SVGA3dCopyBox box, *boxes;
assert(svga); assert(svga);
@ -124,18 +115,11 @@ svga_texture_copy_handle(struct svga_context *svga,
dst_handle, dst_level, dst_x, dst_y, dst_z); dst_handle, dst_level, dst_x, dst_y, dst_z);
*/ */
ret = SVGA3D_BeginSurfaceCopy(svga->swc, SVGA_RETRY(svga, SVGA3D_BeginSurfaceCopy(svga->swc,
&src.base, &src.base,
&dst.base, &dst.base,
&boxes, 1); &boxes, 1));
if (ret != PIPE_OK) {
svga_context_flush(svga, NULL);
ret = SVGA3D_BeginSurfaceCopy(svga->swc,
&src.base,
&dst.base,
&boxes, 1);
assert(ret == PIPE_OK);
}
*boxes = box; *boxes = box;
SVGA_FIFOCommitAll(svga->swc); SVGA_FIFOCommitAll(svga->swc);
} }
@ -563,7 +547,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
* associated resource. We will then use the cloned surface view for * associated resource. We will then use the cloned surface view for
* render target. * render target.
*/ */
for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) { for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_TESS_EVAL; shader++) {
if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) { if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
SVGA_DBG(DEBUG_VIEWS, SVGA_DBG(DEBUG_VIEWS,
"same resource used in shaderResource and renderTarget 0x%x\n", "same resource used in shaderResource and renderTarget 0x%x\n",
@ -601,11 +585,7 @@ svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
* need to update the host-side copy with the invalid * need to update the host-side copy with the invalid
* content when the associated mob is first bound to the surface. * content when the associated mob is first bound to the surface.
*/ */
if (SVGA3D_InvalidateGBSurface(svga->swc, stex->handle) != PIPE_OK) { SVGA_RETRY(svga, SVGA3D_InvalidateGBSurface(svga->swc, stex->handle));
svga_context_flush(svga, NULL);
ret = SVGA3D_InvalidateGBSurface(svga->swc, stex->handle);
assert(ret == PIPE_OK);
}
stex->validated = TRUE; stex->validated = TRUE;
} }
@ -670,7 +650,6 @@ svga_surface_destroy(struct pipe_context *pipe,
struct svga_surface *s = svga_surface(surf); struct svga_surface *s = svga_surface(surf);
struct svga_texture *t = svga_texture(surf->texture); struct svga_texture *t = svga_texture(surf->texture);
struct svga_screen *ss = svga_screen(surf->texture->screen); struct svga_screen *ss = svga_screen(surf->texture->screen);
enum pipe_error ret = PIPE_OK;
SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_DESTROYSURFACE); SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_DESTROYSURFACE);
@ -689,8 +668,6 @@ svga_surface_destroy(struct pipe_context *pipe,
} }
if (s->view_id != SVGA3D_INVALID_ID) { if (s->view_id != SVGA3D_INVALID_ID) {
unsigned try;
/* The SVGA3D device will generate a device error if the /* The SVGA3D device will generate a device error if the
* render target view or depth stencil view is destroyed from * render target view or depth stencil view is destroyed from
* a context other than the one it was created with. * a context other than the one it was created with.
@ -702,18 +679,14 @@ svga_surface_destroy(struct pipe_context *pipe,
} }
else { else {
assert(svga_have_vgpu10(svga)); assert(svga_have_vgpu10(svga));
for (try = 0; try < 2; try++) { if (util_format_is_depth_or_stencil(s->base.format)) {
if (util_format_is_depth_or_stencil(s->base.format)) { SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc,
ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id); s->view_id));
} }
else { else {
ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id); SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc,
} s->view_id));
if (ret == PIPE_OK)
break;
svga_context_flush(svga, NULL);
} }
assert(ret == PIPE_OK);
util_bitmask_clear(svga->surface_view_id_bm, s->view_id); util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
} }
} }

View file

@ -216,9 +216,9 @@ svga_vbuf_submit_state(struct svga_vbuf_render *svga_render)
{ {
struct svga_context *svga = svga_render->svga; struct svga_context *svga = svga_render->svga;
SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS]; SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
enum pipe_error ret;
unsigned i; unsigned i;
static const unsigned zero[PIPE_MAX_ATTRIBS] = {0}; static const unsigned zero[PIPE_MAX_ATTRIBS] = {0};
boolean retried;
/* if the vdecl or vbuf hasn't changed do nothing */ /* if the vdecl or vbuf hasn't changed do nothing */
if (!svga->swtnl.new_vdecl) if (!svga->swtnl.new_vdecl)
@ -230,13 +230,10 @@ svga_vbuf_submit_state(struct svga_vbuf_render *svga_render)
memcpy(vdecl, svga_render->vdecl, sizeof(vdecl)); memcpy(vdecl, svga_render->vdecl, sizeof(vdecl));
/* flush the hw state */ /* flush the hw state */
ret = svga_hwtnl_flush(svga->hwtnl); SVGA_RETRY_CHECK(svga, svga_hwtnl_flush(svga->hwtnl), retried);
if (ret != PIPE_OK) { if (retried) {
svga_context_flush(svga, NULL);
ret = svga_hwtnl_flush(svga->hwtnl);
/* if we hit this path we might become synced with hw */ /* if we hit this path we might become synced with hw */
svga->swtnl.new_vbuf = TRUE; svga->swtnl.new_vbuf = TRUE;
assert(ret == PIPE_OK);
} }
for (i = 0; i < svga_render->vdecl_count; i++) { for (i = 0; i < svga_render->vdecl_count; i++) {

View file

@ -47,7 +47,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
ASSERTED unsigned old_num_vertex_buffers; ASSERTED unsigned old_num_vertex_buffers;
unsigned i; unsigned i;
const void *map; const void *map;
enum pipe_error ret; boolean retried;
SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLDRAWVBO); SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SWTNLDRAWVBO);
@ -58,12 +58,9 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
/* Make sure that the need_swtnl flag does not go away */ /* Make sure that the need_swtnl flag does not go away */
svga->state.sw.in_swtnl_draw = TRUE; svga->state.sw.in_swtnl_draw = TRUE;
ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW); SVGA_RETRY_CHECK(svga, svga_update_state(svga, SVGA_STATE_SWTNL_DRAW), retried);
if (ret != PIPE_OK) { if (retried) {
svga_context_flush(svga, NULL);
ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
svga->swtnl.new_vbuf = TRUE; svga->swtnl.new_vbuf = TRUE;
assert(ret == PIPE_OK);
} }
/* /*
@ -148,7 +145,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
svga->dirty |= SVGA_NEW_NEED_PIPELINE | SVGA_NEW_NEED_SWVFETCH; svga->dirty |= SVGA_NEW_NEED_PIPELINE | SVGA_NEW_NEED_SWVFETCH;
SVGA_STATS_TIME_POP(svga_sws(svga)); SVGA_STATS_TIME_POP(svga_sws(svga));
return ret; return PIPE_OK;
} }

View file

@ -279,6 +279,10 @@ struct svga_shader_emitter_v10
/* viewport constant */ /* viewport constant */
unsigned viewport_index; unsigned viewport_index;
unsigned vertex_id_bias_index;
unsigned vertex_id_sys_index;
unsigned vertex_id_tmp_index;
/* temp index of adjusted vertex attributes */ /* temp index of adjusted vertex attributes */
unsigned adjusted_input[PIPE_MAX_SHADER_INPUTS]; unsigned adjusted_input[PIPE_MAX_SHADER_INPUTS];
} vs; } vs;
@ -333,7 +337,6 @@ struct svga_shader_emitter_v10
struct { struct {
unsigned vertices_per_patch_index; /**< vertices_per_patch system value index */ unsigned vertices_per_patch_index; /**< vertices_per_patch system value index */
unsigned imm_index; /**< immediate for tcs */ unsigned imm_index; /**< immediate for tcs */
unsigned vertices_out;
unsigned invocation_id_sys_index; /**< invocation id */ unsigned invocation_id_sys_index; /**< invocation id */
unsigned invocation_id_tmp_index; unsigned invocation_id_tmp_index;
unsigned instruction_token_pos; /* token pos for the first instruction */ unsigned instruction_token_pos; /* token pos for the first instruction */
@ -343,6 +346,7 @@ struct svga_shader_emitter_v10
unsigned control_point_tmp_index; /* control point temporary register */ unsigned control_point_tmp_index; /* control point temporary register */
unsigned control_point_out_count; /* control point output count */ unsigned control_point_out_count; /* control point output count */
boolean control_point_phase; /* true if in control point phase */ boolean control_point_phase; /* true if in control point phase */
boolean fork_phase_add_signature; /* true if needs to add signature in fork phase */
unsigned patch_generic_out_count; /* per-patch generic output count */ unsigned patch_generic_out_count; /* per-patch generic output count */
unsigned patch_generic_out_index; /* per-patch generic output register index*/ unsigned patch_generic_out_index; /* per-patch generic output register index*/
unsigned patch_generic_tmp_index; /* per-patch generic temporary register index*/ unsigned patch_generic_tmp_index; /* per-patch generic temporary register index*/
@ -408,6 +412,7 @@ struct svga_shader_emitter_v10
/* VS/TCS/TES/GS/FS Linkage info */ /* VS/TCS/TES/GS/FS Linkage info */
struct shader_linkage linkage; struct shader_linkage linkage;
struct tgsi_shader_info *prevShaderInfo;
/* Shader signature */ /* Shader signature */
struct svga_shader_signature signature; struct svga_shader_signature signature;
@ -603,7 +608,7 @@ check_register_index(struct svga_shader_emitter_v10 *emit,
(emit->unit == PIPE_SHADER_FRAGMENT && (emit->unit == PIPE_SHADER_FRAGMENT &&
index >= VGPU10_MAX_FS_INPUTS) || index >= VGPU10_MAX_FS_INPUTS) ||
(emit->unit == PIPE_SHADER_TESS_CTRL && (emit->unit == PIPE_SHADER_TESS_CTRL &&
index >= VGPU11_MAX_HS_INPUTS) || index >= VGPU11_MAX_HS_INPUT_CONTROL_POINTS) ||
(emit->unit == PIPE_SHADER_TESS_EVAL && (emit->unit == PIPE_SHADER_TESS_EVAL &&
index >= VGPU11_MAX_DS_INPUT_CONTROL_POINTS)) { index >= VGPU11_MAX_DS_INPUT_CONTROL_POINTS)) {
emit->register_overflow = TRUE; emit->register_overflow = TRUE;
@ -1445,7 +1450,7 @@ static boolean
need_temp_reg_initialization(struct svga_shader_emitter_v10 *emit, need_temp_reg_initialization(struct svga_shader_emitter_v10 *emit,
unsigned index) unsigned index)
{ {
if (!(emit->info.indirect_files & (1u << TGSI_FILE_TEMPORARY)) if (!(emit->info.indirect_files && (1u << TGSI_FILE_TEMPORARY))
&& emit->current_loop_depth == 0) { && emit->current_loop_depth == 0) {
if (!emit->temp_map[index].initialized && if (!emit->temp_map[index].initialized &&
emit->temp_map[index].index < emit->num_shader_temps) { emit->temp_map[index].index < emit->num_shader_temps) {
@ -1575,10 +1580,18 @@ emit_src_register(struct svga_shader_emitter_v10 *emit,
} }
} }
else if (file == TGSI_FILE_SYSTEM_VALUE) { else if (file == TGSI_FILE_SYSTEM_VALUE) {
/* Map the TGSI system value to a VGPU10 input register */ if (index == emit->vs.vertex_id_sys_index &&
assert(index < ARRAY_SIZE(emit->system_value_indexes)); emit->vs.vertex_id_tmp_index != INVALID_INDEX) {
file = TGSI_FILE_INPUT; file = TGSI_FILE_TEMPORARY;
index = emit->system_value_indexes[index]; index = emit->vs.vertex_id_tmp_index;
swizzleX = swizzleY = swizzleZ = swizzleW = TGSI_SWIZZLE_X;
}
else {
/* Map the TGSI system value to a VGPU10 input register */
assert(index < ARRAY_SIZE(emit->system_value_indexes));
file = TGSI_FILE_INPUT;
index = emit->system_value_indexes[index];
}
} }
} }
else if (emit->unit == PIPE_SHADER_TESS_CTRL) { else if (emit->unit == PIPE_SHADER_TESS_CTRL) {
@ -1600,7 +1613,10 @@ emit_src_register(struct svga_shader_emitter_v10 *emit,
*/ */
operand0.numComponents = VGPU10_OPERAND_1_COMPONENT; operand0.numComponents = VGPU10_OPERAND_1_COMPONENT;
operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID; operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID;
index = 0; operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
operand0.mask = 0;
emit_dword(emit, operand0.value);
return;
} }
else { else {
/* There is no control point ID input declaration in /* There is no control point ID input declaration in
@ -1718,6 +1734,8 @@ emit_src_register(struct svga_shader_emitter_v10 *emit,
* to align with the tcs output index. * to align with the tcs output index.
*/ */
index = emit->linkage.input_map[index]; index = emit->linkage.input_map[index];
assert(index2 < emit->key.tes.vertices_per_patch);
} }
else { else {
if (index < emit->key.tes.tessfactor_index) if (index < emit->key.tes.tessfactor_index)
@ -2824,7 +2842,7 @@ emit_vgpu10_property(struct svga_shader_emitter_v10 *emit,
break; break;
case TGSI_PROPERTY_TCS_VERTICES_OUT: case TGSI_PROPERTY_TCS_VERTICES_OUT:
emit->tcs.vertices_out = prop->u[0].Data; /* This info is already captured in the shader key */
break; break;
case TGSI_PROPERTY_TES_PRIM_MODE: case TGSI_PROPERTY_TES_PRIM_MODE:
@ -2935,7 +2953,7 @@ emit_domain_shader_declarations(struct svga_shader_emitter_v10 *emit)
assert(emit->unit == PIPE_SHADER_TESS_EVAL); assert(emit->unit == PIPE_SHADER_TESS_EVAL);
/* Emit the input control point count */ /* Emit the input control point count */
assert(emit->key.tes.vertices_per_patch > 0 && assert(emit->key.tes.vertices_per_patch >= 0 &&
emit->key.tes.vertices_per_patch <= 32); emit->key.tes.vertices_per_patch <= 32);
opcode0.value = 0; opcode0.value = 0;
@ -3066,11 +3084,11 @@ emit_hull_shader_declarations(struct svga_shader_emitter_v10 *emit)
end_emit_instruction(emit); end_emit_instruction(emit);
/* Emit the output control point count */ /* Emit the output control point count */
assert(emit->tcs.vertices_out >= 0 && emit->tcs.vertices_out <= 32); assert(emit->key.tcs.vertices_out >= 0 && emit->key.tcs.vertices_out <= 32);
opcode0.value = 0; opcode0.value = 0;
opcode0.opcodeType = VGPU10_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT; opcode0.opcodeType = VGPU10_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT;
opcode0.controlPointCount = emit->tcs.vertices_out; opcode0.controlPointCount = emit->key.tcs.vertices_out;
begin_emit_instruction(emit); begin_emit_instruction(emit);
emit_dword(emit, opcode0.value); emit_dword(emit, opcode0.value);
end_emit_instruction(emit); end_emit_instruction(emit);
@ -3157,7 +3175,8 @@ needs_control_point_phase(struct svga_shader_emitter_v10 *emit)
* we need a control point phase to explicitly set the output control * we need a control point phase to explicitly set the output control
* points. * points.
*/ */
if (emit->key.tcs.vertices_per_patch != emit->tcs.vertices_out) if ((emit->key.tcs.vertices_per_patch != emit->key.tcs.vertices_out) &&
emit->key.tcs.vertices_out)
return TRUE; return TRUE;
for (i = 0; i < emit->info.num_outputs; i++) { for (i = 0; i < emit->info.num_outputs; i++) {
@ -3175,23 +3194,93 @@ needs_control_point_phase(struct svga_shader_emitter_v10 *emit)
/** /**
* Start the hull shader control point phase * A helper function to add shader signature for passthrough control point
* phase. This signature is also generated for passthrough control point
* phase from HLSL compiler and is needed by Metal Renderer.
*/ */
static boolean static void
emit_hull_shader_control_point_phase(struct svga_shader_emitter_v10 *emit) emit_passthrough_control_point_signature(struct svga_shader_emitter_v10 *emit)
{
struct svga_shader_signature *sgn = &emit->signature;
SVGA3dDXShaderSignatureEntry *sgnEntry;
unsigned i;
for (i = 0; i < emit->info.num_inputs; i++) {
unsigned index = emit->linkage.input_map[i];
enum tgsi_semantic sem_name = emit->info.input_semantic_name[i];
sgnEntry = &sgn->inputs[sgn->header.numInputSignatures++];
set_shader_signature_entry(sgnEntry, index,
tgsi_semantic_to_sgn_name[sem_name],
VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN,
SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT);
sgnEntry = &sgn->outputs[sgn->header.numOutputSignatures++];
set_shader_signature_entry(sgnEntry, i,
tgsi_semantic_to_sgn_name[sem_name],
VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN,
SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT);
}
}
/**
* A helper function to emit an instruction to start the control point phase
* in the hull shader.
*/
static void
emit_control_point_phase_instruction(struct svga_shader_emitter_v10 *emit)
{ {
VGPU10OpcodeToken0 opcode0; VGPU10OpcodeToken0 opcode0;
/* If there is no control point output, skip the control point phase. */
if (!needs_control_point_phase(emit))
return FALSE;
/* Start the control point phase in the hull shader */
opcode0.value = 0; opcode0.value = 0;
opcode0.opcodeType = VGPU10_OPCODE_HS_CONTROL_POINT_PHASE; opcode0.opcodeType = VGPU10_OPCODE_HS_CONTROL_POINT_PHASE;
begin_emit_instruction(emit); begin_emit_instruction(emit);
emit_dword(emit, opcode0.value); emit_dword(emit, opcode0.value);
end_emit_instruction(emit); end_emit_instruction(emit);
}
/**
* Start the hull shader control point phase
*/
static boolean
emit_hull_shader_control_point_phase(struct svga_shader_emitter_v10 *emit)
{
/* If there is no control point output, skip the control point phase. */
if (!needs_control_point_phase(emit)) {
if (!emit->key.tcs.vertices_out) {
/**
* If the tcs does not explicitly generate any control point output
* and the tes does not use any input control point, then
* emit an empty control point phase with zero output control
* point count.
*/
emit_control_point_phase_instruction(emit);
/**
* Since this is an empty control point phase, we will need to
* add input signatures when we parse the tcs again in the
* patch constant phase.
*/
emit->tcs.fork_phase_add_signature = TRUE;
}
else {
/**
* Before skipping the control point phase, add the signature for
* the passthrough control point.
*/
emit_passthrough_control_point_signature(emit);
}
return FALSE;
}
/* Start the control point phase in the hull shader */
emit_control_point_phase_instruction(emit);
/* Declare the output control point ID */ /* Declare the output control point ID */
if (emit->tcs.invocation_id_sys_index == INVALID_INDEX) { if (emit->tcs.invocation_id_sys_index == INVALID_INDEX) {
@ -3799,9 +3888,6 @@ emit_fs_output_declarations(struct svga_shader_emitter_v10 *emit)
emit->key.fs.write_color0_to_n_cbufs; emit->key.fs.write_color0_to_n_cbufs;
} }
} }
else {
assert(!emit->key.fs.write_color0_to_n_cbufs);
}
} }
else if (semantic_name == TGSI_SEMANTIC_POSITION) { else if (semantic_name == TGSI_SEMANTIC_POSITION) {
/* Fragment depth output */ /* Fragment depth output */
@ -4064,7 +4150,7 @@ emit_tesslevel_declaration(struct svga_shader_emitter_v10 *emit,
SVGA3dDXShaderSignatureEntry *sgnEntry = SVGA3dDXShaderSignatureEntry *sgnEntry =
&sgn->patchConstants[sgn->header.numPatchConstantSignatures++]; &sgn->patchConstants[sgn->header.numPatchConstantSignatures++];
set_shader_signature_entry(sgnEntry, index, set_shader_signature_entry(sgnEntry, index,
sgnName, SVGA3DWRITEMASK_0, sgnName, VGPU10_OPERAND_4_COMPONENT_MASK_X,
SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN, SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN,
SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT); SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT);
} }
@ -4324,6 +4410,7 @@ emit_system_value_declaration(struct svga_shader_emitter_v10 *emit,
map_tgsi_semantic_to_sgn_name(semantic_name)); map_tgsi_semantic_to_sgn_name(semantic_name));
break; break;
case TGSI_SEMANTIC_VERTEXID: case TGSI_SEMANTIC_VERTEXID:
emit->vs.vertex_id_sys_index = index;
index = alloc_system_value_index(emit, index); index = alloc_system_value_index(emit, index);
emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV, emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV,
VGPU10_OPERAND_TYPE_INPUT, VGPU10_OPERAND_TYPE_INPUT,
@ -4786,6 +4873,10 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
unsigned i; unsigned i;
unsigned size = emit->key.tcs.vertices_per_patch; unsigned size = emit->key.tcs.vertices_per_patch;
unsigned indicesMask = 0; unsigned indicesMask = 0;
boolean addSignature = TRUE;
if (!emit->tcs.control_point_phase)
addSignature = emit->tcs.fork_phase_add_signature;
for (i = 0; i < emit->info.num_inputs; i++) { for (i = 0; i < emit->info.num_inputs; i++) {
unsigned usage_mask = emit->info.input_usage_mask[i]; unsigned usage_mask = emit->info.input_usage_mask[i];
@ -4793,7 +4884,8 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
enum tgsi_semantic semantic_name = emit->info.input_semantic_name[i]; enum tgsi_semantic semantic_name = emit->info.input_semantic_name[i];
VGPU10_SYSTEM_NAME name = VGPU10_NAME_UNDEFINED; VGPU10_SYSTEM_NAME name = VGPU10_NAME_UNDEFINED;
VGPU10_OPERAND_TYPE operandType = VGPU10_OPERAND_TYPE_INPUT; VGPU10_OPERAND_TYPE operandType = VGPU10_OPERAND_TYPE_INPUT;
boolean addSignature = TRUE; SVGA3dDXSignatureSemanticName sgn_name =
map_tgsi_semantic_to_sgn_name(semantic_name);
/* indices that are declared */ /* indices that are declared */
indicesMask |= 1 << index; indicesMask |= 1 << index;
@ -4806,13 +4898,18 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
else if (usage_mask == 0) { else if (usage_mask == 0) {
continue; /* register is not actually used */ continue; /* register is not actually used */
} }
else if (semantic_name == TGSI_SEMANTIC_CLIPDIST) {
/* The shadow copy is being used here. So set the signature name
* to UNDEFINED.
*/
sgn_name = SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED;
}
/* input control points in the patch constant phase are emitted in the /* input control points in the patch constant phase are emitted in the
* vicp register rather than the v register. * vicp register rather than the v register.
*/ */
if (!emit->tcs.control_point_phase) { if (!emit->tcs.control_point_phase) {
operandType = VGPU10_OPERAND_TYPE_INPUT_CONTROL_POINT; operandType = VGPU10_OPERAND_TYPE_INPUT_CONTROL_POINT;
addSignature = emit->tcs.control_point_out_count == 0;
} }
/* Tessellation control shader inputs are two dimensional. /* Tessellation control shader inputs are two dimensional.
@ -4826,9 +4923,7 @@ emit_tcs_input_declarations(struct svga_shader_emitter_v10 *emit)
VGPU10_OPERAND_4_COMPONENT_MASK_MODE, VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
VGPU10_OPERAND_4_COMPONENT_MASK_ALL, VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
VGPU10_INTERPOLATION_UNDEFINED, VGPU10_INTERPOLATION_UNDEFINED,
addSignature, addSignature, sgn_name);
map_tgsi_semantic_to_sgn_name(semantic_name));
} }
if (emit->tcs.control_point_phase) { if (emit->tcs.control_point_phase) {
@ -4983,6 +5078,54 @@ emit_tes_input_declarations(struct svga_shader_emitter_v10 *emit)
} }
emit_tessfactor_input_declarations(emit); emit_tessfactor_input_declarations(emit);
/* DX spec requires DS input controlpoint/patch-constant signatures to match
* the HS output controlpoint/patch-constant signatures exactly.
* Add missing input declarations even if they are not used in the shader.
*/
if (emit->linkage.num_inputs < emit->linkage.prevShader.num_outputs) {
struct tgsi_shader_info *prevInfo = emit->prevShaderInfo;
for (i = 0; i < emit->linkage.prevShader.num_outputs; i++) {
/* If a tcs output does not have a corresponding input register in
* tes, add one.
*/
if (emit->linkage.prevShader.output_map[i] >
emit->linkage.input_map_max) {
const enum tgsi_semantic sem_name = prevInfo->output_semantic_name[i];
if (sem_name == TGSI_SEMANTIC_PATCH) {
emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT,
VGPU10_OPERAND_TYPE_INPUT_PATCH_CONSTANT,
VGPU10_OPERAND_INDEX_1D,
i, 1, VGPU10_NAME_UNDEFINED,
VGPU10_OPERAND_4_COMPONENT,
VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
VGPU10_INTERPOLATION_UNDEFINED,
TRUE,
map_tgsi_semantic_to_sgn_name(sem_name));
} else if (sem_name != TGSI_SEMANTIC_TESSINNER &&
sem_name != TGSI_SEMANTIC_TESSOUTER) {
emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT,
VGPU10_OPERAND_TYPE_INPUT_CONTROL_POINT,
VGPU10_OPERAND_INDEX_2D,
i, emit->key.tes.vertices_per_patch,
VGPU10_NAME_UNDEFINED,
VGPU10_OPERAND_4_COMPONENT,
VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
VGPU10_INTERPOLATION_UNDEFINED,
TRUE,
map_tgsi_semantic_to_sgn_name(sem_name));
}
/* tessellation factors are taken care of in
* emit_tessfactor_input_declarations().
*/
}
}
}
} }
@ -5088,7 +5231,7 @@ emit_output_declarations(struct svga_shader_emitter_v10 *emit)
VGPU10_NAME_UNDEFINED, VGPU10_NAME_UNDEFINED,
emit->output_usage_mask[emit->clip_dist_out_index], emit->output_usage_mask[emit->clip_dist_out_index],
TRUE, TRUE,
SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE); SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED);
if (emit->info.num_written_clipdistance > 4) { if (emit->info.num_written_clipdistance > 4) {
/* for the second clip distance register, each handles 4 planes */ /* for the second clip distance register, each handles 4 planes */
@ -5097,7 +5240,7 @@ emit_output_declarations(struct svga_shader_emitter_v10 *emit)
VGPU10_NAME_UNDEFINED, VGPU10_NAME_UNDEFINED,
emit->output_usage_mask[emit->clip_dist_out_index+1], emit->output_usage_mask[emit->clip_dist_out_index+1],
TRUE, TRUE,
SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE); SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED);
} }
} }
@ -5184,6 +5327,11 @@ emit_temporaries_declaration(struct svga_shader_emitter_v10 *emit)
total_temps++; total_temps++;
} }
if (emit->info.uses_vertexid) {
assert(emit->unit == PIPE_SHADER_VERTEX);
emit->vs.vertex_id_tmp_index = total_temps++;
}
if (emit->unit == PIPE_SHADER_VERTEX || emit->unit == PIPE_SHADER_GEOMETRY) { if (emit->unit == PIPE_SHADER_VERTEX || emit->unit == PIPE_SHADER_GEOMETRY) {
if (emit->vposition.need_prescale || emit->key.vs.undo_viewport || if (emit->vposition.need_prescale || emit->key.vs.undo_viewport ||
emit->key.clip_plane_enable || emit->key.clip_plane_enable ||
@ -5440,6 +5588,9 @@ emit_constant_declaration(struct svga_shader_emitter_v10 *emit)
if (emit->key.vs.undo_viewport) { if (emit->key.vs.undo_viewport) {
emit->vs.viewport_index = total_consts++; emit->vs.viewport_index = total_consts++;
} }
if (emit->key.vs.need_vertex_id_bias) {
emit->vs.vertex_id_bias_index = total_consts++;
}
} }
/* user-defined clip planes */ /* user-defined clip planes */
@ -9985,6 +10136,33 @@ emit_temp_prescale_instructions(struct svga_shader_emitter_v10 *emit)
} }
/**
* A helper function to emit an instruction in a vertex shader to add a bias
* to the VertexID system value. This patches the VertexID in the SVGA vertex
* shader to include the base vertex of an indexed primitive or the start index
* of a non-indexed primitive.
*/
static void
emit_vertex_id_nobase_instruction(struct svga_shader_emitter_v10 *emit)
{
struct tgsi_full_src_register vertex_id_bias_index =
make_src_const_reg(emit->vs.vertex_id_bias_index);
struct tgsi_full_src_register vertex_id_sys_src =
make_src_reg(TGSI_FILE_SYSTEM_VALUE, emit->vs.vertex_id_sys_index);
struct tgsi_full_src_register vertex_id_sys_src_x =
scalar_src(&vertex_id_sys_src, TGSI_SWIZZLE_X);
struct tgsi_full_dst_register vertex_id_tmp_dst =
make_dst_temp_reg(emit->vs.vertex_id_tmp_index);
/* IADD vertex_id_tmp, vertex_id_sys, vertex_id_bias */
unsigned vertex_id_tmp_index = emit->vs.vertex_id_tmp_index;
emit->vs.vertex_id_tmp_index = INVALID_INDEX;
emit_instruction_opn(emit, VGPU10_OPCODE_IADD, &vertex_id_tmp_dst,
&vertex_id_sys_src_x, &vertex_id_bias_index, NULL, FALSE,
FALSE);
emit->vs.vertex_id_tmp_index = vertex_id_tmp_index;
}
/** /**
* Hull Shader must have control point outputs. But tessellation * Hull Shader must have control point outputs. But tessellation
* control shader can return without writing to control point output. * control shader can return without writing to control point output.
@ -10155,6 +10333,7 @@ emit_pre_helpers(struct svga_shader_emitter_v10 *emit)
* do a second pass of the instructions for the patch constant phase. * do a second pass of the instructions for the patch constant phase.
*/ */
emit->tcs.instruction_token_pos = emit->cur_tgsi_token; emit->tcs.instruction_token_pos = emit->cur_tgsi_token;
emit->tcs.fork_phase_add_signature = FALSE;
if (!emit_hull_shader_control_point_phase(emit)) { if (!emit_hull_shader_control_point_phase(emit)) {
emit->skip_instruction = TRUE; emit->skip_instruction = TRUE;
@ -10230,6 +10409,9 @@ emit_pre_helpers(struct svga_shader_emitter_v10 *emit)
} }
else if (emit->unit == PIPE_SHADER_VERTEX) { else if (emit->unit == PIPE_SHADER_VERTEX) {
emit_vertex_attrib_instructions(emit); emit_vertex_attrib_instructions(emit);
if (emit->info.uses_vertexid)
emit_vertex_id_nobase_instruction(emit);
} }
else if (emit->unit == PIPE_SHADER_TESS_EVAL) { else if (emit->unit == PIPE_SHADER_TESS_EVAL) {
emit_temp_tessfactor_instructions(emit); emit_temp_tessfactor_instructions(emit);
@ -10707,6 +10889,7 @@ compute_input_mapping(struct svga_context *svga,
if (prevShader != NULL) { if (prevShader != NULL) {
svga_link_shaders(&prevShader->info, &emit->info, &emit->linkage); svga_link_shaders(&prevShader->info, &emit->info, &emit->linkage);
emit->prevShaderInfo = &prevShader->info;
} }
else { else {
/** /**
@ -10830,6 +11013,10 @@ svga_tgsi_vgpu10_translate(struct svga_context *svga,
emit->vposition.so_index = INVALID_INDEX; emit->vposition.so_index = INVALID_INDEX;
emit->vposition.out_index = INVALID_INDEX; emit->vposition.out_index = INVALID_INDEX;
emit->vs.vertex_id_sys_index = INVALID_INDEX;
emit->vs.vertex_id_tmp_index = INVALID_INDEX;
emit->vs.vertex_id_bias_index = INVALID_INDEX;
emit->fs.color_tmp_index = INVALID_INDEX; emit->fs.color_tmp_index = INVALID_INDEX;
emit->fs.face_input_index = INVALID_INDEX; emit->fs.face_input_index = INVALID_INDEX;
emit->fs.fragcoord_input_index = INVALID_INDEX; emit->fs.fragcoord_input_index = INVALID_INDEX;

View file

@ -132,6 +132,8 @@ enum svga_stats_time {
SVGA_STATS_TIME_CREATEGS, SVGA_STATS_TIME_CREATEGS,
SVGA_STATS_TIME_CREATESURFACE, SVGA_STATS_TIME_CREATESURFACE,
SVGA_STATS_TIME_CREATESURFACEVIEW, SVGA_STATS_TIME_CREATESURFACEVIEW,
SVGA_STATS_TIME_CREATETCS,
SVGA_STATS_TIME_CREATETES,
SVGA_STATS_TIME_CREATETEXTURE, SVGA_STATS_TIME_CREATETEXTURE,
SVGA_STATS_TIME_CREATEVS, SVGA_STATS_TIME_CREATEVS,
SVGA_STATS_TIME_DEFINESHADER, SVGA_STATS_TIME_DEFINESHADER,
@ -141,6 +143,8 @@ enum svga_stats_time {
SVGA_STATS_TIME_DRAWELEMENTS, SVGA_STATS_TIME_DRAWELEMENTS,
SVGA_STATS_TIME_EMITFS, SVGA_STATS_TIME_EMITFS,
SVGA_STATS_TIME_EMITGS, SVGA_STATS_TIME_EMITGS,
SVGA_STATS_TIME_EMITTCS,
SVGA_STATS_TIME_EMITTES,
SVGA_STATS_TIME_EMITVS, SVGA_STATS_TIME_EMITVS,
SVGA_STATS_TIME_EMULATESURFACEVIEW, SVGA_STATS_TIME_EMULATESURFACEVIEW,
SVGA_STATS_TIME_FENCEFINISH, SVGA_STATS_TIME_FENCEFINISH,
@ -201,6 +205,8 @@ enum svga_stats_time {
SVGA_STATS_PREFIX "CreateGS", \ SVGA_STATS_PREFIX "CreateGS", \
SVGA_STATS_PREFIX "CreateSurface", \ SVGA_STATS_PREFIX "CreateSurface", \
SVGA_STATS_PREFIX "CreateSurfaceView", \ SVGA_STATS_PREFIX "CreateSurfaceView", \
SVGA_STATS_PREFIX "CreateTCS", \
SVGA_STATS_PREFIX "CreateTES", \
SVGA_STATS_PREFIX "CreateTexture", \ SVGA_STATS_PREFIX "CreateTexture", \
SVGA_STATS_PREFIX "CreateVS", \ SVGA_STATS_PREFIX "CreateVS", \
SVGA_STATS_PREFIX "DefineShader", \ SVGA_STATS_PREFIX "DefineShader", \
@ -210,6 +216,8 @@ enum svga_stats_time {
SVGA_STATS_PREFIX "DrawElements", \ SVGA_STATS_PREFIX "DrawElements", \
SVGA_STATS_PREFIX "EmitFS", \ SVGA_STATS_PREFIX "EmitFS", \
SVGA_STATS_PREFIX "EmitGS", \ SVGA_STATS_PREFIX "EmitGS", \
SVGA_STATS_PREFIX "EmitTCS", \
SVGA_STATS_PREFIX "EmitTES", \
SVGA_STATS_PREFIX "EmitVS", \ SVGA_STATS_PREFIX "EmitVS", \
SVGA_STATS_PREFIX "EmulateSurfaceView", \ SVGA_STATS_PREFIX "EmulateSurfaceView", \
SVGA_STATS_PREFIX "FenceFinish", \ SVGA_STATS_PREFIX "FenceFinish", \
@ -594,6 +602,11 @@ struct svga_winsys_screen
uint32 numMipLevels, uint32 numMipLevels,
uint32 numSamples); uint32 numSamples);
void
(*surface_init)(struct svga_winsys_screen *sws,
struct svga_winsys_surface *surface,
unsigned surf_size, SVGA3dSurfaceAllFlags flags);
/** /**
* Buffer management. Buffer attributes are mostly fixed over its lifetime. * Buffer management. Buffer attributes are mostly fixed over its lifetime.
* *
@ -786,6 +799,7 @@ struct svga_winsys_screen
boolean have_transfer_from_buffer_cmd; boolean have_transfer_from_buffer_cmd;
boolean have_fence_fd; boolean have_fence_fd;
boolean have_intra_surface_copy; boolean have_intra_surface_copy;
boolean have_constant_buffer_offset_cmd;
}; };

View file

@ -98,6 +98,7 @@ vmw_winsys_create( int fd )
vws->base.have_gb_dma = !vws->force_coherent; vws->base.have_gb_dma = !vws->force_coherent;
vws->base.need_to_rebind_resources = FALSE; vws->base.need_to_rebind_resources = FALSE;
vws->base.have_transfer_from_buffer_cmd = vws->base.have_vgpu10; vws->base.have_transfer_from_buffer_cmd = vws->base.have_vgpu10;
vws->base.have_constant_buffer_offset_cmd = FALSE;
getenv_val = getenv("SVGA_FORCE_KERNEL_UNMAPS"); getenv_val = getenv("SVGA_FORCE_KERNEL_UNMAPS");
vws->cache_maps = !getenv_val || strcmp(getenv_val, "0") == 0; vws->cache_maps = !getenv_val || strcmp(getenv_val, "0") == 0;
vws->fence_ops = vmw_fence_ops_create(vws); vws->fence_ops = vmw_fence_ops_create(vws);

View file

@ -495,6 +495,7 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
vws->base.buffer_map = vmw_svga_winsys_buffer_map; vws->base.buffer_map = vmw_svga_winsys_buffer_map;
vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap; vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap;
vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy; vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy;
vws->base.surface_init = vmw_svga_winsys_surface_init;
vws->base.fence_reference = vmw_svga_winsys_fence_reference; vws->base.fence_reference = vmw_svga_winsys_fence_reference;
vws->base.fence_signalled = vmw_svga_winsys_fence_signalled; vws->base.fence_signalled = vmw_svga_winsys_fence_signalled;
vws->base.shader_create = vmw_svga_winsys_shader_create; vws->base.shader_create = vmw_svga_winsys_shader_create;

View file

@ -34,7 +34,68 @@
#include "vmw_context.h" #include "vmw_context.h"
#include "pipebuffer/pb_bufmgr.h" #include "pipebuffer/pb_bufmgr.h"
void
vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws,
struct svga_winsys_surface *srf,
unsigned surf_size, SVGA3dSurfaceAllFlags flags)
{
struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
void *data = NULL;
struct pb_buffer *pb_buf;
uint32_t pb_flags;
struct vmw_winsys_screen *vws = vsrf->screen;
pb_flags = PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
struct pb_manager *provider;
struct pb_desc desc;
data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf,
PIPE_TRANSFER_DONTBLOCK | pb_flags);
if (data)
goto out_unlock;
provider = vws->pools.mob_fenced;
memset(&desc, 0, sizeof(desc));
desc.alignment = 4096;
pb_buf = provider->create_buffer(provider, vsrf->size, &desc);
if (pb_buf != NULL) {
struct svga_winsys_buffer *vbuf =
vmw_svga_winsys_buffer_wrap(pb_buf);
data = vmw_svga_winsys_buffer_map(&vws->base, vbuf, pb_flags);
if (data) {
if (vsrf->buf) {
vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf);
vsrf->buf = vbuf;
goto out_unlock;
} else
vmw_svga_winsys_buffer_destroy(&vws->base, vbuf);
}
}
data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags);
if (data == NULL)
goto out_unlock;
out_unlock:
mtx_unlock(&vsrf->mutex);
if (data)
{
if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) {
memset(data, 0, surf_size + sizeof(SVGA3dDXSOState));
}
else {
memset(data, 0, surf_size);
}
}
mtx_lock(&vsrf->mutex);
vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf);
mtx_unlock(&vsrf->mutex);
}
void * void *
vmw_svga_winsys_surface_map(struct svga_winsys_context *swc, vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
struct svga_winsys_surface *srf, struct svga_winsys_surface *srf,

View file

@ -95,4 +95,10 @@ void
vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc, vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc,
struct svga_winsys_surface *srf, struct svga_winsys_surface *srf,
boolean *rebind); boolean *rebind);
void
vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws,
struct svga_winsys_surface *surface,
unsigned surf_size, SVGA3dSurfaceAllFlags flags);
#endif /* VMW_SURFACE_H_ */ #endif /* VMW_SURFACE_H_ */