[Mesa-dev] [PATCH 20/75] st/nine: Initial ProcessVertices support
Axel Davy
axel.davy at ens.fr
Thu Oct 6 22:33:25 UTC 2016
On 06/10/2016 22:28, Ilia Mirkin wrote:
> On Thu, Oct 6, 2016 at 4:24 PM, Axel Davy <axel.davy at ens.fr> wrote:
>> On 05/10/2016 22:08, Axel Davy wrote:
>>> HRESULT NINE_WINAPI
>>> NineDevice9_ProcessVertices( struct NineDevice9 *This,
>>> UINT SrcStartIndex,
>>> @@ -3174,33 +3188,69 @@ NineDevice9_ProcessVertices( struct NineDevice9
>>> *This,
>>> IDirect3DVertexDeclaration9 *pVertexDecl,
>>> DWORD Flags )
>>> {
>>> - struct pipe_screen *screen = This->screen;
>>> + struct pipe_screen *screen_sw = This->screen_sw;
>>> + struct pipe_context *pipe_sw = This->pipe_sw;
>>> struct NineVertexDeclaration9 *vdecl =
>>> NineVertexDeclaration9(pVertexDecl);
>>> + struct NineVertexBuffer9 *dst = NineVertexBuffer9(pDestBuffer);
>>> struct NineVertexShader9 *vs;
>>> struct pipe_resource *resource;
>>> + struct pipe_transfer *transfer = NULL;
>>> + struct pipe_stream_output_info so;
>>> struct pipe_stream_output_target *target;
>>> struct pipe_draw_info draw;
>>> + struct pipe_box box;
>>> + unsigned offsets[1] = {0};
>>> HRESULT hr;
>>> - unsigned buffer_offset, buffer_size;
>>> + unsigned buffer_size;
>>> + void *map;
>>> DBG("This=%p SrcStartIndex=%u DestIndex=%u VertexCount=%u "
>>> "pDestBuffer=%p pVertexDecl=%p Flags=%d\n",
>>> This, SrcStartIndex, DestIndex, VertexCount, pDestBuffer,
>>> pVertexDecl, Flags);
>>> - if (!screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS))
>>> - STUB(D3DERR_INVALIDCALL);
>>> + if (!screen_sw->get_param(screen_sw,
>>> PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS)) {
>>> + DBG("ProcessVertices not supported\n");
>>> + return D3DERR_INVALIDCALL;
>>> + }
>>> - nine_update_state(This);
>>> - /* TODO: Create shader with stream output. */
>>> - STUB(D3DERR_INVALIDCALL);
>>> - struct NineVertexBuffer9 *dst = NineVertexBuffer9(pDestBuffer);
>>> + vs = This->state.programmable_vs ? This->state.vs : This->ff.vs;
>>> + /* Note: version is 0 for ff */
>>> + user_assert(vdecl || (vs->byte_code.version < 0x30 && dst->desc.FVF),
>>> + D3DERR_INVALIDCALL);
>>> + if (!vdecl) {
>>> + DWORD FVF = dst->desc.FVF;
>>> + vdecl = util_hash_table_get(This->ff.ht_fvf, &FVF);
>>> + if (!vdecl) {
>>> + hr = NineVertexDeclaration9_new_from_fvf(This, FVF, &vdecl);
>>> + if (FAILED(hr))
>>> + return hr;
>>> + vdecl->fvf = FVF;
>>> + util_hash_table_set(This->ff.ht_fvf, &vdecl->fvf, vdecl);
>>> + NineUnknown_ConvertRefToBind(NineUnknown(vdecl));
>>> + }
>>> + }
>>> - vs = This->state.vs ? This->state.vs : This->ff.vs;
>>> + /* Flags: Can be 0 or D3DPV_DONOTCOPYDATA, and/or lock flags
>>> + * D3DPV_DONOTCOPYDATA -> Has effect only for ff. In particular
>>> + * if not set, everything from src will be used, and dst
>>> + * must match exactly the ff vs outputs.
>>> + * TODO: Handle all the checks, etc for ff */
>>> + user_assert(vdecl->position_t || This->state.programmable_vs,
>>> + D3DERR_INVALIDCALL);
>>> +
>>> + /* TODO: Support vs < 3 and ff */
>>> + user_assert(vs->byte_code.version == 0x30,
>>> + D3DERR_INVALIDCALL);
>>> + /* TODO: Not hardcode the constant buffers for swvp */
>>> + user_assert(This->may_swvp,
>>> + D3DERR_INVALIDCALL);
>>> +
>>> + nine_state_prepare_draw_sw(This, vdecl, SrcStartIndex, VertexCount,
>>> &so);
>>> - buffer_size = VertexCount * vs->so->stride[0];
>>> - if (1) {
>>> + buffer_size = VertexCount * so.stride[0] * 4;
>>> + {
>>> struct pipe_resource templ;
>>> templ.target = PIPE_BUFFER;
>>> @@ -3212,49 +3262,50 @@ NineDevice9_ProcessVertices( struct NineDevice9
>>> *This,
>>> templ.height0 = templ.depth0 = templ.array_size = 1;
>>> templ.last_level = templ.nr_samples = 0;
>>> - resource = This->screen->resource_create(This->screen, &templ);
>>> + resource = screen_sw->resource_create(screen_sw, &templ);
>>> if (!resource)
>>> return E_OUTOFMEMORY;
>>> - buffer_offset = 0;
>>> - } else {
>>> - /* SO matches vertex declaration */
>>> - resource = NineVertexBuffer9_GetResource(dst);
>>> - buffer_offset = DestIndex * vs->so->stride[0];
>>> }
>>> - target = This->pipe->create_stream_output_target(This->pipe,
>>> resource,
>>> - buffer_offset,
>>> - buffer_size);
>>> + target = pipe_sw->create_stream_output_target(pipe_sw, resource,
>>> + 0, buffer_size);
>>> if (!target) {
>>> pipe_resource_reference(&resource, NULL);
>>> return D3DERR_DRIVERINTERNALERROR;
>>> }
>>> - if (!vdecl) {
>>> - hr = NineVertexDeclaration9_new_from_fvf(This, dst->desc.FVF,
>>> &vdecl);
>>> - if (FAILED(hr))
>>> - goto out;
>>> - }
>>> -
>>> init_draw_info(&draw, This, D3DPT_POINTLIST, VertexCount);
>>> draw.instance_count = 1;
>>> draw.indexed = FALSE;
>>> - draw.start = SrcStartIndex;
>>> + draw.start = 0;
>>> draw.index_bias = 0;
>>> - draw.min_index = SrcStartIndex;
>>> - draw.max_index = SrcStartIndex + VertexCount - 1;
>>> + draw.min_index = 0;
>>> + draw.max_index = VertexCount - 1;
>>> +
>>> +
>>> + pipe_sw->set_stream_output_targets(pipe_sw, 1, &target, offsets);
>>> - This->pipe->set_stream_output_targets(This->pipe, 1, &target, 0);
>>> - This->pipe->draw_vbo(This->pipe, &draw);
>>> - This->pipe->set_stream_output_targets(This->pipe, 0, NULL, 0);
>>> - This->pipe->stream_output_target_destroy(This->pipe, target);
>>> + pipe_sw->draw_vbo(pipe_sw, &draw);
>>> +
>>> + pipe_sw->set_stream_output_targets(pipe_sw, 0, NULL, 0);
>>> + pipe_sw->stream_output_target_destroy(pipe_sw, target);
>>> +
>>> + u_box_1d(0, VertexCount * so.stride[0] * 4, &box);
>>> + map = pipe_sw->transfer_map(pipe_sw, resource, 0, PIPE_TRANSFER_READ,
>>> &box,
>>> + &transfer);
>>> + if (!map) {
>>> + hr = D3DERR_DRIVERINTERNALERROR;
>>> + goto out;
>>> + }
>>> hr = NineVertexDeclaration9_ConvertStreamOutput(vdecl,
>>> dst, DestIndex,
>>> VertexCount,
>>> - resource, vs->so);
>>> + map, &so);
>>> + if (transfer)
>>> + pipe_sw->transfer_unmap(pipe_sw, transfer);
>>> +
>>> out:
>>> + nine_state_after_draw_sw(This);
>>> pipe_resource_reference(&resource, NULL);
>>> - if (!pVertexDecl)
>>> - NineUnknown_Release(NineUnknown(vdecl));
>>> return hr;
>>> }
>>>
>> Hi,
>>
>> For some reason, this is not working well anymore on both llvmpipe and
>> softpipe (but If I force screen_sw to take hal, that is radeonsi, the
>> function works).
>>
>> It crashes at the last
>>
>> pipe_resource_reference(&resource, NULL);
>>
>>
>> However the resource refcount is 1, so I don't see the problem....
>> The patch used to work, but perhaps I broke it when modifying a few other
>> stuffs.
>> Any idea why this would crash ?
> Recently a "next" pointer has been added to pipe_resource which has
> been causing a few people grief as it's not always nulled out in the
> initial templates. Not sure if it's relevant to this case or not.
>
> -ilia
>
Indeed, it seems to be that.
What's the fix ? Should I set the field to NULL everywhere in nine when
we create a resource ? Some tester said -O2 stopped working, I guess it
is that as well.
Axel
More information about the mesa-dev
mailing list