**********************************************************/
#include "pipe/p_compiler.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_upload_mgr.h"
#include "svga_context.h"
#include "svga_draw.h"
#include "svga_draw_private.h"
#include "svga_debug.h"
#include "svga_screen.h"
-#include "svga_screen_buffer.h"
-#include "svga_screen_texture.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_surface.h"
#include "svga_winsys.h"
#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;
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_buffer_reference( &hwtnl->index_cache[i][j].buffer,
- NULL );
+ pipe_resource_reference(&hwtnl->index_cache[i][j].buffer, NULL);
}
}
for (i = 0; i < hwtnl->cmd.vdecl_count; i++)
- pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], NULL);
+ pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], NULL);
for (i = 0; i < hwtnl->cmd.prim_count; i++)
- pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
-
+ 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_buffer_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_buffer *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_buffer_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;
unsigned i;
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;
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_surface(svga->curr.framebuffer.cbufs[0])->handle,
+ 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
vdecl[i].rangeHint.last = 0;
}
- swc->surface_relocation(swc,
- &vdecl[i].array.surfaceId,
- vb_handle[i],
- PIPE_BUFFER_USAGE_GPU_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],
- PIPE_BUFFER_USAGE_GPU_READ);
- pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
+ 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;
}
}
+void
+svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias)
+{
+ hwtnl->index_bias = index_bias;
+}
* Internal functions:
*/
-enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
- const SVGA3dPrimitiveRange *range,
- unsigned min_index,
- unsigned max_index,
- struct pipe_buffer *ib )
+enum pipe_error
+svga_hwtnl_prim(struct svga_hwtnl *hwtnl,
+ const SVGA3dPrimitiveRange * range,
+ unsigned min_index,
+ unsigned max_index, struct pipe_resource *ib)
{
- int ret = PIPE_OK;
+ enum pipe_error ret = PIPE_OK;
#ifdef DEBUG
{
unsigned i;
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
- struct pipe_buffer *vb = hwtnl->cmd.vdecl_vb[i];
- unsigned size = vb ? vb->size : 0;
+ 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;
+ int index_bias = (int) range->indexBias + hwtnl->index_bias;
unsigned width;
assert(vb);
assert(size);
assert(offset < size);
- assert(index_bias >= 0);
assert(min_index <= max_index);
- assert(offset + index_bias*stride < size);
- assert(offset + (index_bias + min_index)*stride < size);
switch (hwtnl->cmd.vdecl[i].identity.type) {
case SVGA3D_DECLTYPE_FLOAT1:
width = 4;
break;
case SVGA3D_DECLTYPE_FLOAT2:
- width = 4*2;
+ width = 4 * 2;
break;
case SVGA3D_DECLTYPE_FLOAT3:
- width = 4*3;
+ width = 4 * 3;
break;
case SVGA3D_DECLTYPE_FLOAT4:
- width = 4*4;
+ width = 4 * 4;
break;
case SVGA3D_DECLTYPE_D3DCOLOR:
width = 4;
break;
case SVGA3D_DECLTYPE_UBYTE4:
- width = 1*4;
+ width = 1 * 4;
break;
case SVGA3D_DECLTYPE_SHORT2:
- width = 2*2;
+ width = 2 * 2;
break;
case SVGA3D_DECLTYPE_SHORT4:
- width = 2*4;
+ width = 2 * 4;
break;
case SVGA3D_DECLTYPE_UBYTE4N:
- width = 1*4;
+ width = 1 * 4;
break;
case SVGA3D_DECLTYPE_SHORT2N:
- width = 2*2;
+ width = 2 * 2;
break;
case SVGA3D_DECLTYPE_SHORT4N:
- width = 2*4;
+ width = 2 * 4;
break;
case SVGA3D_DECLTYPE_USHORT2N:
- width = 2*2;
+ width = 2 * 2;
break;
case SVGA3D_DECLTYPE_USHORT4N:
- width = 2*4;
+ width = 2 * 4;
break;
case SVGA3D_DECLTYPE_UDEC3:
width = 4;
width = 4;
break;
case SVGA3D_DECLTYPE_FLOAT16_2:
- width = 2*2;
+ width = 2 * 2;
break;
case SVGA3D_DECLTYPE_FLOAT16_4:
- width = 2*4;
+ width = 2 * 4;
break;
default:
assert(0);
break;
}
- assert(!stride || width <= stride);
- assert(offset + (index_bias + max_index)*stride + width <= size);
+ if (index_bias >= 0) {
+ assert(offset + index_bias * stride + width <= size);
+ }
+
+ /*
+ * min_index/max_index are merely conservative guesses, so we can't
+ * make buffer overflow detection based on their values.
+ */
}
assert(range->indexWidth == range->indexArray.stride);
- if(ib) {
- unsigned size = ib->size;
+ if (ib) {
+ unsigned size = ib->width0;
unsigned offset = range->indexArray.offset;
unsigned stride = range->indexArray.stride;
unsigned count;
break;
}
- assert(offset + count*stride <= size);
+ assert(offset + count * stride <= size);
}
}
#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_buffer_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
+ pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
hwtnl->cmd.prim_count++;
return ret;