From: Christoph Bumiller Date: Thu, 15 Dec 2011 17:46:10 +0000 (+0100) Subject: d3d1x: implement new stream output interface X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14193da589275969be31dbdb3280bb48cd24d0c0;p=mesa.git d3d1x: implement new stream output interface --- diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp index 5f270cdfa71..2828389cebf 100644 --- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp +++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp @@ -846,8 +846,8 @@ struct dxgi_blitter pipe->bind_vs_state(pipe, vs); if(pipe->bind_gs_state) pipe->bind_gs_state(pipe, 0); - if(pipe->bind_stream_output_state) - pipe->bind_stream_output_state(pipe, 0); + if(pipe->set_stream_output_targets) + pipe->set_stream_output_targets(pipe, 0, NULL, 0); pipe->set_fragment_sampler_views(pipe, 1, &view); pipe->draw_vbo(pipe, &draw); diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h index 4055c549d85..a64e8d195a9 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h @@ -58,7 +58,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl refcnt_ptr samplers[D3D11_STAGES][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; refcnt_ptr input_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; refcnt_ptr render_target_views[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - refcnt_ptr so_targets[D3D11_SO_BUFFER_SLOT_COUNT]; + refcnt_ptr so_buffers[D3D11_SO_BUFFER_SLOT_COUNT]; #if API >= 11 refcnt_ptr cs_unordered_access_views[D3D11_PS_CS_UAV_REGISTER_COUNT]; @@ -67,7 +67,6 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl D3D11_VIEWPORT viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; D3D11_RECT scissor_rects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - unsigned so_offsets[D3D11_SO_BUFFER_SLOT_COUNT]; D3D11_PRIMITIVE_TOPOLOGY primitive_topology; DXGI_FORMAT index_format; unsigned index_offset; @@ -88,10 +87,9 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl // derived state int primitive_mode; struct pipe_vertex_buffer vertex_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - struct pipe_resource* so_buffers[D3D11_SO_BUFFER_SLOT_COUNT]; + struct pipe_stream_output_target* so_targets[D3D11_SO_BUFFER_SLOT_COUNT]; struct pipe_sampler_view* sampler_views[D3D11_STAGES][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; void* sampler_csos[D3D11_STAGES][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - struct pipe_resource* buffers[D3D11_SO_BUFFER_SLOT_COUNT]; unsigned num_shader_resource_views[D3D11_STAGES]; unsigned num_samplers[D3D11_STAGES]; unsigned num_vertex_buffers; @@ -150,8 +148,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl caps.gs = false; caps.stages = 2; } - if(!pipe->set_stream_output_buffers) - caps.so = false; + assert(!caps.so || pipe->set_stream_output_targets); if(!pipe->set_geometry_sampler_views) caps.stages_with_sampling &=~ (1 << PIPE_SHADER_GEOMETRY); if(!pipe->set_fragment_sampler_views) @@ -164,7 +161,6 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl // pipeline state memset(viewports, 0, sizeof(viewports)); memset(scissor_rects, 0, sizeof(scissor_rects)); - memset(so_offsets, 0, sizeof(so_offsets)); primitive_topology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; index_format = DXGI_FORMAT_UNKNOWN; index_offset = 0; @@ -178,7 +174,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl // derived state primitive_mode = 0; memset(vertex_buffers, 0, sizeof(vertex_buffers)); - memset(so_buffers, 0, sizeof(so_buffers)); + memset(so_targets, 0, sizeof(so_buffers)); memset(sampler_views, 0, sizeof(sampler_views)); memset(sampler_csos, 0, sizeof(sampler_csos)); memset(num_shader_resource_views, 0, sizeof(num_shader_resource_views)); @@ -744,6 +740,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl info.instance_count = 1; info.primitive_restart = TRUE; info.restart_index = strip_cut_index; + info.count_from_stream_output = NULL; pipe->draw_vbo(pipe, &info); } @@ -767,6 +764,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl info.start_instance = 0; info.instance_count = 1; info.primitive_restart = FALSE; + info.count_from_stream_output = NULL; pipe->draw_vbo(pipe, &info); } @@ -794,6 +792,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl info.instance_count = instance_count; info.primitive_restart = TRUE; info.restart_index = strip_cut_index; + info.count_from_stream_output = NULL; pipe->draw_vbo(pipe, &info); } @@ -819,6 +818,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl info.start_instance = start_instance_location; info.instance_count = instance_count; info.primitive_restart = FALSE; + info.count_from_stream_output = NULL; pipe->draw_vbo(pipe, &info); } @@ -832,7 +832,21 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl if(update_flags) update_state(); - pipe->draw_stream_output(pipe, primitive_mode); + pipe_draw_info info; + info.mode = primitive_mode; + info.indexed = FALSE; + info.count = 0; + info.start = 0; + info.index_bias = 0; + info.min_index = 0; + info.max_index = ~0; + info.start_instance = 0; + info.instance_count = 1; + info.primitive_restart = FALSE; + info.restart_index = 0; + info.count_from_stream_output = input_buffers[0].p->so_target; + + pipe->draw_vbo(pipe, &info); } virtual void STDMETHODCALLTYPE DrawIndexedInstancedIndirect( @@ -864,6 +878,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl info.instance_count = data.instance_count; info.primitive_restart = TRUE; info.restart_index = strip_cut_index; + info.count_from_stream_output = NULL; pipe->draw_vbo(pipe, &info); } @@ -895,6 +910,7 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl info.start_instance = 0; info.instance_count = data.instance_count; info.primitive_restart = FALSE; + info.count_from_stream_output = NULL; pipe->draw_vbo(pipe, &info); } @@ -1293,34 +1309,53 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl const unsigned *new_offsets) { SYNCHRONIZED; - unsigned i; + + unsigned new_count, i; + bool changed = false; + + uint32_t append_mask = 0xffffffff; + if(!new_so_targets) count = 0; - bool changed = false; - for(i = 0; i < count; ++i) + for(new_count = 0, i = 0; i < count; ++i) { - ID3D11Buffer* buffer = new_so_targets[i]; - if(buffer != so_targets[i].p || new_offsets[i] != so_offsets[i]) + GalliumD3D11Buffer* buffer = static_cast(new_so_targets[i]); + + if(buffer != so_buffers[i].p) { - so_buffers[i] = buffer ? ((GalliumD3D11Buffer*)buffer)->resource : 0; - so_targets[i] = buffer; - so_offsets[i] = new_offsets[i]; changed = true; + so_buffers[i] = buffer; + so_targets[i] = buffer ? buffer->so_target : 0; } - } - for(; i < D3D11_SO_BUFFER_SLOT_COUNT; ++i) - { - if(so_targets[i].p || so_offsets[i]) + if(!buffer) + continue; + new_count = i + 1; + + if(new_offsets[i] == (unsigned)-1) + { + assert(so_targets[i]); + continue; + } + append_mask &= ~(1 << i); + + if(!so_targets[i] || new_offsets[i] != so_targets[i]->buffer_offset) { + pipe_so_target_reference(&buffer->so_target, NULL); + buffer->so_target = pipe->create_stream_output_target( + pipe, buffer->resource, new_offsets[i], buffer->resource->width0 - new_offsets[i]); + so_targets[i] = buffer->so_target; changed = true; - so_targets[i] = (ID3D11Buffer*)0; - so_offsets[i] = 0; } } - num_so_targets = count; + if(i < num_so_targets) { + changed = true; + for(; i < num_so_targets; ++i) + so_buffers[i] = (GalliumD3D11Buffer*)0; + } + num_so_targets = new_count; - if(changed && caps.so) - pipe->set_stream_output_buffers(pipe, so_buffers, (int*)so_offsets, num_so_targets); + if(likely(caps.so) && (changed || append_mask != 0xffffffff)) + pipe->set_stream_output_targets(pipe, num_so_targets, so_targets, append_mask); } virtual void STDMETHODCALLTYPE SOGetTargets( @@ -1334,9 +1369,9 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl SYNCHRONIZED; for(unsigned i = 0; i < count; ++i) { - out_so_targets[i] = so_targets[i].ref(); + out_so_targets[i] = so_buffers[i].ref(); #if API < 11 - out_offsets[i] = so_offsets[i]; + out_offsets[i] = so_targets[i]->buffer_offset; #endif } } @@ -1369,9 +1404,12 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl GalliumD3D11Asynchronous<>* async = (GalliumD3D11Asynchronous<>*)iasync; void* tmp_data = alloca(async->data_size); + memset(tmp_data, 0, async->data_size); // sizeof(BOOL) is 4, sizeof(boolean) is 1 boolean ret = pipe->get_query_result(pipe, async->query, !(get_data_flags & D3D11_ASYNC_GETDATA_DONOTFLUSH), tmp_data); if(out_data) + { memcpy(out_data, tmp_data, std::min(async->data_size, data_size)); + } return ret ? S_OK : S_FALSE; } @@ -1646,11 +1684,12 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl pipe->bind_vs_state(pipe, shaders[D3D11_STAGE_VS].p ? shaders[D3D11_STAGE_VS].p->object : default_shaders[PIPE_SHADER_VERTEX]); if(caps.gs) pipe->bind_gs_state(pipe, shaders[D3D11_STAGE_GS].p ? shaders[D3D11_STAGE_GS].p->object : default_shaders[PIPE_SHADER_GEOMETRY]); + if(caps.so && num_so_targets) + pipe->set_stream_output_targets(pipe, num_so_targets, so_targets, ~0); set_framebuffer(); set_viewport(); set_clip(); set_render_condition(); - // TODO: restore stream output update_flags |= UPDATE_VERTEX_BUFFERS | (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_PS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_PS)); } @@ -1669,8 +1708,8 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl GalliumD3D11ShaderResourceView* view = (GalliumD3D11ShaderResourceView*)shader_resource_view; if(caps.gs) pipe->bind_gs_state(pipe, 0); - if(caps.so) - pipe->bind_stream_output_state(pipe, 0); + if(caps.so && num_so_targets) + pipe->set_stream_output_targets(pipe, 0, NULL, 0); if(pipe->render_condition) pipe->render_condition(pipe, 0, 0); for(unsigned layer = view->object->u.tex.first_layer; layer <= view->object->u.tex.last_layer; ++layer) @@ -1695,9 +1734,6 @@ struct GalliumD3D10Device : public GalliumD3D10ScreenImpl pipe->set_constant_buffer(pipe, s, i, constant_buffers[s][i].p ? constant_buffers[s][i].p->resource : 0); } - if(caps.so) - pipe->set_stream_output_buffers(pipe, so_buffers, (int*)so_offsets, num_so_targets); - update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_VS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_VS)); update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + D3D11_STAGE_GS)) | (1 << (UPDATE_VIEWS_SHIFT + D3D11_STAGE_GS)); diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_objects.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_objects.h index 7e4ea1385bc..e1ef7b807be 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_objects.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_objects.h @@ -368,19 +368,40 @@ typedef GalliumD3D11TypedResource GalliumD3D11BufferBase; #if API >= 11 -typedef GalliumD3D11BufferBase GalliumD3D11Buffer; typedef GalliumD3D11Texture1DBase GalliumD3D11Texture1D; typedef GalliumD3D11Texture2DBase GalliumD3D11Texture2D; typedef GalliumD3D11Texture3DBase GalliumD3D11Texture3D; + +struct GalliumD3D11Buffer : public GalliumD3D11BufferBase +{ + struct pipe_stream_output_target* so_target; + + GalliumD3D11Buffer(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_BUFFER_DESC& desc, unsigned dxgi_usage) + : GalliumD3D11BufferBase(device, resource, desc, dxgi_usage), so_target(0) + { + } + + ~GalliumD3D11Buffer() + { + if(so_target) + pipe_so_target_reference(&so_target, NULL); + } +}; #else struct GalliumD3D10Buffer : public GalliumD3D10BufferBase { + struct pipe_stream_output_target *so_target; + GalliumD3D10Buffer(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_BUFFER_DESC& desc, unsigned dxgi_usage) : GalliumD3D10BufferBase(device, resource, desc, dxgi_usage) - {} + { + } ~GalliumD3D10Buffer() { + if(so_target) + pipe_so_target_reference(&so_target, NULL); + device->UnbindBuffer(this); } diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h index 84d747199f1..e64e1f6b3fc 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h @@ -72,13 +72,13 @@ static unsigned caps_dx_10_0[] = { UTIL_CHECK_CAP(ANISOTROPIC_FILTER), UTIL_CHECK_CAP(MIXED_COLORBUFFER_FORMATS), UTIL_CHECK_CAP(FRAGMENT_COLOR_CLAMP_CONTROL), - UTIL_CHECK_CAP(STREAM_OUTPUT), UTIL_CHECK_CAP(CONDITIONAL_RENDER), UTIL_CHECK_CAP(PRIMITIVE_RESTART), UTIL_CHECK_CAP(TGSI_INSTANCEID), UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), UTIL_CHECK_INT(MAX_TEXTURE_ARRAY_LAYERS, 512), + UTIL_CHECK_INT(MAX_STREAM_OUTPUT_BUFFERS, 4), UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16), UTIL_CHECK_SHADER(GEOMETRY, MAX_CONST_BUFFERS, 14), UTIL_CHECK_SHADER(GEOMETRY, MAX_TEXTURE_SAMPLERS, 16), @@ -108,7 +108,7 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen { memset(&screen_caps, 0, sizeof(screen_caps)); screen_caps.gs = screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; - screen_caps.so = !!screen->get_param(screen, PIPE_CAP_STREAM_OUTPUT); + screen_caps.so = screen->get_param(screen, PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) > 0; screen_caps.queries = screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY); screen_caps.render_condition = screen->get_param(screen, PIPE_CAP_CONDITIONAL_RENDER); for(unsigned i = 0; i < PIPE_SHADER_TYPES; ++i) @@ -1347,19 +1347,31 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen return S_OK; } +#define D3D1X_SHVER_GEOMETRY_SHADER 2 /* D3D11_SHVER_GEOMETRY_SHADER */ + GalliumD3D11Shader<>* create_stage_shader(unsigned type, const void* shader_bytecode, SIZE_T bytecode_length #if API >= 11 , ID3D11ClassLinkage *class_linkage #endif - ) + , struct pipe_stream_output_info* so_info) { bool dump = debug_get_option_dump_shaders(); + std::auto_ptr sm4(0); + dxbc_chunk_header* sm4_chunk = dxbc_find_shader_bytecode(shader_bytecode, bytecode_length); if(!sm4_chunk) - return 0; - - std::auto_ptr sm4(sm4_parse(sm4_chunk + 1, bswap_le32(sm4_chunk->size))); + { + if(so_info) + sm4.reset(new sm4_program()); + } + else + { + sm4.reset(sm4_parse(sm4_chunk + 1, bswap_le32(sm4_chunk->size))); + // check if this is a dummy GS, in which case we only need a place to store the signature + if(sm4.get() && so_info && sm4->version.type != D3D1X_SHVER_GEOMETRY_SHADER) + sm4.reset(new sm4_program()); + } if(!sm4.get()) return 0; @@ -1382,7 +1394,13 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen struct pipe_shader_state tgsi_shader; memset(&tgsi_shader, 0, sizeof(tgsi_shader)); - tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi(*sm4); + if(so_info) + memcpy(&tgsi_shader.stream_output, so_info, sizeof(tgsi_shader.stream_output)); + + if(so_info && sm4->version.type != D3D1X_SHVER_GEOMETRY_SHADER) + tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi_linkage_only(*sm4); + else + tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi(*sm4); if(!tgsi_shader.tokens) return 0; @@ -1435,7 +1453,7 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen ID3D11##Stage##Shader **out_shader) \ { \ SYNCHRONIZED; \ - GalliumD3D11##Stage##Shader* shader = (GalliumD3D11##Stage##Shader*)create_stage_shader(PIPE_SHADER_##GALLIUM, PASS_SHADER_ARGS); \ + GalliumD3D11##Stage##Shader* shader = (GalliumD3D11##Stage##Shader*)create_stage_shader(PIPE_SHADER_##GALLIUM, PASS_SHADER_ARGS, NULL); \ if(!shader) \ return E_FAIL; \ if(out_shader) \ @@ -1483,10 +1501,58 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen ID3D11GeometryShader **out_geometry_shader) { SYNCHRONIZED; + GalliumD3D11GeometryShader* gs; - return E_NOTIMPL; +#if API >= 11 + if(rasterized_stream != 0) + return E_NOTIMPL; // not yet supported by gallium +#endif + struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE); + if(!sig) + return E_INVALIDARG; + D3D11_SIGNATURE_PARAMETER_DESC* out; + unsigned num_outputs = dxbc_parse_signature(sig, &out); + + struct pipe_stream_output_info so; + memset(&so, 0, sizeof(so)); - // remember to return S_FALSE if ppGeometyShader == NULL and the shader is OK +#if API >= 11 + if(num_strides) + so.stride = buffer_strides[0]; + if(num_strides > 1) + debug_printf("Warning: multiple user-specified strides not implemented !\n"); +#else + so.stride = output_stream_stride; +#endif + + for(unsigned i = 0; i < num_entries; ++i) + { + unsigned j; + for(j = 0; j < num_outputs; ++j) + if(out[j].SemanticIndex == so_declaration[i].SemanticIndex && !strcasecmp(out[j].SemanticName, so_declaration[i].SemanticName)) + break; + if(j >= num_outputs) + continue; + const int first_comp = ffs(out[j].Mask) - 1 + so_declaration[i].StartComponent; + so.output[i].output_buffer = so_declaration[i].OutputSlot; + so.output[i].register_index = out[j].Register; + so.output[i].register_mask = ((1 << so_declaration[i].ComponentCount) - 1) << first_comp; + ++so.num_outputs; + } + if(out) + free(out); + + gs = reinterpret_cast(create_stage_shader(PIPE_SHADER_GEOMETRY, PASS_SHADER_ARGS, &so)); + if(!gs) + return E_FAIL; + + if(!out_geometry_shader) { + gs->Release(); + return S_FALSE; + } + *out_geometry_shader = gs; + + return S_OK; } #if API >= 11 diff --git a/src/gallium/state_trackers/d3d1x/gd3d1x/d3d_enums.cpp b/src/gallium/state_trackers/d3d1x/gd3d1x/d3d_enums.cpp index b8b36765596..e531b0ed557 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d1x/d3d_enums.cpp +++ b/src/gallium/state_trackers/d3d1x/gd3d1x/d3d_enums.cpp @@ -107,11 +107,11 @@ unsigned d3d11_query_size[D3D11_QUERY_COUNT] = sizeof(BOOL), sizeof(UINT64), sizeof(UINT64), - sizeof(UINT64), + sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), sizeof(D3D11_QUERY_DATA_PIPELINE_STATISTICS), sizeof(BOOL), sizeof(D3D11_QUERY_DATA_SO_STATISTICS), - 0, + sizeof(BOOL), 0, 0, 0, diff --git a/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.cpp b/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.cpp index b541d922cd4..392fd3e0921 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.cpp +++ b/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.cpp @@ -24,6 +24,7 @@ * **************************************************************************/ +#include #include "d3d1xstutil.h" #include "sm4.h" #include "tgsi/tgsi_ureg.h" @@ -819,3 +820,41 @@ void* sm4_to_tgsi(struct sm4_program& program) sm4_to_tgsi_converter conv(program); return conv.translate(); } + +void* sm4_to_tgsi_linkage_only(struct sm4_program& prog) +{ + struct ureg_program* ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY); + + uint64_t already = 0; + for(unsigned n = 0, i = 0; i < prog.num_params_out; ++i) + { + unsigned sn, si; + + if(already & (1ULL << prog.params_out[i].Register)) + continue; + already |= 1ULL << prog.params_out[i].Register; + + switch(prog.params_out[i].SystemValueType) + { + case D3D_NAME_UNDEFINED: + sn = TGSI_SEMANTIC_GENERIC; + si = n++; + break; + case D3D_NAME_CULL_DISTANCE: + case D3D_NAME_CLIP_DISTANCE: + // FIXME + sn = 0; + si = prog.params_out[i].SemanticIndex; + assert(0); + break; + default: + continue; + } + + ureg_DECL_output(ureg, sn, si); + } + + const struct tgsi_token* tokens = ureg_get_tokens(ureg, 0); + ureg_destroy(ureg); + return (void*)tokens; +} diff --git a/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.h b/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.h index 5722b277fb7..c0524200c12 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.h +++ b/src/gallium/state_trackers/d3d1x/gd3d1x/sm4_to_tgsi.h @@ -30,5 +30,6 @@ #include "sm4.h" void* sm4_to_tgsi(struct sm4_program& program); +void* sm4_to_tgsi_linkage_only(struct sm4_program& program); #endif /* SM4_TO_TGSI_H_ */