X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_draw.c;h=366a2dccdf128c1487ad8df6e937181f03fac5e0;hb=7ce20cf59a1171c4fa2e17a6c0c2f7e24b1150d2;hp=2c873a0f7ac276fc65ccb80c0c12df6ef20fecb2;hpb=610c24b19d21f3d147fde4d96a3afaa107670f1e;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index 2c873a0f7ac..366a2dccdf1 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -42,18 +42,16 @@ #include "svga_cmd.h" -struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga, - struct u_upload_mgr *upload_ib, - struct svga_winsys_context *swc ) +struct svga_hwtnl * +svga_hwtnl_create(struct svga_context *svga) { struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl); if (hwtnl == NULL) goto fail; hwtnl->svga = svga; - hwtnl->upload_ib = upload_ib; - - hwtnl->cmd.swc = swc; + + hwtnl->cmd.swc = svga->swc; return hwtnl; @@ -61,14 +59,15 @@ fail: return NULL; } -void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl ) + +void +svga_hwtnl_destroy(struct svga_hwtnl *hwtnl) { - int i, j; + unsigned i, j; for (i = 0; i < PIPE_PRIM_MAX; i++) { for (j = 0; j < IDX_CACHE_MAX; j++) { - pipe_resource_reference( &hwtnl->index_cache[i][j].buffer, - NULL ); + pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL); } } @@ -77,60 +76,93 @@ void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl ) for (i = 0; i < hwtnl->cmd.prim_count; i++) pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); - FREE(hwtnl); } -void svga_hwtnl_set_flatshade( struct svga_hwtnl *hwtnl, - boolean flatshade, - boolean flatshade_first ) +void +svga_hwtnl_set_flatshade(struct svga_hwtnl *hwtnl, + boolean flatshade, boolean flatshade_first) { hwtnl->hw_pv = PV_FIRST; hwtnl->api_pv = (flatshade && !flatshade_first) ? PV_LAST : PV_FIRST; -} +} + -void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl, - unsigned mode ) +void +svga_hwtnl_set_unfilled(struct svga_hwtnl *hwtnl, unsigned mode) { hwtnl->api_fillmode = mode; -} +} + -void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl, - unsigned count ) +void +svga_hwtnl_reset_vdecl(struct svga_hwtnl *hwtnl, unsigned count) { unsigned i; assert(hwtnl->cmd.prim_count == 0); for (i = count; i < hwtnl->cmd.vdecl_count; i++) { - pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], - NULL); + pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], NULL); } hwtnl->cmd.vdecl_count = count; } -void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl, - unsigned i, - const SVGA3dVertexDecl *decl, - struct pipe_resource *vb) +void +svga_hwtnl_vdecl(struct svga_hwtnl *hwtnl, + unsigned i, + const SVGA3dVertexDecl * decl, struct pipe_resource *vb) { assert(hwtnl->cmd.prim_count == 0); - assert( i < hwtnl->cmd.vdecl_count ); + assert(i < hwtnl->cmd.vdecl_count); hwtnl->cmd.vdecl[i] = *decl; - pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], vb); + pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], vb); } +/** + * Determine whether the specified buffer is referred in the primitive queue, + * for which no commands have been written yet. + */ +boolean +svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl, + struct pipe_resource *buffer) +{ + unsigned i; + + if (svga_buffer_is_user_buffer(buffer)) { + return FALSE; + } + + if (!hwtnl->cmd.prim_count) { + return FALSE; + } + + for (i = 0; i < hwtnl->cmd.vdecl_count; ++i) { + if (hwtnl->cmd.vdecl_vb[i] == buffer) { + return TRUE; + } + } + + for (i = 0; i < hwtnl->cmd.prim_count; ++i) { + if (hwtnl->cmd.prim_ib[i] == buffer) { + return TRUE; + } + } + + return FALSE; +} + enum pipe_error -svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) +svga_hwtnl_flush(struct svga_hwtnl *hwtnl) { struct svga_winsys_context *swc = hwtnl->cmd.swc; struct svga_context *svga = hwtnl->svga; @@ -144,10 +176,8 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) SVGA3dPrimitiveRange *prim; unsigned i; - /* Unmap upload manager vertex buffers */ - u_upload_flush(svga->upload_vb); - for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { + assert(!svga_buffer_is_user_buffer(hwtnl->cmd.vdecl_vb[i])); handle = svga_buffer_handle(svga, hwtnl->cmd.vdecl_vb[i]); if (handle == NULL) return PIPE_ERROR_OUT_OF_MEMORY; @@ -155,38 +185,60 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) vb_handle[i] = handle; } - /* Unmap upload manager index buffers */ - u_upload_flush(svga->upload_ib); - for (i = 0; i < hwtnl->cmd.prim_count; i++) { if (hwtnl->cmd.prim_ib[i]) { + assert(!svga_buffer_is_user_buffer(hwtnl->cmd.prim_ib[i])); handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]); if (handle == NULL) return PIPE_ERROR_OUT_OF_MEMORY; } - else + else { handle = NULL; + } ib_handle[i] = handle; } + if (svga->rebind.rendertargets) { + ret = svga_reemit_framebuffer_bindings(svga); + if (ret != PIPE_OK) { + return ret; + } + } + + if (svga->rebind.texture_samplers) { + ret = svga_reemit_tss_bindings(svga); + if (ret != PIPE_OK) { + return ret; + } + } + + if (svga->rebind.vs) { + ret = svga_reemit_vs_bindings(svga); + if (ret != PIPE_OK) { + return ret; + } + } + + if (svga->rebind.fs) { + ret = svga_reemit_fs_bindings(svga); + if (ret != PIPE_OK) { + return ret; + } + } + SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n", svga->curr.framebuffer.cbufs[0] ? svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL, hwtnl->cmd.prim_count); - ret = SVGA3D_BeginDrawPrimitives(swc, - &vdecl, - hwtnl->cmd.vdecl_count, - &prim, - hwtnl->cmd.prim_count); - if (ret != PIPE_OK) + ret = SVGA3D_BeginDrawPrimitives(swc, &vdecl, hwtnl->cmd.vdecl_count, + &prim, hwtnl->cmd.prim_count); + if (ret != PIPE_OK) return ret; - - memcpy( vdecl, - hwtnl->cmd.vdecl, - hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]); + memcpy(vdecl, hwtnl->cmd.vdecl, + hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]); for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { /* Given rangeHint is considered to be relative to indexBias, and @@ -202,25 +254,20 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) vdecl[i].rangeHint.last = 0; } - swc->surface_relocation(swc, - &vdecl[i].array.surfaceId, - vb_handle[i], - SVGA_RELOC_READ); + swc->surface_relocation(swc, &vdecl[i].array.surfaceId, NULL, + vb_handle[i], SVGA_RELOC_READ); } - memcpy( prim, - hwtnl->cmd.prim, - hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]); + memcpy(prim, hwtnl->cmd.prim, + hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]); for (i = 0; i < hwtnl->cmd.prim_count; i++) { - swc->surface_relocation(swc, - &prim[i].indexArray.surfaceId, - ib_handle[i], - SVGA_RELOC_READ); + swc->surface_relocation(swc, &prim[i].indexArray.surfaceId, NULL, + ib_handle[i], SVGA_RELOC_READ); pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); } - - SVGA_FIFOCommitAll( swc ); + + SVGA_FIFOCommitAll(swc); hwtnl->cmd.prim_count = 0; } @@ -228,6 +275,11 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) } +void +svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias) +{ + hwtnl->index_bias = index_bias; +} @@ -235,151 +287,164 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl ) * Internal functions: */ -enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, - const SVGA3dPrimitiveRange *range, - unsigned min_index, - unsigned max_index, - struct pipe_resource *ib ) +/** + * For debugging only. + */ +static void +check_draw_params(struct svga_hwtnl *hwtnl, + const SVGA3dPrimitiveRange *range, + unsigned min_index, unsigned max_index, + struct pipe_resource *ib) { - int ret = PIPE_OK; - -#ifdef DEBUG - { - unsigned i; - for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { - struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i]; - unsigned size = vb ? vb->width0 : 0; - unsigned offset = hwtnl->cmd.vdecl[i].array.offset; - unsigned stride = hwtnl->cmd.vdecl[i].array.stride; - unsigned index_bias = range->indexBias; - unsigned width; - - assert(vb); - assert(size); - assert(offset < size); - assert(index_bias >= 0); - assert(min_index <= max_index); - assert(offset + index_bias*stride < size); - if (min_index != ~0) { - assert(offset + (index_bias + min_index) * stride < size); - } + unsigned i; - switch (hwtnl->cmd.vdecl[i].identity.type) { - case SVGA3D_DECLTYPE_FLOAT1: - width = 4; - break; - case SVGA3D_DECLTYPE_FLOAT2: - width = 4*2; - break; - case SVGA3D_DECLTYPE_FLOAT3: - width = 4*3; - break; - case SVGA3D_DECLTYPE_FLOAT4: - width = 4*4; - break; - case SVGA3D_DECLTYPE_D3DCOLOR: - width = 4; - break; - case SVGA3D_DECLTYPE_UBYTE4: - width = 1*4; - break; - case SVGA3D_DECLTYPE_SHORT2: - width = 2*2; - break; - case SVGA3D_DECLTYPE_SHORT4: - width = 2*4; - break; - case SVGA3D_DECLTYPE_UBYTE4N: - width = 1*4; - break; - case SVGA3D_DECLTYPE_SHORT2N: - width = 2*2; - break; - case SVGA3D_DECLTYPE_SHORT4N: - width = 2*4; - break; - case SVGA3D_DECLTYPE_USHORT2N: - width = 2*2; - break; - case SVGA3D_DECLTYPE_USHORT4N: - width = 2*4; - break; - case SVGA3D_DECLTYPE_UDEC3: - width = 4; - break; - case SVGA3D_DECLTYPE_DEC3N: - width = 4; - break; - case SVGA3D_DECLTYPE_FLOAT16_2: - width = 2*2; - break; - case SVGA3D_DECLTYPE_FLOAT16_4: - width = 2*4; - break; - default: - assert(0); - width = 0; - break; - } + for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { + struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i]; + unsigned size = vb ? vb->width0 : 0; + unsigned offset = hwtnl->cmd.vdecl[i].array.offset; + unsigned stride = hwtnl->cmd.vdecl[i].array.stride; + int index_bias = (int) range->indexBias + hwtnl->index_bias; + unsigned width; + + assert(vb); + assert(size); + assert(offset < size); + assert(min_index <= max_index); + + switch (hwtnl->cmd.vdecl[i].identity.type) { + case SVGA3D_DECLTYPE_FLOAT1: + width = 4; + break; + case SVGA3D_DECLTYPE_FLOAT2: + width = 4 * 2; + break; + case SVGA3D_DECLTYPE_FLOAT3: + width = 4 * 3; + break; + case SVGA3D_DECLTYPE_FLOAT4: + width = 4 * 4; + break; + case SVGA3D_DECLTYPE_D3DCOLOR: + width = 4; + break; + case SVGA3D_DECLTYPE_UBYTE4: + width = 1 * 4; + break; + case SVGA3D_DECLTYPE_SHORT2: + width = 2 * 2; + break; + case SVGA3D_DECLTYPE_SHORT4: + width = 2 * 4; + break; + case SVGA3D_DECLTYPE_UBYTE4N: + width = 1 * 4; + break; + case SVGA3D_DECLTYPE_SHORT2N: + width = 2 * 2; + break; + case SVGA3D_DECLTYPE_SHORT4N: + width = 2 * 4; + break; + case SVGA3D_DECLTYPE_USHORT2N: + width = 2 * 2; + break; + case SVGA3D_DECLTYPE_USHORT4N: + width = 2 * 4; + break; + case SVGA3D_DECLTYPE_UDEC3: + width = 4; + break; + case SVGA3D_DECLTYPE_DEC3N: + width = 4; + break; + case SVGA3D_DECLTYPE_FLOAT16_2: + width = 2 * 2; + break; + case SVGA3D_DECLTYPE_FLOAT16_4: + width = 2 * 4; + break; + default: + assert(0); + width = 0; + break; + } - if (max_index != ~0) { - assert(offset + (index_bias + max_index) * stride + width <= size); - } + if (index_bias >= 0) { + assert(offset + index_bias * stride + width <= size); } - assert(range->indexWidth == range->indexArray.stride); - - if(ib) { - unsigned size = ib->width0; - unsigned offset = range->indexArray.offset; - unsigned stride = range->indexArray.stride; - unsigned count; - - assert(size); - assert(offset < size); - assert(stride); - - switch (range->primType) { - case SVGA3D_PRIMITIVE_POINTLIST: - count = range->primitiveCount; - break; - case SVGA3D_PRIMITIVE_LINELIST: - count = range->primitiveCount * 2; - break; - case SVGA3D_PRIMITIVE_LINESTRIP: - count = range->primitiveCount + 1; - break; - case SVGA3D_PRIMITIVE_TRIANGLELIST: - count = range->primitiveCount * 3; - break; - case SVGA3D_PRIMITIVE_TRIANGLESTRIP: - count = range->primitiveCount + 2; - break; - case SVGA3D_PRIMITIVE_TRIANGLEFAN: - count = range->primitiveCount + 2; - break; - default: - assert(0); - count = 0; - break; - } + /* + * min_index/max_index are merely conservative guesses, so we can't + * make buffer overflow detection based on their values. + */ + } - assert(offset + count*stride <= size); + assert(range->indexWidth == range->indexArray.stride); + + if (ib) { + unsigned size = ib->width0; + unsigned offset = range->indexArray.offset; + unsigned stride = range->indexArray.stride; + unsigned count; + + assert(size); + assert(offset < size); + assert(stride); + + switch (range->primType) { + case SVGA3D_PRIMITIVE_POINTLIST: + count = range->primitiveCount; + break; + case SVGA3D_PRIMITIVE_LINELIST: + count = range->primitiveCount * 2; + break; + case SVGA3D_PRIMITIVE_LINESTRIP: + count = range->primitiveCount + 1; + break; + case SVGA3D_PRIMITIVE_TRIANGLELIST: + count = range->primitiveCount * 3; + break; + case SVGA3D_PRIMITIVE_TRIANGLESTRIP: + count = range->primitiveCount + 2; + break; + case SVGA3D_PRIMITIVE_TRIANGLEFAN: + count = range->primitiveCount + 2; + break; + default: + assert(0); + count = 0; + break; } + + assert(offset + count * stride <= size); } +} + + +enum pipe_error +svga_hwtnl_prim(struct svga_hwtnl *hwtnl, + const SVGA3dPrimitiveRange * range, + unsigned min_index, + unsigned max_index, struct pipe_resource *ib) +{ + enum pipe_error ret = PIPE_OK; + +#ifdef DEBUG + check_draw_params(hwtnl, range, min_index, max_index, ib); #endif - if (hwtnl->cmd.prim_count+1 >= QSZ) { - ret = svga_hwtnl_flush( hwtnl ); + if (hwtnl->cmd.prim_count + 1 >= QSZ) { + ret = svga_hwtnl_flush(hwtnl); if (ret != PIPE_OK) return ret; } - + /* min/max indices are relative to bias */ hwtnl->cmd.min_index[hwtnl->cmd.prim_count] = min_index; hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index; hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range; + hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias; pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib); hwtnl->cmd.prim_count++;